题意:

  给出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 位运算+枚举的更多相关文章

  1. 枚举进行位运算 枚举组合z

    枚举进行位运算--枚举组合 public enum MyEnum { MyEnum1 = , //0x1 MyEnum2 = << , //0x2 MyEnum3 = << , ...

  2. POJ 1753. Flip Game 枚举or爆搜+位压缩,或者高斯消元法

    Flip Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 37427   Accepted: 16288 Descr ...

  3. 在C#中对枚举进行位运算--枚举组合

    由于枚举的基础类型类型为基本的数值类型,支持位运算,因此可以使用一个值表示多个枚举的组合,在定义枚举时需要指定枚举数为2的幂指数方便进行位运算,即枚举数为1,2,4,8…,或1,1<<1, ...

  4. POJ 3220 位运算+搜索

    转载自:http://blog.csdn.net/lyhypacm/article/details/5813634 DES:相邻的两盏灯状态可以互换,给出初始状态.询问是否能在三步之内到达.如果能的话 ...

  5. poj 1222 EXTENDED LIGHTS OUT(位运算+枚举)

    http://poj.org/problem?id=1222 题意:给一个确定的5*6放入矩阵.每一个格子都有一个开关和一盏灯,0表示灯没亮,1表示灯亮着.让你输出一个5*6的矩阵ans[i][j], ...

  6. POJ 2965 The Pilots Brothers' refrigerator 位运算枚举

      The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 151 ...

  7. poj 1753 Flip Game 枚举(bfs+状态压缩)

    题目:http://poj.org/problem?id=1753 因为粗心错了好多次……,尤其是把1<<15当成了65535: 参考博客:http://www.cnblogs.com/k ...

  8. hdu 1882 Strange Billboard(位运算+枚举)

    http://acm.hdu.edu.cn/showproblem.php?pid=1882 感觉非常不错的一道题. 给一个n*m(1<=n,m<=16)的矩阵,每一个格子都有黑白两面,当 ...

  9. POJ1222熄灯问题【位运算+枚举】

    EXTENDED LIGHTS OUT Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 14231   Accepted: 8 ...

随机推荐

  1. SRM 583 Div Level Two:IDNumberVerification

    题目来源:http://community.topcoder.com/stat?c=problem_statement&pm=12610 这道题比较有意思,估计是中国人出的吧,以前都不知道身份 ...

  2. DBA 应该要注意Linux 环境下的一些操作

    DBA 对OS的依赖.一丁点儿也不亚于DB.对于Oracle DBA.尤为突出     DB和OS的感情也与日俱增.耦合度高的让人一度以为这两要劳燕双飞了 例如.Oracle里面. 而且.故障诊断以及 ...

  3. QQ邮箱中转站文件即将过期时如何转存到微云

    今天QQ邮箱提示我的中转站有个文件即将过期,然后我看看了那个文件然后我想永久保存这个文件,腾讯有个微云网盘(好像有10T),想知道能不能保存到微云已变永久保存 结果发现在文件中转站这个界面竟然没有续期 ...

  4. 【小白的java成长系列】——javakeyword

    准备出一个系列的内容啦,今天就从keyword開始说起吧~ 类型 keyword 说明 keyword 说明 訪问控制权限 public 公共的.公开的. protected 受保护的.用来修饰属性或 ...

  5. 【thinking in java】读书笔记(一)

    近期開始读tij,好记性不如烂笔头,所以还是记录一下,方便以后查阅. 一.各种初始化问题: 方法重载的问题: 方法的重载,差别是靠传入方法的參数,而不是返回值.比方f(),假设是返回值的话,easy产 ...

  6. JSP的学习(8)——JSP标签

    JSP标签也称为JSP Action(JSP动作)元素,用于在JSP页面中封装Java代码,这样使得在JSP页面中避免直接编写Java代码,让JSP真正成为MVC模式中的作为视图作用. 几个JSP常用 ...

  7. Hbase初体验

    搭建local模式搭建, 官网:http://hbase.apache.org API:http://hbase.apache.org/apidocs/index.html download:http ...

  8. uva 12096

    优先队列,主要是STL应用所以复制一下 #include <iostream> #include <cstdio> #include <cstdlib> #incl ...

  9. Jetty:配置JSP支持

    选择JSP实现 从Jetty-9.2開始,使用Apache Jasper作为默认JSP容器实现.在前面的版本号中使用的是Glassfish Jasper,在后面的版本号中也能够继续使用它. Jetty ...

  10. Swift - 几种使用数组的数据存储模型

    在iOS游戏开发中,比如2048游戏.有时会需要存储N×N数组的数据模型(如3×3,4×4等).这里我们演示了三种实现方式,分别是:一维数组.仿二维数组.自定义二维数组(即矩阵结构). 功能是根据传入 ...