HDOJ搜索专题之翻纸牌游戏
2012-05-16 16:18
435 查看
BFS题,数学模型如下:
对于一个01序列(长度小于20),定义翻转操作为:选定序列中的一位,将其取反,并将其左右相邻的位(如果存在)取反,现给定一个初始序列,求最少需操作多少次使得序列变成全0序列。
分析:序列状态可用一个32位整数表示,状态数目最多为220,所以搜索不会超时,翻转操作可用异或运算来表示。
需注意的是,写好后别忘了测试n=1的情况。
View Code
对于一个01序列(长度小于20),定义翻转操作为:选定序列中的一位,将其取反,并将其左右相邻的位(如果存在)取反,现给定一个初始序列,求最少需操作多少次使得序列变成全0序列。
分析:序列状态可用一个32位整数表示,状态数目最多为220,所以搜索不会超时,翻转操作可用异或运算来表示。
需注意的是,写好后别忘了测试n=1的情况。
View Code
#include <stdio.h> #include <string.h> #include <math.h> #include <queue> using namespace std; typedef struct node { int s,t; }node; queue<node> S; node cur,next; int d[20]; char s[21]; char vis[1<<20]; void bfs() { int i,ans; bool success=false; while(!S.empty()) S.pop(); memset(vis,0,sizeof(vis)); cur.t=0; vis[cur.s]=1; S.push(cur); while(!S.empty()&&!success) { cur=S.front(),S.pop(); if(cur.s==0) success=true,ans=cur.t; for(i=0;i<20&&!success;i++) { next=cur; next.t++; next.s^=d[i]; if(next.s==0) success=true,ans=next.t; else if(!vis[next.s]) { vis[next.s]=1; S.push(next); } } } if(success) printf("%d\n",ans); else puts("NO"); } int main() { int i,n; while(gets(s)) { n=strlen(s); d[0]=3; if(n>1) { d[n-1]=3<<(n-2); if(n>2) d[1]=3; else d[1]=7; for(i=2;i<n-1;i++) d[i]=d[i-1]<<1; } cur.s=0; for(i=0;i<n;i++) { cur.s=(cur.s<<1)+s[i]-'0'; } if(n==1&&cur.s==1) puts("1"); else bfs(); } return 0; }
相关文章推荐
- HDOJ —2009 翻纸牌游戏——搜索(回溯)算法
- HDOJ搜索专题之Robot Motion
- HDU2209翻纸牌游戏(位运算+搜索)
- hdoj 2209 翻纸牌游戏 【dfs】
- HDOJ搜索专题之Jugs
- hdoj 2209 翻纸牌游戏(翻转问题)
- HDOJ搜索专题之Another Eight Puzzle
- 杭电2209 翻纸牌游戏 DFS BFS 搜索
- hdu 2209 翻纸牌游戏 搜索+贪心
- HDOJ搜索专题之Accept Necklace
- HDOJ搜索专题之非常可乐
- HDOJ搜索专题之Sticks
- hdoj 2209 翻纸牌游戏(BFS + 位运算)
- HDOJ搜索专题之胜利大逃亡
- HDOJ搜索专题之下沙小面的(2)
- HDOJ 题目2209 翻纸牌游戏(dfs)
- HDOJ搜索专题之Prime Ring Problem
- HDOJ搜索专题之Square
- HDOJ搜索专题之Red and Black
- HDOJ搜索专题之变形课