poj—1753 (DFS+枚举)
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 51056 | Accepted: 21551 |
Description
- Choose any one of the 16 pieces.
- Flip the chosen piece and also all adjacent pieces to the left, to the right, to the top, and to the bottom of the chosen piece (if there are any).
Consider the following position as an example:
bwbw
wwww
bbwb
bwwb
Here "b" denotes pieces lying their black side up and "w" denotes pieces lying their white side up. If we choose to flip the 1st piece from the 3rd row (this choice is shown at the picture), then the field will become:
bwbw
bwww
wwwb
wwwb
The goal of the game is to flip either all pieces white side up or all pieces black side up. You are to write a program that will search for the minimum number of rounds needed to achieve this goal.
Input
Output
Sample Input
bwwb
bbwb
bwwb
bwww
Sample Output
4 题意:给了你一个4*4的棋盘,棋盘上的每一个格子里都有一颗一面黑一面白的棋子,一开始给出你棋盘的初始状态,你可以给任何一个棋子翻面,但是如果你翻了某一个棋子,那他上下左右的棋子都要翻面。问你最少需要翻多少次才能让16枚棋子都为黑或都为白。
思路:总共有16个棋子,每个棋子只有两种状态,翻或者不翻,因为一面棋子只有两种颜色,翻基数次等同于只翻了1次,翻偶数次等同于没翻。所以可以分别枚举翻1枚,2枚,3枚,4枚......16枚的所有情况。根据排列组合,枚举完所有情况需要2^16次。那如何进行枚举呢?可以用for循环一 一枚举某一次需要翻的棋子数,然后用DFS搜索翻这个数量的棋子的所有情况。如何DFS呢?首先选择要翻的第一个棋子,然后下一个要翻的棋子从已选择的这个棋子之后进行选择,一直到选完需要数量的棋子,然后判断所有棋子是否为同一种颜色,如果是,则不用再进行搜索了,这就是答案,因为你是从1-16依次枚举,所以第一次满足条件的情况一定是次数最少的;如果不是则继续搜索。具体看代码和注释理解:
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<algorithm>
#include<stack>
#include<queue>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std; int visit[];
int map[][];
int ans; void Flip()
{
int x,y;
for(int i=; i<=; ++i)
{
if(visit[i]) //如果标记为 1,表示这个棋子要翻
{
x = i/ + ; // 计算出棋子再棋盘中的位置
y = i % ;
if(i% == )
{
x--;
y = ;
}
map[x][y] = -map[x][y]; //翻自己
map[x-][y] = -map[x-][y]; //翻上
map[x+][y] = -map[x+][y]; //翻下
map[x][y+] = -map[x][y+]; //翻左
map[x][y-] = -map[x][y-]; //翻右
}
}
return;
} int Judge() //判断是否为同一种颜色
{
for(int i=; i<=; ++i)
for(int j=; j<=; ++j)
{
if(map[i][j] != map[][])
return ;
}
return ;
} void DFS(int num,int times,int who) //num表示总共要翻几个琪,times表示已经翻了几个,who表示上一次翻的是哪一个棋
{
if(ans < inf) return; //如果已经找到答案了,就不用往下了
if(times == num) //当翻棋的数量达到了,就进行判断
{
Flip(); //翻棋
if(Judge()) //判断全为同一种颜色
{
ans = num; //记录答案
}
else Flip(); //否则将棋盘恢复原状
return;
} for(int i=who+; i<=; ++i) //从上一个翻的棋子的下一个开始选择,这样可以防止出现重复的情况
{
visit[i] = ;//选中的标记为 1
DFS(num,times+,i); //搜索翻下一个的情况,
visit[i] = ; //清除标记
}
} int main()
{
char first;
memset(map,,sizeof(map));
for(int i=; i<=; ++i)
for(int j=; j<=; ++j)
{
cin>>first;//依次输入棋子
if(first == 'w')
map[i][j] = ; //若为白棋,记为 1
else map[i][j] = -; //黑记为为 -1
} ans = inf; //初始化答案为无穷大
for(int i=; i<=; ++i) //枚举翻棋子数
{
memset(visit,,sizeof(visit)); //每种情况开始前要将标记数组初始化为 0
DFS(i,,); //搜索翻这么多棋子的所有情况
if(ans < inf) break; //如果答案不为无穷大,表示已经有结果了,不用搜了
} if(ans == inf) cout<<"Impossible"<<endl;
else cout<<ans<<endl;
return ;
}
poj—1753 (DFS+枚举)的更多相关文章
- POJ 1753 DFS
思路: 有过两个裸搜的思路,第一个一个无限TLE,第二个还不慢... 错误思路:迭代加深搜索,枚举翻第几个棋,挂的原因:16的16次方,不挂就怪了. 错误代码见下: #include <cstd ...
- POJ 1753 Flip Game DFS枚举
看题传送门:http://poj.org/problem?id=1753 DFS枚举的应用. 基本上是参考大神的.... 学习学习.. #include<cstdio> #include& ...
- POJ 1753 Flip Game (DFS + 枚举)
题目:http://poj.org/problem?id=1753 这个题在開始接触的训练计划的时候做过,当时用的是DFS遍历,其机制就是把每一个棋子翻一遍.然后顺利的过了.所以也就没有深究. 省赛前 ...
- poj 1753 Flip Game(bfs状态压缩 或 dfs枚举)
Description Flip game squares. One side of each piece is white and the other one is black and each p ...
- [ACM训练] 算法初级 之 基本算法 之 枚举(POJ 1753+2965)
先列出题目: 1.POJ 1753 POJ 1753 Flip Game:http://poj.org/problem?id=1753 Sample Input bwwb bbwb bwwb bww ...
- 枚举 POJ 1753 Flip Game
题目地址:http://poj.org/problem?id=1753 /* 这题几乎和POJ 2965一样,DFS函数都不用修改 只要修改一下change规则... 注意:是否初始已经ok了要先判断 ...
- POJ 1753 位运算+枚举
题意: 给出4*4的棋盘,只有黑棋和白棋,问你最少几步可以使棋子的颜色一样. 游戏规则是:如果翻动一个棋子,则该棋子上下左右的棋子也会翻一面,棋子正反面颜色相反. 思路: 都是暴搜枚举. 第一种方法: ...
- poj 2965 The Pilots Brothers' refrigerator(dfs 枚举 +打印路径)
链接:poj 2965 题意:给定一个4*4矩阵状态,代表门的16个把手.'+'代表关,'-'代表开.当16个把手都为开(即'-')时.门才干打开,问至少要几步门才干打开 改变状态规则:选定16个把手 ...
- POJ 1753. Flip Game 枚举or爆搜+位压缩,或者高斯消元法
Flip Game Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 37427 Accepted: 16288 Descr ...
随机推荐
- 1_python小程序之实现用户的注册登陆验证功能
python小程序之实现用户的注册登陆验证功能 程序扼要简述: 一.程序流程:1.程序开始2.判断本地文件/数据库是否已存在用户信息,存在则跳转到登陆,否则跳转到注册,注册成功后后跳转到登陆3.判断 ...
- OD 实验(二) - 绕过序列号验证
需要破解的程序 输入用户名和序列号,点击 Check,程序会进行校验 用 OD 打开程序 按快捷键 Ctrl+F9 跟随表达式 GetDlgItemTextA 点击 ok 在这里调用了 GetDlgI ...
- 移动终端App测试点归纳
以下所有测试最后必须在真机上完整的执行. 1 安装.卸载测试 1.1 在真机上.第三方软件(xy苹果助手.91.安卓助手)的安装与卸载 1.2 安装在手机卡上 或 SD卡上 (不同的IOS和安卓版本) ...
- Flask之模板之特殊变量和方法
3.6 Flask中的特殊变量和方法: 在Flask中,有一些特殊的变量和方法是可以在模板文件中直接访问的. config 对象: config 对象就是Flask的config对象,也就是 app. ...
- [Z] 关于Python Tornado的一些资料
一个简单的样例: http://osedu.net/article/python/2014-03-18/501.html ioloop的官方doc: http://www.tornadoweb.org ...
- SharePreferences基本用法
Android提供的轻量级数据储存方法,一般存少量数据,比如配置什么的.方式是通过键值对存取,比较方便. 下面通过一个 记住密码 的简单例子来说明 public class MainActivity ...
- python利用paramiko连接远程服务器执行命令
python中的paramiko模块是用来实现ssh连接到远程服务器上的库,在进行连接的时候,可以用来执行命令,也可以用来上传文件. 1.得到一个连接的对象 在进行连接的时候,可以使用如下的代码: d ...
- mongodb(四)
Count+Distinct+Group数据库命令操作固定集合特性GridFS文件系统补充服务器端脚本 db.runCommand({group:{ ns:"persons", k ...
- 详解Vue2.0生命周期
网上已经有很多关于vue生命周期的文章,我的这篇文章的由来,其实是我对官网上描述的一句话的思考与理解:“el被新创建的vm.$el替换”,所以文章更多的内容可能是在对vue生命周期中“created ...
- Qt(自适应窗口)
关于窗口布局: 默认控件的大小为最小尺寸: 如果此时右键设置布局时,窗口大小会自动缩放对应大小,不利于调整. 建议窗口控件设置好最小尺寸,便于窗口布局时,控件不会变形,例如: 改变minimumsiz ...