您的位置:首页 > 其它

poj 2965 11/14

2015-11-14 17:10 253 查看
http://poj.org/problem?id=2965

poj 2965

题目大意:棋盘上有若干个棋子,有黑白两种颜色(黑的反面就是白色)。要求给出一种初始状态,进行若干操作后使得棋盘上所有棋子为一种颜色。

操作规定:

1.翻转一枚棋子。

2.如果翻转一枚棋子,那么周边相邻的也要翻转。

首先:每个棋子要么翻,要么不翻,翻n次和n-2次是一样的效果。



思路1:id-dfs,迭代加深搜索,因为n<=16,限制深度搜索。2^16=65536可以用一个数组来保存状态。

结论:超时(代码就不给了)

思路2:广度优先

思考后不可取。

思路3:枚举。既然要么翻要么不翻,一共就有2^16-1=65535种情况,这个范围是可以接受的。因此可以把所有情况枚举过去。(430MS,我承认写不出0MS的代码)

<span style="color:#000000;">#include <iostream>
#include <cstring>
#define INF 999999
using namespace std;
char table[5][5];
int turn[6][6];
bool func(int x,int y)
{
if(turn[x][y]%2)return !table[x][y];
return table[x][y];
}
void turn_deal(int n)
{
int x=(n-1)/4+1;  <span style="color:#009900;">//由于只考虑1~4,1~4,并且turn数组够大,偷懒操作</span>
int y=(n-1)%4+1;
turn[x][y]++;
turn[x-1][y]++;
turn[x][y-1]++;
turn[x+1][y]++;
turn[x][y+1]++;
}
int count(int num)
{
int cnt=0;
for (int i=0;i<16;++i)
if((1<<i)&num)cnt++;    </span><pre name="code" class="cpp"><pre name="code" class="cpp"><span style="color:#000000;"><span style="color:#009900;">// 计算动了几个</span></span>



return cnt;}int main(){char val=0;for (int i=1;i<=4;++i) for (int j=1;j<=4;++j) { cin>>val; if(val=='w')table[i][j]=0; else table[i][j]=1;} //input int s=0; int cnt=INF; for (s=0;s<=65535;++s) { memset(turn,0,sizeof(turn)); for (int i=0;i<=15;++i) { int q=1<<i;
if(q>s)break; if(q&s) turn_deal(i+1);}bool f=true;bool start=func(1,1);for (int i=1;i<=4;++i) for (int j=1;j<=4;++j) if(func(i,j)!=start) {f=false;break;};if(f)cnt=min(cnt,count(s)); }if(cnt!=INF)cout<<cnt;else cout<<"Impossible";;return 0;




                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: