问题链接:Problem I
问题简述:
给定字符串S1,S2,与S12.将S2的首个字符放在首位,S1的首个字符放在第2位,S2的第2个字符放在第3位……以此类推组合成一个新的字符串,再将新的字符串平均分为两半,前一半为作为S1,后一半作为S2,如此反复直至组合字符串满足最终状态S12。若能满足,输出最少组合次数,若不能满足,输出-1。
问题分析:
求最小路径。可用BFS求解,但本题转化方向固定,所以只需用简单的模拟即可得到答案,若组合后的字符串曾经出现过,则可认为进入了循环状态,无法得到目标字符串S12。
程序说明:
用set或map来记录状态,以死循环while(1)不断模拟字符串的组合与拆分过程,再用strcmp函数比较组合字符串与目标字符串。需要注意的是每次得出新的字符串末位须手动加上‘\0’避免strcmp函数出错。
AC通过的C语言程序如下:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<cstring>
#include<cmath>
using namespace std;
char s1[205],s2[205],s12[405],st[405];
int main(){
std::ios::sync_with_stdio(false);
int n;
cin>>n;
int t=0;
while(n--){
t++;
int c;
cin>>c;
memset(s1,'\0',sizeof(s1));
memset(s2,'\0',sizeof(s2));
memset(s12,'\0',sizeof(s12));
cin>>s1>>s2>>s12;
map<string,bool>vis;
vis[s1]=1;
vis[s2]=1;
int step=0;
while(1){
for(int i=0,j=0,k=0;i<2*c;){
st[i++]=s2[j++];
st[i++]=s1[k++];
}
st[2*c]='\0';
step++;
if(strcmp(st,s12)==0){
cout<<t<<" "<<step<<endl;
break;
}
else if(vis[st]){
cout<<t<<" "<<-1<<endl;
break;
}
vis[st]=1;
for(int i=0;i<c;i++){
s1[i]=st[i];
}
s1[c]='\0';
for(int i=c,j=0;i<2*c;i++,j++){
s2[j]=st[i];
}
s2[c]='\0';
}
}
}