標籤:i++ code index oid 搜尋 bool 開關 並且 開啟
題意:給你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 = 11;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[10][1025];priority_queue<Node>q;int perLights[10] = { 1 << 0,1 << 1,1 << 2 ,1 << 3 ,1 << 4 ,1 << 5 , 1 << 6,1 << 7,1 << 8 ,1 << 9 };void read(){ int ss, ee; for (int i = 0;i < d;i++) { cin >> ss >> ee; //start with 0 conn[ss - 1][ee - 1] = 1; conn[ee - 1][ss - 1] = 1; } for (int i = 0;i < s;i++) { cin >> ss >> ee; contro[ss - 1][ee - 1] = 1; }}Node bfs(){ Node node; node.cur = 0; node.curStepNum = 0; node.lights = 1; q.push(node); //init node 只有0房間是亮的 states[0][1] = 1; 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 - 1) && curLights == perLights[r - 1]) { return node; } //枚舉燈的狀態 for (int i = 0;i < 10; i++) { if (contro[curIndex][i] == 0) continue; if (i == curIndex) continue; //控制的燈 int nextControLightIndex = i; string desc = ""; int nextLight = 0; if ((curLights & perLights[nextControLightIndex]) == perLights[nextControLightIndex]) { //關閉next房間的燈 nextLight = (curLights ^ perLights[nextControLightIndex]); if (states[curIndex][nextLight] == 1) //repeat continue; desc = "- Switch off light in room " + std::to_string(nextControLightIndex + 1); desc += "."; } else { //開啟next房間的燈 nextLight = curLights | perLights[nextControLightIndex]; if (states[curIndex][nextLight] == 1) //repeat continue; desc = "- Switch on light in room " + std::to_string(nextControLightIndex + 1); desc += "."; } Node newNode; newNode.curStepNum = curStepNum + 1; newNode.cur = curIndex; newNode.lights = nextLight; newNode.step = node.step; newNode.step.push_back(desc); //push to queue q.push(newNode); states[curIndex][nextLight] = 1; } //end curIndex enum lights state //start door for (int i = 0;i < 10;i++) { if (curIndex == i) continue; if (conn[curIndex][i] == 0) continue; int nextDoor = i; if ((perLights[nextDoor] & curLights) == 0) //燈是滅的,不能進 continue; if (states[nextDoor][curLights] == 1) //已經看到過,不能進 continue; //燈是開著的,能進 Node newNode; newNode.cur = nextDoor; newNode.curStepNum = curStepNum + 1; newNode.lights = curLights; newNode.step = node.step; string desc = "- Move to room " + std::to_string(nextDoor + 1); desc += "."; newNode.step.push_back(desc); states[nextDoor][curLights] = 1; q.push(newNode); } } node.cur = -1; return node;}int main(){ int t = 0; while (cin >> r >> d >> s) { if (r == d && d == s && r == 0) break; memset(conn, 0, sizeof(conn)); memset(contro, 0, sizeof(conn)); memset(states, 0, sizeof(states)); while (q.empty() == false) q.pop(); read(); cout << "Villa #"; cout << t + 1 << endl; if (r == 1) { cout << "The problem can be solved in " << 0 << " steps:" << endl; } else { Node node = bfs(); //cout << "test" << endl; if (node.cur == -1) { 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 = 0;i <= b.size() - 1;i++) cout << b[i] << endl;; } } t++; cout << endl; }}
uva-321-暴力枚舉-隱式圖搜尋