NC106350 POJ1753 Flip Game 翻转游戏
网上上课写的题目 POJ传送们http://poj.org/problem?id=1753
先贴代码,感觉里面重点部分说的已经比较清楚了
#include <iostream>
#include <stdlib.h>
#include <algorithm>
using namespace std;
const int n = 4, m = 4;
int a[m + 10], b[m + 10];
int change[n + 10]; //灯泡需要做出的变化
/*
bwwb
bbwb
bwwb
bwww
*/int clac(int x)
{int cent = 0;while (x){if ((x & 1))cent++;x >>= 1;}return cent;
}
int deal(int a[])
{int ans = 0x7f7f7f7f;int cur[n + 10], cnt = 0; //新定义一个暂时数组用来保存灯泡当前的亮灭情况for (change[0] = 0; change[0] <= ((1 << m) - 1); change[0]++){cnt = clac(change[0]);//第一排灯泡一共有15种不同的变化,用0 1 数列来表示这种变化//我们首先要去确定每一种第一排变化所带来后面几排的变化//因为我们对第一排的操作是能影响第二排的,而第二排的change 操作与上一排(按完之后) 的0 1 情况一样cur[0] = a[0] ^ change[0] ^ (change[0] >> 1) ^ ((change[0] << 1) & ((1 << m) - 1));//((change[0]<<1)&(1<<m)-1) 是指如果change 左移一位 那么就会会出现第五位数//比如:1010 左移一位——> 10100 但我们只需要0100 这个序列//所以就要对 **(1<<m)-1 == 1111 ** 这个数进行 与 运算(只有同为 1 的时候才为 1 )cur[1] = a[1] ^ change[0];for (int i = 1; i < n; i++){change[i] = cur[i - 1];cnt += clac(change[i]); //统计change 中 1 出现的次数,就是按了几次cur[i] = cur[i] ^ change[i] ^ (change[i] >> 1) ^ ((change[i] << 1) & (1 << m) - 1);cur[i + 1] = a[i + 1] ^ change[i];}if (cur[n - 1] == 0)ans = min(ans, cnt);}return ans;
}int main()
{for (int i = 0; i < 4; i++)for (int j = 0; j < 4; j++){char c;scanf(" %c", &c);if (c == 'b')a[i] |= (1 << j);elseb[i] |= (1 << j);}int ans = min(deal(a), deal(b));if (ans > n * m)cout << "Impossible" << endl;elsecout << ans;system("pause");
}
首先让我们理清一下思路。
问题:怎么样才能让所有的都变白或者都变黑
因为变白和变黑的两种状态,所以我们可以用 0 1 这种二进制位运算去解决这个问题
(因为我也是才学的,所以感觉像这种2种状态的题都可以根据这种 0 1 位运算思路去解决)
下面就是比较难理解的了,我们首先让他全变亮为主要目标
我们会有一个简单的思路,就是一排一排的去让它全变亮,
第一排我们一共有 2的4次方-1 种按法 根据第一排的不同按法,然后第二排相应给出对应的按法,
然后不断循环,直到最后一排。这时候前几排都是已经变亮的,这时候,我们会发现,如果最后一排不是都亮的,那么这种方式就是无解的。
所以推出第一排的按法有问题,从而不断循环,
那发生错误,所有都不满足的条件是什么呢:就是按遍了都没按出来。这样就返回impossible
其实只有第一排的选项会影响下面的选择,
我们只用遍历出第一排所有的情况,根据固定的方式就能去推出下面的情况
最终确定有没有灯还在亮着。
为了把零 0 排按灭,我们会发现,第 1 排按灭的方式与第 0 排亮着的方式一样
所以我们能通过第一排按的方式知道下一排按的方式。以此循环
最终确定。
简单记录一下我写过程的一些思路,如果想详细了解的可以加我QQ:2268568923
正好讨论一下,加深印象。位运算那个我想了很久才转过来弯的。真难想啊
NC106350 POJ1753 Flip Game 翻转游戏相关推荐
- POJ1753 flip Game翻转棋盘
/*题目大意:有一个4*4的方格,每个方格中放一粒棋子,这个棋子一面是白色,一面是黑色. 游戏规则为每次任选16颗中的一颗,把选中的这颗以及它四周的棋子一并反过来,当所有的棋子都是同一个颜色朝上时, ...
- Flip Game翻转游戏
4*4的棋盘,棋盘上的每个位置都是黑或白,每个位置的颜色可以翻转,并且翻转一个位置的同时其周围的棋子的颜色也同时翻转.给一个目标状态,问多少步可以到达目标状态. 广度优先搜索. #include &l ...
- [Swift]LeetCode293. 翻转游戏 $ Flip Game
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ ➤微信公众号:山青咏芝(shanqingyongzhi) ➤博客园地址:山青咏芝(https://www.cnblog ...
- POJ1753 Flip Game
题目链接:http://poj.org/problem?id=1753 大致题意:翻转游戏在一个长方形的4x4场地上进行,在其16个方格中分别放置双面棋子.每个棋子的一面是白色,另一面是黑色,每个都是 ...
- 翻转游戏(Flip_Game)
翻转游戏--Flip Game 问题描述 样例 代码 问题描述 翻转游戏:给定一个只包含两种字符的字符串:+和-.你可以将两个连续的"++"翻转成"–",你需要 ...
- LeetCode 294. 翻转游戏 II(记忆化递归)
文章目录 1. 题目 2. 解题 1. 题目 你和朋友玩一个叫做「翻转游戏」的游戏, 游戏规则:给定一个只有 + 和 - 的字符串. 你和朋友轮流将 连续 的两个 "++" 反转成 ...
- LeetCode 293. 翻转游戏
文章目录 1. 题目 2. 解题 1. 题目 你和朋友玩一个叫做「翻转游戏」的游戏,游戏规则:给定一个只有 + 和 - 的字符串. 你和朋友轮流将 连续 的两个 "++" 反转成 ...
- 20200208(补):翻转游戏Ⅰ Ⅱ(leetcode)
翻转游戏Ⅰ& Ⅱ 题目 思路与算法 代码实现 题目 翻转游戏Ⅰ 翻转游戏Ⅱ 思路与算法 翻转游戏Ⅰ的意思读题容易歧义,读英文题目后理解是第一次操作后的所有list集合,因此思路很清晰,遍历,找 ...
- 51nod-1337:翻转游戏
1337 翻转游戏 题目来源: TopCoder 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注 这个游戏与灯有关,有M只灯排成一行,编号为0,1, ...
最新文章
- Python基础-第二天
- 使用putty远程linux服务
- 关于iOS7以后版本号企业公布问题
- 进程间通信(一)管道
- java五子棋用到的类_JAVA五子棋用到的知识点以及方法类有哪些?
- c语言while运行出现错误,【图片】为什么我的while(1)不执行啊?【c语言吧】_百度贴吧...
- Java修炼之道--I/O
- c#实现文件批处理:剪切、复制、删除、改名、分类等
- 洛谷4577 LOJ2521:[FJOI2018]领导集团问题——题解
- 基于java的员工绩效考核管理系统
- inventor牙距_滚子链计算基础知识 | Inventor 2018 | Autodesk Knowledge Network
- Vue子组件与父组件(看了就会)
- 百度ueditor实现word图片自动转存
- 魅族千元新机曝光:处理器不错!
- VB连接Sql Server,Oracle,SyBase,Access数据库操作实例
- java八大数据类型_java的八大基本数据类型分别是什么?
- CPI即消费者物价指数
- 工作中使用的sql知识点及查询语法
- Python入门-基础语法笔记
- Hive分析、窗口函数