这题不是搜索题,就是按照题意遍历下去,其实也就是搜索的思想。。
题意:
有两堆数量都为c的木柴,现在要把两个堆s1和s2合并(shuffle),合并成高度为2*c的大木堆叫s12,合并策略是:
先放s2的最下面木柴,再放s1的最下面木柴;放s2的倒数第二根木柴,放s1的倒数第二根木柴.......;放s2的最上面一根木柴,放s1的最上面一根木柴。
s12的最上面c个木柴又作为s2,s12的下面c的木柴又作为s1使用,接下来可以继续做shuffle的操作。
问:给定s1、s2,目标S
问s1和s2需要经过多少次shuffle,才可以得到目标S。
题解:
这里唯一要注意的点是,找到循环节,跳出,这里的tmps1,tmps2 就是判定是不是等于当前s1和s2,如果等于,就说明开始循环查找了,退出,输出 -1。
我的字符串没有用c++的string,所以代码很长。 水题。
AC。0ms
#include<cstdio>
#include<cstring>
#include<algorithm>
char tmps1[105],tmps2[105];
void shuffle(char *s1,char *s2,char *sn,int len){
int k=0;
for(int i=0;i<len;i++)
{
sn[k++]=s2[i];
sn[k++]=s1[i];
}
sn[k]='\0';
}
int equall(char *s1,char *s2){
int ok=1;
int len=(int)strlen(s1);
for(int i=0;i<len;i++)
if(s1[i]!=s2[i]) {ok=0;break;}
return ok;
}
void cpp(char *sn,char *x,int st,int len){
for(int i=0;i<len;i++)
x[i]=sn[st+i];
}
int dfs(int len,char *s1,char *s2,char *s){
int ret=0;
char sn[210];
while(1){
shuffle(s1,s2,sn,len);
ret++;
if(equall(s,sn)) break;
cpp(sn,s1,0,len);
cpp(sn,s2,len,len);
if(equall(s1, tmps1) && equall(s2, tmps2)) {
ret=-1;
break;
}
}
return ret;
}
int main(int argc, const char * argv[]) {
int T;
char s1[105],s2[105],s[210];
int c;
scanf("%d",&T);
for(int t=1;t<=T;t++){
scanf("%d%s%s%s",&c,s1,s2,s);
cpp(s1,tmps1,0,c);
cpp(s2,tmps2,0,c);
int ans=dfs(c,s1,s2,s);
printf("%d %d\n",t,ans);
}
return 0;
}