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的矩形,有'+'和'-'两种符号,每次可以转换一个坐标的符号,同时该列和该行上的其他符号也要随之改变.最少需要几次才能全 ...
随机推荐
- 【java基础】Java锁机制
在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类.介绍的内容如下: 公平锁/非公平锁 可重入锁 独享锁/共享锁(广义) 互斥锁/读写锁(独享锁/共享锁的实现) 乐观锁 ...
- 【HEVC帧间预测论文】P1.9 Coding Tree Depth Estimation for Complexity Reduction of HEVC
Coding Tree Depth Estimation for Complexity Reduction of HEVC <HEVC标准介绍.HEVC帧间预测论文笔记>系列博客,目录见: ...
- Java递归调用改成非递归
在java语言中,使用递归调用时,如果过多的调用容易造成java.lang.StackOverflowError即栈溢出和程序执行过慢.这是一个潜在Bug和影响程序执行效率问题,需要谨慎使 ...
- CAD交互绘制带颜色宽度的直线(网页版)
用户可以在CAD控件视区任意位置绘制直线. 主要用到函数说明: _DMxDrawX::DrawLine 绘制一个直线.详细说明如下: 参数 说明 DOUBLE dX1 直线的开始点x坐标 DOUBLE ...
- Python matlab octave 矩阵运算基础
基础总结,分别在三种软件下,计算 求逆矩阵 矩阵转置 等运算,比较异同 例子:正规方程法求多元线性回归的最优解 θ=(XTX)-1XTY octave: pwd()当前目录 ones() zeros( ...
- freemarker list集合去重,实现hashset
在freemarker中没有提供去重的方法,虽然有提供定义hash的方法,如:<#assign myHash = { "name": "mouse", & ...
- java内存模型(线程独占部分)
线程独占部分 1.你了解Java的内存模型吗? 内存简介 有内核空间.用户空间(java是运行在用户空间上) 32位系统--->最大的访问内存大小是4G 62位系统--->最大的访问内存大 ...
- HLS协议分析实现与相关开源代码
苹果定义的HLS协议,广泛运用在现在很多的流媒体服务器和客户端之间,用以传输直播电视数据流. 具体的协议参照 http://tools.ietf.org/html/draft-pa ...
- css 浮动规则
1. 如果浮动元素的高度大于父级元素,那么浮动元素块会超过父级元素的底部.解决办法:将父级元素也设置为浮动定位. 2. 不改变box尺寸的情况下增加box内部的内边距:box-sizing: bord ...
- CQOI2018 九连环 打表找规律 fft快速傅里叶变换
题面: CQOI2018九连环 分析: 个人认为这道题没有什么价值,纯粹是为了考算法而考算法. 对于小数据我们可以直接爆搜打表,打表出来我们可以观察规律. f[1~10]: 1 2 5 10 21 4 ...