poj2965(位运算压缩+bfs+记忆路径)
2024-09-29 06:18:08
题意:有个4*4的开关,里面有着16个小开关
-+--
----
---- '+'表示开关是关着的,'-'表示开关是开着的,只有所有的开关全被打开,总开关才会被打开。现在有一种操作,只要改变某个开关,那么这个开关的行列所在开关都会被改变
-+-- 问,要打开总开关至少要改变多少次开关?并输出改变开关的位置。 思路: 由于每个开关只有两种状态,那么对于这16个小开关,我们可以用2进制来压缩下,如果开关是打开的那么为'0',如果是关着的,那么为'1',如此,我们就可以从下到上,从右到左给这16个开关
标记状态,如果以某个点为中心,那么这个点的行列状态都压缩进去,遇到这个点,取反与不取反,然后一次广搜过去,再记忆下路径,结果就出来了......
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define M 1<<16
int t[20]={
63624,62532,61986,61713,
36744,20292,12066,7953,
35064,17652,8946,4593,
34959,17487,8751,4383,
};
structnode
{
int k;
int step;
};
structnode1
{
int father;
int x,y;
}s[(1<<17)];
//bool vist[(1<<17)];
int sum;
void print(int ans)
{
if(ans==sum)
return;
print(s[ans].father);
printf("%d %d\n",s[ans].x+1,s[ans].y+1);
}
void bfs(int ans)
{
queue<node>q;
node p;
p.k=ans;
p.step=0;
s[p.k].father=-10;
q.push(p);
while(!q.empty())
{
p=q.front();
q.pop();
if(p.k==0)
{
printf("%d\n",p.step);
print(p.k);
return;
}
for(int i=0;i<16;i++)
{
node p1;
p1.k=p.k^t[i];
p1.step=p.step+1;
if(s[p1.k].father==-1)
{
s[p1.k].father=p.k;
s[p1.k].x=i/4;
s[p1.k].y=i%4;
q.push(p1);
}
}
}
}
int main()
{
int ans=0,cnt=15;
for(int i=0;i<4;i++)
{
char ch[100];
scanf("%s",ch);
for(int j=0;j<4;j++)
{
if(ch[j]=='+')
{
ans|=(1<<cnt);
}
cnt--;
}
}
//printf("%d\n",ans);
sum=ans;
for(int i=0;i<(M);i++)
{
s[i].father=-1;
}
bfs(ans);
return 0;
}
最新文章
- Format
- Javascript学习笔记:闭包题解(3)
- samba server install
- 给Jquery添加alert,prompt方法,类似系统的Alert,Prompt,可以响应键盘,支持拖动
- 动态代理 Proxy InvocationHandler
- Codeforces Round #263
- Servlet 获取IllegelStateException
- Day6_正则表达式
- css图形——椭圆
- phpStorm字体大小无法调整, 怎么办?
- BZOJ1179 [Apio2009]Atm Tarjan 强连通缩点 动态规划
- jenkins如何获取text parameter多行的文本内容
- P1(2)线性回归
- 协同过滤CF算法之入门
- 【LeetCode题解】136_只出现一次的数字
- P4433 [COCI2009-2010#1] ALADIN
- python及其模块下载集合
- SQL中注意数据类型对性能的影响
- mysql 一次性插入上万条数据测试专用
- Zookeeper--java操作zookeeper