Sample Inputbwwb
bbwb
bwwb
bwww
Sample Output4

题意:给一个4x4的棋盘,棋盘上有16个棋子,棋子正反两面分别为黑色和白色,给出初始状态(棋子可能是正面可能是反面),可以操作任意多次,每次操作可以翻转任意一个棋子,同时被翻转棋子的相邻棋子也会被翻转,问最少需要几步操作就可以将所有棋子置于全黑或者全白。

思路:实际上一个棋子最终的状态只与初始状态和被翻转过的次数的奇偶性有关,如果是偶次则保持初始状态不变,如果是奇数则是另一面,所以可以直接将翻转次数当做只有0次和1次,同时,翻转的顺序也是不会影响最终的状态的。因此可以将题意转化为:最多操作16次,且每个格子只能操作1次,问能否达到目的,这时候翻转的所有状态就只有2^16种。因此可以枚举所有翻转状态,再一一判断当前这种翻转状态下的最终态是否满足目的。

具体做法:将棋盘转化成一行二进制数,用1表示黑色,用0表示白色(左上角是第15位,即最高位,右下角第0位),判断初态是否满足要求,不满足则从1枚举到(1 << 16) - 1,中的所有状态。枚举的第种状态的第位是1则翻转初始状态的第pos位,并且

将第pos位会影响到的所有点翻转。

AC代码:

#include<map>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define pb push_back
#define LL long long
#define mkp make_pair
#define PLL pair<LL, LL>
#define lowbit(x) x & (-x)
#define PII pair<int, int>
#define Pque priority_queue
using namespace std;
const int maxn = 1e5 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const int EPS = 1e-6;vector<int> c[17];
bool pos[17], ans[17];void PB();inline void work(int i, int j){pos[j] ^= 1;for(int k = 0; k < c[j].size(); k++) pos[c[j][k]] ^= 1;
}inline bool check(){bool flag = pos[0] ^ 1;for(int i = 1; i <= 15; ++i) if(pos[i] == flag) return 0;return 1;
}inline int PRINT(int x){int cnt = 0;for(int i = 0; i <= 15; ++i) {if((1 << i) & x){cnt++;}}return cnt;
}int main(){char s[5][5];int MAX = (1 << 16) - 1;for(int i = 1; i <= 4; ++i) scanf(" %s", s[i] + 1);int cnt = 15;for(int i = 1; i <= 4; ++i) for(int j = 1; j <= 4; ++j) {if(s[i][j] == 'b') ans[cnt] = 1;cnt--;}PB();for(int j = 0; j < 16; j++) pos[j] = ans[j];if(check()){printf("0\n");return 0;}int tmp = MAX + 1;for(int i = 1; i <= MAX; i++){ for(int j = 0; j < 16; j++) pos[j] = ans[j];for(int j = 0; j < 16; j++) {if(i & (1 << j)) work(i, j);}if(check()) {tmp = min(tmp, PRINT(i));}}if(tmp == MAX + 1){printf("Impossible\n");return 0;}printf("%d\n", tmp);return 0;
}void PB(){for(int i = 0; i < 9; i += 4) c[i].pb(i + 1), c[i].pb(i + 4);for(int i = 12; i < 15; i++) c[i].pb(i - 4), c[i].pb(i + 1);for(int i = 15; i >= 7; i -= 4) c[i].pb(i - 1), c[i].pb(i - 4);for(int i = 3; i >= 1; i--) c[i].pb(i + 4), c[i].pb(i - 1);for(int i = 5; i < 7; i++) c[i].pb(i - 1), c[i].pb(i + 1), c[i].pb(i - 4), c[i].pb(i + 4);for(int i = 9; i < 11; i++) c[i].pb(i - 1), c[i].pb(i + 1), c[i].pb(i - 4), c[i].pb(i + 4); for(int i = 1; i <= 2; ++i) c[i].pb(i + 1);for(int i = 13; i <= 14; ++i) c[i].pb(i - 1);for(int i = 4; i <=8; i += 4) c[i].pb(i - 4);for(int i = 7; i <=11; i += 4) c[i].pb(i + 4);/*for(int i = 0; i <= 15; i++){printf("%d:", i);for(int j = 0; j < c[i].size(); j++){printf("%d ", c[i][j]);}printf("\n");}*/
}

