这里给出DFS和BFS代码,方便以后回忆。
DFS:
#include <bits/stdc++.h>
using namespace std;
int G[30][30],d[5]={0,0,1,0,-1},ans;
void Rever(int r,int c)//翻转
{
for(int i=0;i<5;i++)
G[r+d[i]][c+d[(i+1)%5]]^=1;
}
void resdfs(int r,int c,int cnt)//从第二行翻转,使得上一行全为1
{
if(cnt>6)
return;
else if(r==6)
{
for(int i=1;i<=5;i++)
if(!G[5][i])
return;
ans=min(ans,cnt);
return;
}
if(c==6)
{
resdfs(r+1,1,cnt);
return;
}
if(!G[r-1][c])
{
Rever(r,c);
resdfs(r,c+1,cnt+1);
Rever(r,c);
}
else
resdfs(r,c+1,cnt);
}
void dfs(int c,int cnt)//枚举第一行所有的翻转可能
{
if(c>5)
return;
Rever(1,c);
dfs(c+1,cnt+1);
resdfs(2,1,cnt+1);
Rever(1,c);
dfs(c+1,cnt);
resdfs(2,1,cnt);
}
int main()
{
int n;
cin>>n;
while(n--)
{
for(int i=1;i<=5;i++)
for(int j=1;j<=5;j++)
scanf("%1d",&G[i][j]);
ans=7;
dfs(1,0);
if(ans>6)
ans=-1;
cout<<ans<<endl;
}
return 0;
}
BFS:
BFS是从全为1的状态,搜索6步能走到的所有状态。
有一点很奇怪,如果输入为
printf
(
"%d\n"
,mp[res]==0?-1:mp[res]);
则会超时。
改成
printf("%d\n",mp[res]-1);
便通过了,运行时间在500ms左右。
#include <bits/stdc++.h>
using namespace std;
map<int,int> mp;
int Rever(int x,int n)
{
x^=1<<n;
if(n-1>=0&&n%5) x^=1<<(n-1);
if(n+1<25&&n%5!=4) x^=1<<(n+1);
if(n-5>=0) x^=1<<(n-5);
if(n+5<25) x^=1<<(n+5);
return x;
}
void bfs()
{
queue<int>que;
que.push((1<<25)-1);
mp[(1<<25)-1]=1;
while(!que.empty())
{
int x=que.front();
que.pop();
if(mp[x]>6)
return;
for(int i=0;i<25;i++)
{
int rex=Rever(x,i);
if(!mp[rex])
{
que.push(rex);
mp[rex]=mp[x]+1;
}
}
}
}
int main()
{
bfs();
int n,x;
scanf("%d",&n);
while(n--)
{
int res=0;
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
{
scanf("%1d",&x);
res=(res<<1)+x;
}
printf("%d\n",mp[res]-1);
}
return 0;
}