poj 2965 11/14

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; 


 


            

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值