POJ 1753 DFS
思路:
有过两个裸搜的思路,第一个一个无限TLE,第二个还不慢。。。
错误思路:迭代加深搜索,枚举翻第几个棋,挂的原因:16的16次方,不挂就怪了。
错误代码见下:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
char q[6][6],vis[6][6],flag=false;
int tot=0,ans=0x3f3f3f3f,xx[]={1,-1,0,0,0},yy[]={0,0,1,-1,0},ansb,answ,step;
void dfs(int a,int b,int an_b,int an_w,int t)
{
if(an_b==16||an_w==16){flag=1;return;}
if(flag||t==step) {return;}
for(int dx=1;dx<=4;dx++){
for(int dy=1;dy<=4;dy++){//错误的枚举
if(vis[dx][dy])continue;
for(int i=0;i<=4;i++)
{
if(q[dx+xx[i]][dy+yy[i]]=='b')an_b--,an_w++,q[dx+xx[i]][dy+yy[i]]='w';
else if(q[dx+xx[i]][dy+yy[i]]=='w')an_w--,an_b++,q[dx+xx[i]][dy+yy[i]]='b';
}
vis[dx][dy]=1;
// printf("dx=%d dy=%d an_b=%d an_w=%d\n",dx,dy,an_b,an_w);
dfs(dx,dy,an_b,an_w,t+1);
vis[dx][dy]=0;
for(int i=0;i<=4;i++){
if(q[dx+xx[i]][dy+yy[i]]=='w')an_w--,an_b++,q[dx+xx[i]][dy+yy[i]]='b';
else if(q[dx+xx[i]][dy+yy[i]]=='b')an_b--,an_w++,q[dx+xx[i]][dy+yy[i]]='w';
}
}
}
}
int main()
{
for(int i=1;i<=4;i++)
{
for(int j=1;j<=4;j++)
{
cin>>q[i][j];
if(q[i][j]=='b') ansb++;
else if(q[i][j]=='w') answ++;
}
}
for(step=0;step<=15;step++)
{
memset(vis,0,sizeof(vis));
dfs(1,1,ansb,answ,0);
if(flag) {
printf("%d",step);
break;
}
}
if(!flag)printf("Impossible");
}
正确思路(但不是最好的思路):
枚举翻或者不翻。2^16,可以接受
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
char q[6][6];
int map[17][3];
int tot=0,xx[]={1,-1,0,0,0},yy[]={0,0,1,-1,0},ansb,answ,flag=0x3f3f3f;
void dfs(int t,int an_b,int an_w,int flip)
{
if(an_b==0||an_w==0)flag=min(flag,flip);
if(t>tot) return;
int dx=map[t][1],dy=map[t][2];
dfs(t+1,an_b,an_w,flip);
for(int i=0;i<=4;i++)
if(q[dx+xx[i]][dy+yy[i]]=='b')an_b--,an_w++,q[dx+xx[i]][dy+yy[i]]='w';
else if(q[dx+xx[i]][dy+yy[i]]=='w')an_w--,an_b++,q[dx+xx[i]][dy+yy[i]]='b';
dfs(t+1,an_b,an_w,flip+1);
for(int i=0;i<=4;i++)
if(q[dx+xx[i]][dy+yy[i]]=='b')an_b--,an_w++,q[dx+xx[i]][dy+yy[i]]='w';
else if(q[dx+xx[i]][dy+yy[i]]=='w')an_w--,an_b++,q[dx+xx[i]][dy+yy[i]]='b';
}
int main()
{
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++){
cin>>q[i][j];
if(q[i][j]=='b') ansb++;
else if(q[i][j]=='w') answ++;
}
for(int j=1;j<=4;j++){
for(int i=1;i<=4;i++){
tot++;
map[tot][1]=j;
map[tot][2]=i;
}
}
dfs(1,ansb,answ,0);
if(flag==0x3f3f3f)printf("Impossible");
else printf("%d\n",flag);
}