题意:给你n个房间,有许多灯的控制开关,i房间灯的开关在j房间,未开灯的房间不能进,i房间和j房间之间如果没有门,也不能从i进入到j,开始房间是1,并且灯是开着的,问你是否能够走到最后一个房间n,并且此时其他房间的灯都是关着的.如果存在多个解,输出操作步数最小的操作序列.

范围:n<=10,

解题思路:设状态为,当前的房间编号+当前其他房间灯的状态.所以总的状态为N*2^N,最大值10*1024,裸枚举.

注意,这道题目每次枚举都必须从房间编码1-N,要不然会wa,而且,PE也wa.使用了位标志房间灯的状态.

#include <iostream>
#include<map>
#include<memory.h>
#include<stdio.h>
#include<string>
#include<queue>
#include<vector>
using namespace std;
const int MAXN = ; class Node
{
public:
vector<string>step;
int cur;
int curStepNum;
int lights;
Node()
{
//step.reserve(65535);
}
bool operator <(const Node& node) const
{
return curStepNum > node.curStepNum;
};
};
int conn[MAXN][MAXN];
int contro[MAXN][MAXN];
int r, d, s;
int states[][];
priority_queue<Node>q;
int perLights[] = {
<< , << , << , << , << , << ,
<< , << , << , << }; void read()
{
int ss, ee;
for (int i = ;i < d;i++)
{
cin >> ss >> ee;
//start with 0
conn[ss - ][ee - ] = ;
conn[ee - ][ss - ] = ;
}
for (int i = ;i < s;i++)
{
cin >> ss >> ee;
contro[ss - ][ee - ] = ;
}
}
Node bfs()
{
Node node;
node.cur = ;
node.curStepNum = ;
node.lights = ;
q.push(node);
//init node 只有0房间是亮的
states[][] = ;
while (q.empty() == false)
{
node = q.top();
q.pop();
int curIndex = node.cur;
//cur lights state
int curLights = node.lights;
int curStepNum = node.curStepNum;
//判断是不是终点
if ((curIndex == r - ) && curLights == perLights[r - ])
{
return node;
} //枚举灯的状态
for (int i = ;i < ; i++)
{
if (contro[curIndex][i] == )
continue;
if (i == curIndex)
continue;
//控制的灯
int nextControLightIndex = i;
string desc = "";
int nextLight = ;
if ((curLights & perLights[nextControLightIndex]) == perLights[nextControLightIndex])
{
//关闭next房间的灯
nextLight = (curLights ^ perLights[nextControLightIndex]);
if (states[curIndex][nextLight] == )
//repeat
continue;
desc = "- Switch off light in room " + std::to_string(nextControLightIndex + );
desc += ".";
}
else
{
//打开next房间的灯
nextLight = curLights | perLights[nextControLightIndex];
if (states[curIndex][nextLight] == )
//repeat
continue;
desc = "- Switch on light in room " + std::to_string(nextControLightIndex + );
desc += ".";
}
Node newNode;
newNode.curStepNum = curStepNum + ;
newNode.cur = curIndex;
newNode.lights = nextLight;
newNode.step = node.step;
newNode.step.push_back(desc);
//push to queue
q.push(newNode);
states[curIndex][nextLight] = ;
}
//end curIndex enum lights state
//start door
for (int i = ;i < ;i++)
{
if (curIndex == i)
continue;
if (conn[curIndex][i] == )
continue;
int nextDoor = i;
if ((perLights[nextDoor] & curLights) == )
//灯是灭的,不能进
continue;
if (states[nextDoor][curLights] == )
//已经看到过,不能进
continue;
//灯是开着的,能进
Node newNode;
newNode.cur = nextDoor;
newNode.curStepNum = curStepNum + ;
newNode.lights = curLights;
newNode.step = node.step;
string desc = "- Move to room " + std::to_string(nextDoor + );
desc += ".";
newNode.step.push_back(desc);
states[nextDoor][curLights] = ;
q.push(newNode);
}
}
node.cur = -;
return node;
}
int main()
{
int t = ;
while (cin >> r >> d >> s)
{
if (r == d && d == s && r == )
break;
memset(conn, , sizeof(conn));
memset(contro, , sizeof(conn));
memset(states, , sizeof(states));
while (q.empty() == false)
q.pop();
read(); cout << "Villa #";
cout << t + << endl;
if (r == )
{
cout << "The problem can be solved in " << << " steps:" << endl; }
else
{
Node node = bfs();
//cout << "test" << endl;
if (node.cur == -)
{
cout << "The problem cannot be solved." << endl;
}
else
{
cout << "The problem can be solved in " << node.curStepNum << " steps:" << endl;
vector<string> b = node.step;
for (int i = ;i <= b.size() - ;i++)
cout << b[i] << endl;;
}
}
t++;
cout << endl;
} }

