POJ 2965 The Pilots Brothers' refrigerator【BFS+状压 Or 脑洞】
题目链接:
http://poj.org/problem?id=1753
题意:
给定冰箱门的开关情况,改变一个门则其所在行列的门都会发生改变,求出改变门的最少操作使得最终所有门都是打开状态。
代码:
bfs+状态压缩很容易想到~~
这里的状态压缩要需要多加小心,注意一下存储的是翻转门的情况~
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
typedef pair<int, int> p;
const int maxn = 1<<17;
struct node
{
int value;
int step;
};
int pos[maxn];
int vis[maxn];
int x[maxn], y[maxn];
node sta;
int pa[maxn];
int dir[16] = {
0xf888, 0x8f88, 0x88f8, 0x888f, 0xf444, 0x4f44, 0x44f4, 0x444f,
0xf222, 0x2f22, 0x22f2, 0x222f, 0xf111, 0x1f11, 0x11f1, 0x111f
};
int bfs()
{
queue<node>q;
vis[sta.value] = 1;
sta.step = 0;
pa[sta.value] = -1;
q.push(sta);
while(!q.empty()){
node t = q.front();q.pop();
if(!t.value) return t.step;
for(int i = 0; i < 16; i++){
node n;
n.value = t.value ^ dir[i];
if(vis[n.value]) continue;
vis[n.value] = 1;
pa[n.value] = t.value;
n.step = t.step + 1;
pos[n.value] = i;
q.push(n);
}
}
return -1;
}
int main (void)
{
char c;
for(int i = 0; i < 4; i++){
for(int j = 0; j < 4; j++){
scanf("%c",&c);
if(c== '+') sta.value |= 1<<(15- i * 4 - j);
}
getchar();
}
int res = bfs();
int va = 0;
for(int i = 0; i < res; i++){
x[i] = pos[va] % 4 + 1;
y[i] = pos[va] /4 + 1;
va = pa[va];
}
printf("%d\n",res);
for(int i = res - 1; i >= 0; i--)
printf("%d %d\n", x[i], y[i]);
return 0;
}
分析:
脑洞做法:
首先观察样例,发现关门的在(1,2)(4,2),而样例却把他们所在行和列的全部翻了一遍。试想,对于某一点(1,2)来说,行和列的元素都翻一遍的话, (1,2)改变了7次,行列元素改变4次,而其他元素改变2次~~也就是说实际上只有(1,2)的状态改变了。把所有行列的元素翻一遍,记录翻动次数,统计翻转过后依然不满足的有多少个,直接翻转这些就好了~至于这道题因为(1,2)(4,2)本身在同一列~所以最后翻动次数为偶数~相当于没有动,就可以不翻转他们了~
#include<iostream>
using namespace std;
const int maxn = 10;
int a[maxn][maxn];
int m[maxn][maxn];
int row[maxn], cal[maxn];
int main (void)
{
char c;
for(int i = 0; i < 4; i++){
for(int j = 0; j < 4; j++){
cin>>c;
a[i][j] = (c=='-')?0:1;
}
}
for(int i = 0; i <4 ;i++){
for(int j = 0; j < 4; j++){
if(!a[i][j]) continue;
for(int k = 0; k < 4; k++){
m[i][k]++;
m[k][j]++;
}
}
}
int res = 0;
for(int i = 0; i < 4; i++){
for(int j = 0; j < 4; j++){
if((m[i][j] + a[i][j])&1){
row[res] = i;
cal[res++] = j;
}
}
}
cout<<res<<endl;
for(int i = 0; i < res; i++)
cout<<row[i] + 1<<' '<<cal[i] + 1<<endl;
return 0;
}
这种方格上玩一个方块动会对周围的方块产生影响之类的问题,适合用奇偶表示翻转状态~~~
遇见问题还是要多思考多观察~~不要硬碰硬,说不定会有更巧妙的方法~
POJ 2965 The Pilots Brothers' refrigerator【BFS+状压 Or 脑洞】的更多相关文章
- 枚举 POJ 2965 The Pilots Brothers' refrigerator
题目地址:http://poj.org/problem?id=2965 /* 题意:4*4的矩形,改变任意点,把所有'+'变成'-',,每一次同行同列的都会反转,求最小步数,并打印方案 DFS:把'+ ...
- POJ 2965. The Pilots Brothers' refrigerator 枚举or爆搜or分治
The Pilots Brothers' refrigerator Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 22286 ...
- POJ 2965 The Pilots Brothers' refrigerator 暴力 难度:1
The Pilots Brothers' refrigerator Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16868 ...
- POJ 2965 The Pilots Brothers' refrigerator 位运算枚举
The Pilots Brothers' refrigerator Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 151 ...
- POJ 2965 The Pilots Brothers' refrigerator (DFS)
The Pilots Brothers' refrigerator Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 15136 ...
- poj 2965 The Pilots Brothers' refrigerator (dfs)
The Pilots Brothers' refrigerator Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 17450 ...
- POJ - 2965 The Pilots Brothers' refrigerator(压位+bfs)
The game “The Pilots Brothers: following the stripy elephant” has a quest where a player needs to op ...
- poj 2965 The Pilots Brothers' refrigerator枚举(bfs+位运算)
//题目:http://poj.org/problem?id=2965//题意:电冰箱有16个把手,每个把手两种状态(开‘-’或关‘+’),只有在所有把手都打开时,门才开,输入数据是个4*4的矩阵,因 ...
- POJ 2965 The Pilots Brothers' refrigerator (枚举+BFS+位压缩运算)
http://poj.org/problem?id=2965 题意: 一个4*4的矩形,有'+'和'-'两种符号,每次可以转换一个坐标的符号,同时该列和该行上的其他符号也要随之改变.最少需要几次才能全 ...
随机推荐
- http与WebSocket
利用websocket连接服务器的最大特点就是:持久链接的特点. 共同点是:都是基于TCP协议进行client-server的链接,websocket是HTML5提出的一套补缺HTTP链接中不能持久链 ...
- 10道有关ios的题
1.你使用过Objective-C的运行时编程(Runtime Programming)么?如果使用过,你用它做了什么?你还能记得你所使用的相关的头文件或者某些方法的名称吗? 2.你实现过多线程的Co ...
- CentOS 7下安装配置proftpd搭建ftp服务器
proftpd全称:Professional FTP daemon,是针对Wu-FTP的弱项而开发的,除了改进的安全性,还具备许多Wu-FTP没有的特点,能以Stand-alone.xinetd模式运 ...
- Python3中的输入输出
input()函数 我们可以通过Python3解释器查看Python3中input()的含义: >>> type(input) <class 'builtin_function ...
- vs code 插件list
vs code 插件list
- 基础数据类型(set集合)
认识集合 由一个或多个确定的元素所构成的整体叫做集合. 集合中的元素有三个特征: 1.确定性(集合中的元素必须是确定的) 2.互异性(集合中的元素互不相同.例如:集合A={1,a},则a不能等于1) ...
- centos7 搭建jenkins
centos7 搭建jenkins.note 环境:VMware 虚拟机 centos 7+ jdk 1.8+ tomcat7+jenkins搭建好linux 服务器后,关闭防火墙 停止firewal ...
- 云服务器linux使用之开发环境搭建(一)
Host key verification failed. @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: ...
- JavaEE-03 JSP数据交互02
学习要点 application pageContext JSP对象作用域 cookie application 作用 类似于系统的“全局变量”,用于在同一个服务器内的所有用于之间的数据共享,对于整个 ...
- 批处理 更新 svn git hg
@echo off Setlocal enabledelayedexpansion ::CODER BY Administrator POWERD BY iBAT 1.6 ::设置svn默认安装位置以 ...