Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its 16 squares. One side of each piece is white and the other one is black and each piece is lying either it's black or white side up. Each round you flip 3 to 5 pieces, thus changing the color of their upper side from black to white and vice versa. The pieces to be flipped are chosen every round according to the following rules:
- Choose any one of the 16 pieces.
- Flip the chosen piece and also all adjacent pieces to the left, to the right, to the top, and to the bottom of the chosen piece (if there are any).
这道题目的意思是让我们找到最少的变换使得最后要么全黑要么全白。
从一开始,我就知道这是到枚举题,但是令我沮丧的是,我的枚举老是TLE,后来发现自己其实做了比较多的无用功,贴下原来TLE的代码先:
#include<iostream>
using namespace std;
unsigned short map;
bool IsRes()
{
return map==0 || map==0xffff;
}
void GetNot(int i,int j)
{
int dir[][2]={0,1,0,-1,1,0,-1,0};
for(int k=0;k<4;k++)
{
int x=i+dir[k][0];
int y=j+dir[k][1];
if(x>=0&&x<4&&y>=0&&y<4)
{
map^=(1<<(x*4+y));
}
}
}
bool DFS(int cnt,int pos)
{
if(cnt==0)
{
if(IsRes())return true;
return false;
}
cnt--;
if(cnt>pos)return false;
while(pos>=0)
{
map^=(1<<pos);
int i = pos/4;
int j = pos%4;
GetNot(i,j);
if(DFS(cnt,pos))return true;
map^=(1<<pos);
GetNot(i,j);
pos--;
}
return false;
}
int main()
{
char s[5];
int i,j;
map = 0 ;
for(i=0;i<4;i++)
{
cin>>s;
for(j=0;j<4;j++)
{
map<<=1;
if(s[j]=='b')map|=1;
}
}
if(IsRes()){cout<<"0"<<endl;return 0;}
for(i=1;i<=16;i++)
{
if(DFS(i,15))
{
cout<<i<<endl;
return 0;
}
}
cout<<"Impossible"<<endl;
return 0;
}
这种做法每次挑选时,有很多跟低cnt重复的情况。应该采用递增,减掉那些重复的内容。AC的代码如下:
#include<iostream> #include<queue> using namespace std; struct node{ node(){} node(int i,int j):map(i),step(j){} unsigned short map; int step; }; unsigned char vis[65536]; queue<node>q; void Init() { char s[5]; node n; n.map=n.step=0; for(int i=0;i<4;i++) { cin>>s; for(int j=0;j<4;j++) { n.map<<=1; if(s[j]=='b')n.map|=1; } } memset(vis,0,sizeof vis); vis[n.map]=1; q.push(n); } int BFS() { node s; int dir[][2]={0,1,0,-1,1,0,-1,0}; while(!q.empty()) { s = q.front(); q.pop(); if(s.map == 0 || s.map == 0xffff)return s.step; for(int i=0;i<16;i++) { unsigned short tmp = (1<<i); for(int j=0;j<4;j++) { int x=i/4+dir[j][0]; int y=i%4+dir[j][1]; if(x>=0&&x<4&&y>=0&&y<4) {tmp|=(1<<(x*4+y));} } if(vis[tmp^s.map]==0){ vis[tmp^s.map]=1; q.push(node(tmp^s.map,s.step+1)); } } } return -1; } int main() { Init(); int res = BFS(); if(res==-1)cout<<"Impossible"<<endl; else cout<<res<<endl; return 0; }