题意:给你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. SDRAM单字写操作

    SDRAM单字写操作 1.单字写操作时序 2.写verilog程序体会 在初始状态,先写好跳转条件.If()....else... 3.通过仿顺序操作来实现连续写操作 首先完成单字写操作,然后跳转到下 ...

  2. The Best KPIs to Use in Your Company

    Here is a list of key performance indicators (KPIs) that should be used in contact centres, alongsid ...

  3. linux新手非常有用的20个命令

    引用:http://www.oschina.net/translate/useful-linux-commands-for-newbies 1. ls命令 ls命令是列出目录内容(List Direc ...

  4. excel技巧--文本拆分合并

    如果像上图那样将一单元格内拆分成同等大小的字词,可用如下步骤: 1.将该单元格的宽度缩至拆分词的大小: 2.选择同列的适当的单元格,用于填充拆分的字符: 3.点击“开始”-->填充-->两 ...

  5. java流程控制与选择控制

    流程控制语句 顺序   程序的正常执行 选择 if else多重if,嵌套if,switch; 循环 for whlie,do whlie; 案例1 自己对代码进行改进!!!!!!!!!!!!!!! ...

  6. InfluxDB 1.6文档

    警告!此页面记录了不再积极开发的InfluxDB的早期版本.InfluxDB v1.7是InfluxDB的最新稳定版本. InfluxDB是一个时间序列数据库,旨在处理高写入和查询负载.它是TICK堆 ...

  7. 黄聪:3分钟学会sessionStorage用法

    前言: 因最近移动端开发过程中遇到一个运营提出的所谓技术难点需求,对于原生APP来说轻而易举,毕竟自己的APP用户操作指哪打哪,但是H5该怎么做?H5就实现不了么?对于一个爱研究攻克这些前端棘手问题的 ...

  8. DB2如何将数据库表解锁

    死锁是应用程序争抢资源造成de,把相关应用程序结束掉就可以解除死锁了 先用list application for database yourdatabasename show detail 来看看应 ...

  9. P1706 全排列问题

    题解:(其实我认为它就是个循环) #include<iostream> #include<cstdio> #include<iomanip> using names ...

  10. 阿里云kubernetes被minerd挖矿入侵

    阿里云kubernetes被minerd挖矿入侵 # kubectl get rc mysql1 -o yaml apiVersion: v1 kind: ReplicationController ...