uva-321-暴力枚举-隐式图搜索

题意:给你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;
} }
上一篇:Android+Sqlite 实现古诗阅读应用(一)


下一篇:xss 防止攻击,恶意用户将输入的信息当成html或js代码执行,办法是将用户输入的信息改为text格式,或特殊符号转义