题目链接:

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 脑洞】的更多相关文章

  1. 枚举 POJ 2965 The Pilots Brothers' refrigerator

    题目地址:http://poj.org/problem?id=2965 /* 题意:4*4的矩形,改变任意点,把所有'+'变成'-',,每一次同行同列的都会反转,求最小步数,并打印方案 DFS:把'+ ...

  2. POJ 2965. The Pilots Brothers' refrigerator 枚举or爆搜or分治

    The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22286 ...

  3. POJ 2965 The Pilots Brothers' refrigerator 暴力 难度:1

    The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16868 ...

  4. POJ 2965 The Pilots Brothers' refrigerator 位运算枚举

      The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 151 ...

  5. POJ 2965 The Pilots Brothers' refrigerator (DFS)

    The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15136 ...

  6. poj 2965 The Pilots Brothers' refrigerator (dfs)

    The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 17450 ...

  7. 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 ...

  8. poj 2965 The Pilots Brothers' refrigerator枚举(bfs+位运算)

    //题目:http://poj.org/problem?id=2965//题意:电冰箱有16个把手,每个把手两种状态(开‘-’或关‘+’),只有在所有把手都打开时,门才开,输入数据是个4*4的矩阵,因 ...

  9. POJ 2965 The Pilots Brothers' refrigerator (枚举+BFS+位压缩运算)

    http://poj.org/problem?id=2965 题意: 一个4*4的矩形,有'+'和'-'两种符号,每次可以转换一个坐标的符号,同时该列和该行上的其他符号也要随之改变.最少需要几次才能全 ...

随机推荐

  1. Pow挖矿流程

    Pow挖矿流程 POW即工作量的证明,主要特征是客户端需要做一定难度的工作得出一个结果,验证方却很容易通过结果来检查出客户端是不是做了相应的工作. Pow挖矿即不断接入新的Block延续Block C ...

  2. sql server 全部错误号详释

    0 操作成功完成. 1 功能错误. 2 系统找不到指定的文件. 3 系统找不到指定的路径. 4 系统无法打开文件. 5 拒绝访问. 6 句柄无效. 7 存储控制块被损坏. 8 存储空间不足,无法处理此 ...

  3. vue 模块 props

    inbody.vue <template> <div> <Breadcrumb :style="{margin: '24px 0'}"> < ...

  4. Web前端基础怎么学? JavaScript、html、css知识架构图

    以前开发者只要掌握 HTML.CSS.JavaScript 三驾马车就能胜任一份前端的工作了.而现在除了普通的编码以外,还要考虑如何性能优化,如何跨端.跨平台实现功能,尤其是 AI.5G 技术的来临, ...

  5. SFM作业

    代码:https://github.com/jianxiongxiao/SFMedu PPT:http://3dvision.princeton.edu/courses/SFMedu/slides.p ...

  6. RTSP详解

    关于 RTSP. RTSP协议是一个非常类似HTTP协议的流控制协议.它们都使用纯文本来发送信息,而且rtsp协议的语法也和HTTP类似.Rtsp一开始这样设计,也是为了能够兼容使用以前写的HTTP协 ...

  7. [题解] codevs 1486 愚蠢的矿工

    http://codevs.cn/problem/1486/ 我们比较熟悉二叉树,题目中给出的是一棵多叉树,我们需要将这可二叉树改造成二叉树. 二叉树可以为这样的: 父亲结点左边储存儿子,右边储存兄弟 ...

  8. Django框架基础知识10-内置分页系统

    from django.shortcuts import render, redirect, reversefrom datetime import datetime# Create your vie ...

  9. Python的Turtle绘制纳兹咩的娘口三三

    今天看完夏目友人帐的大电影,哭成了泪猴~ 所以我打算用Python画一只娘口三三陪伴在我身边 不过.. 画的太丑,还没上色..,你们可以完善一下~ 代码放在这里了 import turtle as t ...

  10. 周三面试Python开发,这几道Python面试题差点答错,Python面试题No7

    第1题:阅读下面的代码,默读出A0,A1至An的最终值. A0 = dict(zip(('a','b','c','d','e'),(1,2,3,4,5))) A1 = range(10) A2 = [ ...