小记:A了这题又长了记性了。定了个全局变量又定了一个相同变量名的局部变量,一直测试不对,想法是肯定是对的。最后想了好久,终于看到了,唉,,b了。
题解:这题,因为只有0和1两种状态,而且题目也说了只有不超过20位的长度,因此我们可以将这个串转换成一个整数值,而每种翻转而成的状态都是唯一的,因此这个值也是唯一的,这个就很好的解决了搜索中某个状态是否搜索过的问题了。不过也是利用空间换时间,看题目提交的情况,唉,大神们就是大神们,差距太大了。如果有看到本文的,有更好的解决方案的大神,给小弟支个招,教教咱。在此先谢过。 继续,有了保存状态的方法后,就直接对每一种状态中的每一位进行bfs,当状态值为0时即表示已搜到,就返回。记得对每一个状态进行标记是否已搜索。
代码奉上:
#include <stdio.h> #include <string.h> #include <queue> using namespace std; #define MAX 1<<20 #define N 50 char s1[N]; int visited[MAX],num[MAX]; int len; int bfs(int x){ queue<int>q; q.push(x); int i, now, next; while(!q.empty()){ now = q.front();//取头 q.pop();//头出队 for (i = 1; i <= len; i++){ if(i == 1) next = now^3;//最左翻转两个 else next = now^(7<<(i-2));//中间翻转3个 next &= (1<<len)-1;//最右的时候翻转了三个,消掉一个 if(visited[next])continue;//是否已搜过 visited[next] = 1;//标记为已搜 num[next] = num[now] + 1;//最少次数加一 if(next == 0) return num[next];//是否搜到了 q.push(next);//没有,则入队 } } return -1; } int main() { int i, a; while(scanf("%s",s1)!=EOF){ len = strlen(s1); a = 0; for(i = 0;i < len;i++) a = (a<<1) + s1[i] -'0'; if(a){ memset(visited,0,sizeof(visited)); memset(num,0,sizeof(num)); a = bfs(a); } if(a == -1) printf("NO\n"); else printf("%d\n",a); } return 0; }