奇怪的电视
原创
©著作权归作者所有:来自51CTO博客作者yitahutu79的原创作品,请联系作者获取转载授权,否则将追究法律责任
题目描述
小明过年的时侯去如姥姥家,除夕之夜,大家都想看春节联欢晚会,而可以依赖的就是一台旧电视。
那一台旧电视不是遥控器控制的,上面有许多按钮,按下某一按钮,其他按钮都将被释放,只有被按的按钮工作(如果其他按钮本来就是释放的状态,那么它们保持不变,处于按下状态的按钮不能重复按下,这对下文依旧适用)。当小明到来的那一天,上面的许多按钮突然无法正常工作。现在按下某个按钮后,有一些按钮将被释放,而另外的一些按钮将不改变原状态。经过一番惨无人道的折腾,小明知道按下每一个按钮会产生什么样的效果。现在他只需要第3个按钮正常工作。
现在帮助小明计算,从给定的状态到只有按钮3工作,而其他按钮都被释放这个最终状态所需按下的按钮序列的最短长度。
输入
第一行一个整数 N,表示按钮数。(3≤N≤20)
第二行包含 N 个数,表示各按钮的初始状态。0 表示相应的按钮是释放的,1 表示相应的按钮是按下的。
接下来的 N 行,表示按下某个按钮时将有那些按钮被释放。第 M+2 行由数字 K 开头,紧跟着 K 个数字(按升序排列),表示当按下按钮 M 时被释放的按钮数及按钮号码(按钮号码用数字 1∼M 表示)。每个按钮不能释放其本身,也可能不释放任何按钮。
输出
输出一个数,表示从给定的状态到只有按钮3工作而其他按钮都被释放这个最终状态所需按下的按钮序列的最短长度。
样例输入
5
1 1 0 0 1
4 2 3 4 5
4 1 3 4 5
2 2 4
0
4 1 2 3 4
样例输出
3
数据规模与约定
时间限制:1 s
内存限制:256 M
100% 的数据保证 3≤N≤20
#include <iostream>
#include <queue>
using namespace std;
struct node {
int status, step;
};
int n, num[25], arr[25][25], check[2200000];
void init() {
int t = 1;
for (int i = 0; i < 21; i++) {
num[i] = t;
t *= 2;
}
}
int main() {
init();
cin >> n;
int start_status = 0;
for (int i = 1; i <= n; i++) {
int t;
cin >> t;
if (t == 1) start_status += num[i];
}
for (int i = 1; i <= n; i++) {
cin >> arr[i][0];
for (int j = 1; j <= arr[i][0]; j++) {
cin >> arr[i][j];
arr[i][24] += num[arr[i][j]];
}
}
queue<node> que;
que.push({start_status, 0});
check[start_status] = 1;
while (!que.empty()) {
node temp = que.front();
que.pop();
if (temp.status == 8) {
cout << temp.step << endl;
return 0;
}
for (int i = 1; i <= n; i++) {
if ((temp.status & num[i]) == 0) {
int status_temp = temp.status + num[i];
status_temp &= ~(arr[i][24]);
if (!check[status_temp]) {
check[status_temp] = 1;
que.push({status_temp, temp.step + 1});
}
}
}
}
return 0;
}