POJ 1753 位运算+枚举
题意:
给出4*4的棋盘,只有黑棋和白棋,问你最少几步可以使棋子的颜色一样。
游戏规则是:如果翻动一个棋子,则该棋子上下左右的棋子也会翻一面,棋子正反面颜色相反。
思路:
都是暴搜枚举。
第一种方法:暴力dfs枚举
棋子只有最多翻一次,因为翻两次后结果和不翻是一样的,所以整个棋盘最多翻16次。
用step代表翻转的次数,当翻转了step次时,就看一下整个棋盘是否是清一色的。
当棋盘是清一色的时候就直接输出step,得到的就是最少翻转次数使棋盘清一色。
第二种方法:利用位运算来优化
因为棋子不是白就是黑,所以可以用0和1来表示。
然后为每一个棋子编号,并计算出该棋子若翻转会影响到的棋子的位置,可以把它们都看成是二进制的。
例如 棋子位置是 第二行第二列 则翻转该棋子会影响到的棋子位置是
0 0 0 0 0 1 0 0
0 1 0 0 1 0 1 0
0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0
二进制表示 0000 0100 0000 0000 0100 1010 0100 0000
当计算最小值时可以预处理一下,即计算出由全白到该方案最少需要步数以及全黑到该方案需要的最少步数。
然后每一种方案都可以通过枚举 dp[j] = min(dp[j], dp[i]+1)来得到,dp[i]表示左上的状态,dp[j]表示右上的状态。
j = 影响的棋子位置^i
再优化之:其实
,所以用dp[(1<<16-1)^i]得到的状态j即是状态i到全黑的最少步数, 这样就可以减少一个数组的开销了。
第三种方法:利用棋子翻转的奇偶次数
预处理时计算出改变该棋子会影响的棋子位置
然后得到棋盘状态的二进制形式记做p
然后枚举翻棋子的情况,总共有2^16-1种,看一看如果翻这些牌并且改变了相应受影响位置的牌棋盘后会不会变成清一色
并记录最少的步数

