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的代码)
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;
}
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;
}
相关文章推荐
- shell入门-系统和用户的配置文件
- linux下的poll机制
- TI DSP TMS320C66x学习笔记之通用并行端口uPP(二)
- 从大数据菜鸟走上大师的历程
- 创建型设计模式:简单工厂模式--分析优缺点
- PHP:修改phpstorm的字体样式和大小
- 编写一个写字板初步了解Winform编程(二)——界面设计
- 多线程编程之三——线程间通讯
- NOIP2015酱油记
- JSP九大内置对象
- 第三天-linux版本选择及安装
- MEF部件的生命周期(PartCreationPolicy)
- Educational Codeforces Round 1 (D) 搜索(优化剪枝)
- struct和typedef struct彻底明白了
- 多线程编程之二——MFC中的多线程开发
- 指针作为函数参数传递
- CentOS 7 WiFi连接
- 遍历容器 Java风格和STL风格 foreach
- phpstorm常用快捷键
- 杭电1072 猜数字