【穷举法】POJ1753
这是一道poj的题目
链接:http://poj.org/problem?id=1753
思路
由于棋盘为4*4,所以我们可以使用穷举法,
我的最开始的想法是,按照flip的次数进行枚举,即第一次假设flip数为1,然后为2,依次进行下去这样子就time limits exceeded了
后来在看了大佬的解法后,我发现最简单的枚举就是,对每个位置进行枚举,因为每个位置要么是被flip了,要么是不flip。这种枚举的效率更加高
代码
#include<iostream>
#include<algorithm>
using namespace std;
int b[6][6];
int dx[5]={0,-1,1,0,0};
int dy[5]={0,0,0,-1,1};
int N=999999;
int flipTimes=0;
bool check()
{
for(int i=1;i<=4;i++)
{
for(int j=1;j<=4;j++)
{
if(b[i][j]!=b[1][1])
{
return false;
}
}
}
return true;
}
void dfs(int i,int j)
{
if(flipTimes>=N|| i==5)
{
return;
}
int next_i,next_j;//即下一个位置
if(j==4)
{
next_i=i+1;
next_j=1;
}
else
{
next_i=i;
next_j=j+1;
}
//flip (i,j)
flipTimes++;
for(int k=0;k<5;k++)
{
b[i+dx[k]][j+dy[k]]=!b[i+dx[k]][j+dy[k]];
}
if(check())
{//如果flip后正好满足,那就更新N的值,且不需要继续考察下一个位置了
N=min(N,flipTimes);
}
else
{
//负责继续考察下一个位置
dfs(next_i,next_j);
}
flipTimes--;
for(int k=0;k<5;k++)
{
b[i+dx[k]][j+dy[k]]=!b[i+dx[k]][j+dy[k]];
}
//dont flip (i,j)
dfs(next_i,next_j);
}
int main()
{
for(int i=1;i<=4;i++)
{
for(int j=1;j<=4;j++)
{
char c;
cin>>c;
if(c=='b')
{
b[i][j]=1;
}
else
{
b[i][j]=0;
}
}
}
if(check())
{
cout<<0<<endl;
}
else
{
dfs(1,1);
if(N==999999)
{
cout<<"Impossible"<<endl;
}
else
{
cout<<N<<endl;
}
}
}