Tips:
位运算的优先级比较小,所以应该st应该= (1<<16)-1,而不是1<<16-1
Code:
#include <stdio.h>
#include <cstring> int dir[][] = {, , -, , , , , , , -}; bool G[][] = {false};
bool flag;
int step;
void flip(int r, int c)
{
for (int i = ; i < ; ++i) {
int rr = dir[i][]+r, cc = dir[i][]+c;
G[rr][cc] = !G[rr][cc];
}
} bool check()
{
for (int i = ; i <= ; ++i)
for (int j = ; j <= ; ++j)
if (G[i][j] != G[][]) return false;
return true;
} void dfs(int x, int y, int depth)
{
if (depth == step) {
flag = check();
return;
}
if (flag || y == ) return; flip(x, y);
if (x < )
dfs(x+, y, depth+);
else dfs(, y+, depth+); flip(x, y);
if (x < )
dfs(x+, y, depth);
else dfs(, y+, depth);
} int main()
{
//freopen("in.txt", "r", stdin);
char c;
for (int i = ; i <= ; ++i) {
for (int j = ; j <= ; ++j) {
scanf("%c", &c);
if (c == 'w') G[i][j] = true;
else G[i][j] = false;
}
getchar();
}
for (step = ; step <= ; ++step) {
dfs(, , );
if (flag) break;
}
if (flag) printf("%d\n", step);
else puts("Impossible");
return ;
}
第一种方法:暴力dfs+枚举
#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;
#define INF 0x1f1f1f1f int dir[][] = {, , , , , , , -, -, };
int eff[];
int dp[<<|];
const int st = (<<)-; bool check(int x, int y)
{
return x >= && x < && y >= && y < ;
} void init()
{
int tot = ;
for (int i = ; i < ; ++i) {
for (int j = ; j < ; ++j) {
int sta = ;
for (int k = ; k < ; ++k) {
int x = i+dir[k][], y = j+dir[k][];
if (check(x, y)) sta |= (<<(x*+y));///!!!
}
eff[tot++] = sta;
}
}
} void bfs()
{
for (int i = ; i <= st; ++i) {
if (dp[i] == INF) continue; ///!!!
for (int j = ; j < ; ++j) {
int sta = i^eff[j];
dp[sta] = min(dp[sta], dp[i]+);
}
}
} int main()
{
//printf("__%d\n", st);
// freopen("in.txt", "r", stdin);
memset(dp, INF, sizeof(dp));
dp[] = ;
init();
bfs();
char c[];
int p = ;
for (int i = ; i < ; ++i) {
scanf("%s", c);
for (int j = ; j < ; ++j) {
if (c[j] == 'w') p ^= (<<(i*+j));
}
}
if (dp[p] == INF && dp[p^st] == INF) puts("Impossible");
else printf("%d\n", min(dp[p], dp[p^st]));
return ;
}
第二种方法:利用位运算存状态,并预处理
#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std; const int INF = 0x1f1f1f1f;
const int st = (<<)-;
int dir[][] = {, , , , , , , -, -, };
int eff[]; bool check(int x, int y)
{
return x >= && x < && y >= && y < ;
} void init()
{
int tot = ;
for (int i = ; i < ; ++i) {
for (int j = ; j < ; ++j) {
int sta = ;
for (int k = ; k < ; ++k) {
int x = i+dir[k][], y = j+dir[k][];
if (check(x, y)) sta |= <<(*x+y);
}
eff[tot++] = sta;
}
}
} int main()
{
//freopen("in.txt", "r", stdin);
init();
int ans = INF;
char c[];
int p = ;
for (int i = ; i < ; ++i) {
scanf("%s", c);
for (int j = ; j < ; ++j) {
if (c[j] == 'b') p |= <<(i*+j);
}
}
for (int i = ; i <= st; ++i) {
int sum = ;
int pp = p;
for (int j = ; j < ; ++j) {
if ((<<j)&i) {
sum++;
pp ^= eff[j];///!!!
}
}
if (pp == || pp == st) ans = min(ans, sum);
}
if (ans == INF) puts("Impossible");
else printf("%d\n", ans);
return ;
}
第三种方法:利用枚举翻哪些牌
链接:http://poj.org/problem?id=1753
POJ 1753 位运算+枚举的更多相关文章
- 枚举进行位运算 枚举组合z
枚举进行位运算--枚举组合 public enum MyEnum { MyEnum1 = , //0x1 MyEnum2 = << , //0x2 MyEnum3 = << , ...
- POJ 1753. Flip Game 枚举or爆搜+位压缩,或者高斯消元法
Flip Game Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 37427 Accepted: 16288 Descr ...
- 在C#中对枚举进行位运算--枚举组合
由于枚举的基础类型类型为基本的数值类型,支持位运算,因此可以使用一个值表示多个枚举的组合,在定义枚举时需要指定枚举数为2的幂指数方便进行位运算,即枚举数为1,2,4,8…,或1,1<<1, ...
- POJ 3220 位运算+搜索
转载自:http://blog.csdn.net/lyhypacm/article/details/5813634 DES:相邻的两盏灯状态可以互换,给出初始状态.询问是否能在三步之内到达.如果能的话 ...
- poj 1222 EXTENDED LIGHTS OUT(位运算+枚举)
http://poj.org/problem?id=1222 题意:给一个确定的5*6放入矩阵.每一个格子都有一个开关和一盏灯,0表示灯没亮,1表示灯亮着.让你输出一个5*6的矩阵ans[i][j], ...
- POJ 2965 The Pilots Brothers' refrigerator 位运算枚举
The Pilots Brothers' refrigerator Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 151 ...
- poj 1753 Flip Game 枚举(bfs+状态压缩)
题目:http://poj.org/problem?id=1753 因为粗心错了好多次……,尤其是把1<<15当成了65535: 参考博客:http://www.cnblogs.com/k ...
- hdu 1882 Strange Billboard(位运算+枚举)
http://acm.hdu.edu.cn/showproblem.php?pid=1882 感觉非常不错的一道题. 给一个n*m(1<=n,m<=16)的矩阵,每一个格子都有黑白两面,当 ...
- POJ1222熄灯问题【位运算+枚举】
EXTENDED LIGHTS OUT Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 14231 Accepted: 8 ...
随机推荐
- HDU2795 Billboard 【线段树】+【单点更新】
Billboard Time Limit: 20000/8000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- 为什么java源文件中只允许一个public类存在
1.提出问题 为什么java源文件中只允许一个public类存在? 2.分析问题 问题涉及到的条件:源文件的名字 public类 main方法 一般我们在编写一个源文件的时候: 一个pu ...
- APK扩展文件介绍、功能及用法
APK扩展文件介绍 Android Market (Google Play Store)中每一个APK文件的最大限制是50MB.假设您的程序中包括大量的数据文件,曾经您仅仅能把这些数据文件放到自己的s ...
- org.apache.hadoop.ipc.Client: Retrying connect to server异常的解决
检查发现是DataNode一直连接不到NameNode. 检查各个节点在etc/hosts中的配置是否有127.0.1.1 xxxxxx.如果有把其屏蔽或者删除,重启各节点即可. 原因:127.0.1 ...
- TCP/IP协议的编写《转载》
基于HHARM9-EDU的TCP/IP(UDP)协议的实现 原文网址:http://blog.csdn.net/lhj0503/article/details/3323788 摘 要:嵌入式技术的发展 ...
- J2EE SSH学习(二)安装Eclipse插件和第一个Eclipse项目
(一)安装Eclipse插件 Eclipse有很多功能很强大的插件,我现在作为一个菜鸟只知道插件的功能通常都很牛叉实用或者很有趣,那么该怎么安装Eclipse插件呢? 我使用的是Eclipse 4.3 ...
- Html网页表格结构化标记的应用
在讲网页表格的结构化标记之前,还是先看几幅图片. Html表格的结构化 所谓的结构化,正如上述第一副图所看到的,就是把我们的表格划分为三种:表头.表体.表尾.从而当我们在改动表体部分的时候,不会影响到 ...
- DFA最小化 -- Hopcroft算法 Python实现
wiki 伪代码看上去一直以为怪.发现葡萄牙语和俄罗斯语那里的 if 推断都还缺少一个条件. 国内的资料比較少.这几份学习资料不错.比我稀里糊涂的思路要好,分享下: http://www.liafa. ...
- Opencv笔记(1) 命名规则数据结构(CvMat,...)
网上搜索了很多,检查中发现的信息劣势,检查源代码 同Cv为类的开始.包含详细的数据不(仅存储指针) CvMat typedef struct CvMat { int type; int step; / ...
- [Codecademy] HTML&CSS 第一课:HTML Basic
本文出自 http://blog.csdn.net/shuangde800 ------------------------------------------------------------ ...