uva-321-暴力枚举-隐式图搜索的更多相关文章

  1. uva10603-倒水问题-暴力枚举-隐式图搜索

    题意: 给你三个杯子,a,b,c,没有刻度,刚开始c杯是满的,倒水的要求,要么倒出水的杯子倒空,要么倒入杯子倒满. 结果: 要求某个杯子内有d水量,并且倒出的水量最少,如果倒不出d水量,那么倒出d1( ...

  2. UVa 658 - It's not a Bug, it's a Feature!(Dijkstra + 隐式图搜索)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  3. 【uva 658】It's not a Bug, it's a Feature!(图论--Dijkstra或spfa算法+二进制表示+类“隐式图搜索”)

    题意:有N个潜在的bug和m个补丁,每个补丁用长为N的字符串表示.首先输入bug数目以及补丁数目.然后就是对M个补丁的描述,共有M行.每行首先是一个整数,表明打该补丁所需要的时间.然后是两个字符串,第 ...

  4. uva 10274 Fans and Gems(隐式图搜索+模拟)

    Fans and Gems Input: Standard Input Output: Standard Output Tomy's fond of a game called 'Fans and G ...

  5. 紫书 例题 11-6 UVa 658 (状态压缩+隐式图搜索+最短路)

    这道题用到了很多知识点, 是一道好题目.      第一用了状态压缩, 因为这里最多只有20位, 所以可以用二进制来储存状态 (要对数据范围敏感), 然后 涉及到了一些位运算.     第二这里是隐式 ...

  6. [HNOI2006]最短母串问题 --- AC自动机 + 隐式图搜索

    [HNOI2006]最短母串问题 题目描述: 给定n个字符串(S1,S2.....,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,......,Sn)都是T的子串. 输入格式: 第 ...

  7. 洛谷 P2622 关灯问题II【状压DP;隐式图搜索】

    题目描述 现有n盏灯,以及m个按钮.每个按钮可以同时控制这n盏灯--按下了第i个按钮,对于所有的灯都有一个效果.按下i按钮对于第j盏灯,是下面3中效果之一:如果a[i][j]为1,那么当这盏灯开了的时 ...

  8. UVA 658 状态压缩+隐式图+优先队列dijstla

    不可多得的好题目啊,我看了别人题解才做出来的,这种题目一看就会做的实在是大神啊,而且我看别人博客都看了好久才明白...还是对状态压缩不是很熟练,理解几个位运算用了好久时间.有些题目自己看着别人的题解做 ...

  9. uva 11088 暴力枚举子集/状压dp

    https://vjudge.net/problem/UVA-11088 对于每一种子集的情况暴力枚举最后一个三人小组取最大的一种情况即可,我提前把三个人的子集情况给筛出来了. 即 f[S]=MAX{ ...

随机推荐

  1. Delphi中如何进行BASE64解码

    //方法1: uses EncdDecd; Memo2.Text:=UTF8Decode( DecodeString(Memo1.Text)); //方法2: // 使用控件 Memo2.Text:= ...

  2. 黑域,黑阈 Permission denied

    在执行: adb -d shell sh /data/data/me.piebridge.brevent/brevent.sh 时遇到Permission denied,多运行一次就好了. 完整的有两 ...

  3. http网站上传文件大小问题【没测试过】

    web.config <httpRuntime maxRequestLength="" executionTimeout=""/> IIS 请求筛选 ...

  4. T-SQL select语句连接两个表

    当一个表中按条件出现多个记录时,会按照匹配条件生成多个结果记录.left out 和right out 是对不能匹配的记录发生作用.

  5. Consul实践指导-DNS接口

    DNS是consul提供的主要查询接口之一.DNS接口允许应用程序在没有与consul高度集成的情况下使用服务发现. 例如:替代consul的HTTP API请求,主机能够通过名字查找直接使用DNS服 ...

  6. 服务注册发现consul之四: 分布式锁之四:基于Consul的KV存储和分布式信号量实现分布式锁

    一.基于key/value实现 我们在构建分布式系统的时候,经常需要控制对共享资源的互斥访问.这个时候我们就涉及到分布式锁(也称为全局锁)的实现,基于目前的各种工具,我们已经有了大量的实现方式,比如: ...

  7. 学习笔记之NumPy

    NumPy — NumPy http://www.numpy.org/ NumPy is the fundamental package for scientific computing with P ...

  8. 学习笔记之Lazy evaluation

    Lazy evaluation - Wikipedia https://en.wikipedia.org/wiki/Lazy_evaluation In programming language th ...

  9. linux一些基本知识

    一.linux i386是32位的,amd64是64位(一般情况不限intel或者amd)       server是服务器版,desktop是桌面版 Desktop是社区开源版,拥有一些新功能新软件 ...

  10. jQuery绑定和解绑点击事件及重复绑定解决办法

    原文地址:http://www.111cn.net/wy/jquery/47597.htm 绑点击事件这个是jquery一个常用的功能,如click,unbind等等这些事件绑定事情,但还有很多朋友不 ...