zoukankan      html  css  js  c++  java
  • POJ 1753 Flip Game (状压+暴力)

    题目链接:http://poj.org/problem?id=1753

    题意:

        给你一个4*4的棋盘,上面有两种颜色的棋子(一种黑色,一种白色),你一次可以选择一个棋子翻转它(黑色变成白色,同理反之),选择的这枚棋子的上下左右都会被翻动(前提是上下左右都可以被翻动)。问最少可以翻动多少颗棋子,让整个棋盘变成全部黑色或者全部白色。

    题解:

       4*4一共就16个格子,每个格子都可以是翻或者不翻,那么就是216翻法。

       所以就可以用状态压缩的方法来解决。

       比如说47。 47的二进制是00101111,我们就可以认为(从右往左)第1,2,3,4,6位是我们选择要翻转的棋子,而为0的位是我们不翻的。这样只要把1~16与4*4的坐标做一个映射就可以知道我们要翻那一个棋子了。把全部棋子翻完之后判断一下是不是全部是一种颜色,是就更新ans。

    ————————————————————

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cstdlib>
      5 #include <string>
      6 #include <vector>
      7 #include <map>
      8 #include <set>
      9 #include <queue>
     10 #include <sstream>
     11 #include <algorithm>
     12 using namespace std;
     13 #define pb push_back
     14 #define mp make_pair
     15 #define ms(a, b)  memset((a), (b), sizeof(a))
     16 //#define LOCAL
     17 typedef long long LL;
     18 const int inf = 0x3f3f3f3f;
     19 const int maxn = 100000+10;
     20 const int mod = 1e9+7;
     21 char input[4][4];
     22 bool color[4][4];//0为白,1为黑
     23 void reset()//重新初始化color表
     24 {
     25     for(int i=0;i<4;i++)
     26         for(int j=0;j<4;j++)
     27             if(input[i][j] == 'b')  color[i][j] = 1;
     28             else    color[i][j] = 0;
     29 }
     30 int cnt(int b)//计算b的二进制中右多少个1。
     31 {
     32     int num = 0;
     33     while(b>0){
     34         num++;
     35         b&=(b-1);
     36     }
     37     return num;
     38 }
     39 void clean(int j)//翻转棋子
     40 {
     41     int x, y;
     42     if(j<4&&j>=0)  x=0, y=j;
     43     else if(j<8&&j>=4)     x=1, y = j-4;
     44     else if(j<12&&j>=8)     x=2, y = j-8;
     45     else    x = 3, y = j-12;
     46 //    printf("%d %d %d
    ", j, x, y);
     47     color[x][y] = !color[x][y];
     48     if(x-1>=0)  color[x-1][y] = !color[x-1][y];//
     49     if(x+1<4)   color[x+1][y] = !color[x+1][y];//
     50     if(y-1>=0)  color[x][y-1] = !color[x][y-1];//
     51     if(y+1<4)   color[x][y+1] = !color[x][y+1];//
     52 }
     53 int judge()
     54 {
     55     bool flag1=1;//全0;
     56     bool flag2=1;//全1;
     57 
     58     //判断是不是为全0
     59     for(int i=0;i<4;i++){
     60         for(int j=0;j<4;j++){
     61             if(color[i][j]==1)  {flag1=0;break;}//如果出现了1就break
     62         }
     63     }
     64     if(flag1==1)    return 1;//如果是就直接返回1,即表为全0
     65     
     66     //同理判断是不是为全1
     67     for(int i=0;i<4;i++){
     68         for(int j=0;j<4;j++){
     69             if(color[i][j] == 0)    {flag2 = 0;break;}
     70         }
     71     }
     72     if(flag2==1)    return 1;
     73     return 0;//既不是全0,又不是全1,就返回0.
     74 }
     75 int main() {
     76 #ifdef LOCAL
     77     freopen("input.txt" , "r", stdin);
     78 #endif // LOCAL
     79     for(int i=0;i<4;i++)
     80         scanf("%s", input[i]);
     81     int ans = inf;
     82 //    for(int i=0;i<16;i++)
     83 //        clean(i);
     84     for(int i=1;i<(1<<16);i++){
     85         reset();
     86         int take = cnt(i);
     87         for(int j = 0;j<16;j++){
     88             if(i&(1<<j)){
     89                 clean(j);
     90             }
     91         }
     92         if(judge()){
     93             ans = min(ans, take);
     94         }
     95     }
     96     reset();//最后判断初始的时候是否已经是全0或者全1
     97     if(judge())     ans = 0;
     98     if(ans !=inf)
     99         printf("%d
    ", ans);
    100     else
    101         printf("Impossible
    ");
    102     return 0;
    103 }
    View Code
  • 相关阅读:
    生成Ptc文件时候使用top camera比较好
    3delight 上关于ptex的讨论,3delight的开发者最后说ptex的内存表现并不比普通的贴图差,不知道是不是因为3delight不支持而故意说的
    闲来无事,写个算法关于11000放在含有1001个元素。。。
    寻最优数字筛选算法找出 “排列数列“ 对应的 “组合数列“
    入住博客园
    日常工作中收集整理的MSSQL 技巧
    序列化 和 反序列化 类
    对Singleton Pattern的一点修改
    快速幂 & 取余运算 讲解
    JDK动态代理实现
  • 原文地址:https://www.cnblogs.com/denghaiquan/p/6697029.html
Copyright © 2011-2022 走看看