题意:多组数据,一个长度n,然后两行字符串s1,s2,还有一行是给定的目标字符串,把s2,s1交叉连接起来之后(s2第一个字符在最下边),不断翻转(每次都是上边一半和下边一半换),直到找到给你的目标字符串。输出所需步数。若无法达到,也就是无限反转循环,弄不出来给你的目标字符串,输出-1;
搜索的话比较麻烦,写了一半放弃了,数组模拟比较简单,但是也有难点,就是你需要标记出现过的字符串来决定是否已经重复并且不是目标字符串,这个地方不控制的话就是死循环。
用到了map库函数,这也是第一次用map函数,比较容易理解,用起来很方便,可以标记出现过的字符串,详细用法代码里就能看明白啦。(数据不大,不用开全局数组,开了应该也不会错);
代码如下:
#include<stdio.h> #include<string.h> #include<iostream> #include<map> using namespace std; int main() { int m,n,i,j,k,cas=0,step; scanf("%d",&n); while(++cas<=n) { scanf("%d",&m); char s1[205],s2[205],s12[410]; scanf("%s%s%s",s1,s2,s12); map<string,bool>vist;//此处为map函数用法,以后字符串标记可以考虑用这个 vist[s12]=true; step=0; while(true) { char s[410]; k=0; for(i=0; i<m; i++)//第一次就是S2,S1交叉存入S数组,这也算一步(从S2第一个开始存,题目要求) { s[k++]=s2[i]; s[k++]=s1[i]; } s[k]=‘\0‘;//此处必须要加‘\0’作为字符串结束标志,切记,如不加就是WA,不加的话中间翻转的时候好像会出错,具体到哪错了没办法显示出来,自己再琢磨琢磨 step++; if(!strcmp(s,s12)) { printf("%d %d\n",cas,step); break; } else if(vist[s]&&strcmp(s,s12))//若出现重复的但是和目标字符串不同,就不必再往下反转了,表示无法弄出来目标字符串 { printf("%d -1\n",cas); break; } vist[s]=true;//出现过的都标记 for(i=0; i<m; i++) s1[i]=s[i]; s1[i]=‘\0‘; for(k=0; i<m*2; i++,k++) s2[k]=s[i]; s2[i]=‘\0‘; } } return 0; }