POJ1753题解(枚举)相关推荐

  1. poj1753 解题思路

    poj1753属于枚举类型的题目,思路很简单,主要把握住两个点: · 1.每个点只有两种情况,翻0次和翻1次,翻偶数次是没有意义的: · 2.哪个点先翻哪个点后翻都是一样的. 明白了以上的基本要点,就 ...

  2. 牛客网 2018年全国多校算法寒假训练营练习比赛(第二场) 题解

    A-吐泡泡 题目描述 小鱼儿吐泡泡,嘟嘟嘟冒出来.小鱼儿会吐出两种泡泡:大泡泡"O",小泡泡"o". 两个相邻的小泡泡会融成一个大泡泡,两个相邻的大泡泡会爆掉. ...

  3. 第六届蓝桥杯B组C++省赛题解。

    目录 一.奖券数目 二.星系炸弹 三.三羊献瑞 四.格子输出 五.格子分数 六.乘法变加法 七.牌型种数 八.移动距离 九.叠骰子 十.生命之树 P,S. 前面的水题不会写太多东西,如果有疑问可以QQ ...

  4. 【CSDN竞赛第16期】简要题解 85分

    目录 1.鬼画符门莲台争夺战(枚举) 题目 题解 枚举 线段树标记 前缀和占领次数 代码(枚举,100%) 2.津津的储蓄计划(模拟) 题目 题解 代码(未知%) 3.多边形的面积 题目 题解 4.小 ...

  5. Mind Control(暴力+枚举)

    Problem - 1291C - Codeforces 你和你的n-1个朋友找到了一个整数阵列a1,a2,...,an.你们决定以如下方式分享它.你们中的n个人都按特定的顺序站成一排.每分钟,排在最 ...

  6. 【水一波题解】题解 of University of Central Florida 2020 (Fall) “Practice” Local Programming Contest

    题解 of University of Central Florida 2020 (Fall) "Practice" Local Programming Contest [by_0 ...

  7. Codeforces Round #635 (Div. 2)(A~D)题解

    Codeforces #635 A~D A.Ichihime and Triangle B.Kana and Dragon Quest game C.Linova and Kingdom D.Xeni ...

  8. 2018年安徽省程序设计大赛题解

    2018年安徽省程序设计大赛参考题解 水平有限错误难免. A: 数7 时间限制:1 s 题目描述: ​ 求整数序列A 中位置L 到R中间一共有多少个7,(每一个位上的7和能被7整除的次数) 输入 第一 ...

  9. BZOJ1295 [SCOI2009]最长距离

    Description windy有一块矩形土地,被分为 N*M 块 1*1 的小格子. 有的格子含有障碍物. 如果从格子A可以走到格子B,那么两个格子的距离就为两个格子中心的欧几里德距离. 如果从格 ...

最新文章

  1. 网站地图对优化的优势有哪些?
  2. 进程间的通信方式(二):管道Pipe和命令管道FIFO
  3. python如何确定拐点_python – 在样条拟合1d数据中找到拐点
  4. uvm 形式验证_UVM基础
  5. STM32F103高级定时器使用
  6. 一名微博架构师的2016年终总结
  7. python程序设计pdf上海交大_上海交大2011_2012程序设计python期末考试题
  8. smartsvn 忽略文件夹_Smart SVN-使用Smart SVN 管理项目代码文件(在windows上)
  9. 软件测试脚本语言有哪些,测试脚本是什么意思有哪些脚本
  10. adb小技巧之实现近似vim编辑器功能编辑android系统内部的文本文件
  11. 华为设备VRRP配置命令
  12. 硬件编程-----根据时序图写C语言驱动
  13. 3.17服务器维护,2016年3月17日服务器停机维护公告
  14. JSHOP2的基本使用
  15. 《普陀区加快发展网络安全产业实施意见》的通知
  16. java编写安卓计算器_安卓实现简单计算器
  17. css鼠标经过按钮变色6,像这种鼠标移过去会变色的按钮怎么做的
  18. 谷歌 Android 12 Go 正式发布!
  19. android下怎样伪装mac,Android刷成iOS?史上最强苹果伪装教程
  20. 谏太宗十思疏 魏征(原文/译文)

热门文章

  1. 《一个投资家的20年》读书笔记
  2. Android系统分区备份与还原
  3. android textview基线,关于Textview基准线的计算
  4. PPC修改注册表大全 (注册表必看)(转载)
  5. 图书馆信息管理系统文档
  6. 工厂机器安排(贪心算法)
  7. vscode远程连接服务器方法
  8. 记录-gitlab自动部署-git拉取代码失败构建失败 + linux系统升级git(yum安装 + 源码安装)
  9. Scrapy第三(②)篇:创建scrapy项目
  10. 解决小程序插槽slot内容显示不对,无论是原生小程序还是uniapp开发的,解决办法如下