您的位置:首页 > 其它

HDOJ搜索专题之翻纸牌游戏

2012-05-16 16:18 435 查看
BFS,数学模型如下:

对于一个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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: