poj 1753、2965枚举
题目大意:
一个4乘4的棋盘,上面放满了正反两面分别为黑和白的棋子,翻转一个棋子会让这个棋子上下左右的棋子也翻转,给定一个初始状态,求使所有棋子颜色相同所需的最少翻转次数。
解题思路:
先检查翻转0个棋子时是否所有棋子颜色一致,若不一致则翻转1个棋子,依次类推,若翻转某n个棋子后成功则n即为所求解,否则直到翻转16个棋子后仍未成功则输出“Impossible”。
翻转某n个棋子可用递归的方法,若递归函数中当前层翻转的是(i, j),则下一层递归函数从(i, j+ 1)开始选择,这样可以保证不重复。若j等于4(说明第i行已结束,)则应让j = 0; i++;到下一行中搜索。
用一个一维数组board[6]代表棋盘,其中board[i](i >= 1 && i <= 4)代表第i行,board[i]的二进制数最右边四位从左到右分别代表棋盘第i行的第1到4列。这样对棋子取反更方便。
#include <iostream>
#include <cstdio>
using namespace std; int board[];
int state[][] = { { , , , }, { , , , } }; void read() {
char c;
for (int i = ; i <= ; i++) {
for (int j = ; j <= ; j++) {
board[i] <<= ;
cin >> c;
if (c == 'b')
board[i] |= ;
}
}
} bool judge() {
if (board[] == && board[] == && board[] == && board[] == ||
board[] == && board[] == && board[] == && board[] == )
return true;
return false;
} void flip(int i, int j) {
i++; //下标从1开始
board[i] ^= state[][j];
board[i - ] ^= state[][j];
board[i + ] ^= state[][j];
} bool work(int n, int i, int j) {//还有n个棋子需翻转
if (n == )
return judge();
if (j == ) {
j = ; i++;
}
if ( - j + ( - i) * < n)
return false;
for (; i < ; i++) {
for (; j < ; j++) {
flip(i, j);
if(work(n - , i, j + ))
return true;
flip(i, j);
}
j = ;
}
return false;
} int main() {
read();
int i;
for (i = ; i <= ; i++) {
if (work(i, , ))
break;
}
if (i == )
cout << "Impossible" << endl;
else
cout << i << endl;
return ;
}
与上题基本相同,只不过需要一个栈来记录翻转的坐标。
#include <iostream>
#include <cstdio>
#include <stack>
using namespace std; int board[];
int state[] = { , , , };
stack<int> s; void read() {
char c;
for (int i = ; i < ; i++) {
for (int j = ; j < ; j++) {
board[i] <<= ;
scanf_s("%c", &c);
if (c == '-')
board[i] |= ;
}
scanf_s("%c", &c); //读入换行符
}
} void change(int i, int j) {
for (int t = ; t < ; t++) {
if (t != i)
board[t] ^= state[j];
}
board[i] ^= ;
} bool judge() {
for (int i = ; i < ; i++) {
if (board[i] != )
return false;
}
return true;
} bool work(int n, int i, int j) { //n为还需转换的个数
if (n == )
return judge();
if (j == ) {
j = ;
i++;
}
if (n > ( - j) + ( - i) * )
return false;
for (; i < ; i++) {
for (; j < ; j++) {
change(i, j);
if (work(n - , i, j + )) {
s.push(j + ); s.push(i + );
return true;
}
change(i, j);
}
j = ;
}
return false;
} int main() {
read();
int i, n = ;
for (i = ; i <= ; i++) {
if (work(i, , ))
break;
}
printf("%d\n", i);
while (!s.empty()) {
printf("%d", s.top());
s.pop();
printf(" %d\n", s.top());
s.pop();
}
return ;
}
poj 1753、2965枚举的更多相关文章
- [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 2965
这两道题类似,前者翻转上下左右相邻的棋子,使得棋子同为黑或者同为白.后者翻转同行同列的所有开关,使得开关全被打开. poj 1753 题意:有一4x4棋盘,上面有16枚双面棋子(一面为黑,一面为白), ...
- poj—1753 (DFS+枚举)
...
- 枚举 POJ 1753 Flip Game
题目地址:http://poj.org/problem?id=1753 /* 这题几乎和POJ 2965一样,DFS函数都不用修改 只要修改一下change规则... 注意:是否初始已经ok了要先判断 ...
- POJ 1753. Flip Game 枚举or爆搜+位压缩,或者高斯消元法
Flip Game Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 37427 Accepted: 16288 Descr ...
- POJ 1753 Flip Game(高斯消元+状压枚举)
Flip Game Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 45691 Accepted: 19590 Descr ...
- POJ 1753 Flip Game DFS枚举
看题传送门:http://poj.org/problem?id=1753 DFS枚举的应用. 基本上是参考大神的.... 学习学习.. #include<cstdio> #include& ...
- POJ 1222 POJ 1830 POJ 1681 POJ 1753 POJ 3185 高斯消元求解一类开关问题
http://poj.org/problem?id=1222 http://poj.org/problem?id=1830 http://poj.org/problem?id=1681 http:// ...
- poj 1873 凸包+枚举
The Fortified Forest Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 6198 Accepted: 1 ...
- 穷举(四):POJ上的两道穷举例题POJ 1411和POJ 1753
下面给出两道POJ上的问题,看如何用穷举法解决. [例9]Calling Extraterrestrial Intelligence Again(POJ 1411) Description A mes ...
随机推荐
- HDU 2879 数论
HeHe Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Submis ...
- 《UML和模式应用(原书第3版)》目录
学习 <UML和模式应用(原书第3版)>目标: 理解OOA/D思想 如何使用UML建模 如何使用设计模式 如何设计分层架构 目录: 第1部分 绪论 第1章 面向对象分析和设计 第2章 迭代 ...
- Oracle broker--详解
1,简介 01,介绍 Data Guard broker是建立在Data Guard基础上的一个对Data Guard配置,集中管理操作的一个平台.我们再上次DG主备切换的时候会发现特别麻烦,为此br ...
- 案例41-hibernate练习-添加客户
1 utils部分 1 HibernateUtils package www.test.utils; import org.hibernate.Session; import org.hibernat ...
- vim代码折叠命令
1. 折叠方式 可用选项 'foldmethod' 来设定折叠方式:set fdm=*****. 有 6 种方法来选定折叠: manual 手工定义折叠 ind ...
- JS常用的设计模式(2)——简单工厂模式
简单工厂模式是由一个方法来决定到底要创建哪个类的实例, 而这些实例经常都拥有相同的接口. 这种模式主要用在所实例化的类型在编译期并不能确定, 而是在执行期决定的情况. 说的通俗点,就像公司茶水间的饮料 ...
- UML建模—EA的使用起步
Enterprise Architect(EA) 是一个功能比较强悍的建模工具. 对于一个软件设计者来说,从需求分析到业务设计.类模型设计.数据库设计到测试.发布.部署等一系列软件设计必须的操作都可以 ...
- Hashtable(哈希表)
简体字繁体字转化: class Program { static void Main(string[] args) { Hashtable ht = new Hashtable(); ; i < ...
- 03.if 和 switch结合练习
namespace _04.练习01 { class Program { static void Main(string[] args) { //请用户输入年份,再输入月份,输出该月有多少天 Cons ...
- 类变量方法,局部变量和成员变量的区别(this关键字的使用)
变量名首写字母使用小写,如果由多个单词组成,从第2个单词开始的其他单词的首写字母使用大写. 如果局部变量的名字和成员变量的名字相同, 要想在该方法中使用成员变量,必须使用关键字this class P ...