⿊⽩⽆常
问题描述
某寝室的同学们在学术完之后准备玩⼀个游戏:
游戏是这样的,每个⼈头上都被贴了⼀张⽩⾊或者⿊ ⾊的纸,现在每个⼈都会说
⼀句话“我看到x张⽩⾊纸条和y张⿊⾊的纸条”,
⼜已知每个头上贴着⽩⾊ 纸的⼈说的是真话、每个头上贴着⿊⾊纸的⼈说的是谎话,
现在要求你判断哪些⼈头上贴着的是⽩⾊ 的纸条,如果⽆解输出“NoSolution.”;
如果有多组解,则把每个答案中贴⽩条的⼈的编号按照⼤⼩排 列后组成⼀个数
(⽐如第⼀个⼈和第三个⼈头上贴着的是⽩纸条,那么这个数就是13;
如果第6、7、 8个⼈都贴的是⽩纸条,那么这个数就是678)
输出最⼩的那个数(如果全部都是⿊纸条也满⾜情况的 话,那么输出0)
输⼊格式
第⼀⾏为⼀个整数n,接下来n⾏中的第i⾏有两个整数x和y,分别表示第i个⼈说“我看到x张⽩⾊纸条 和y张⿊⾊的纸条”。
输出格式
⼀⾏。如果⽆解输出“NoSolution.”。
否则输出答案中数值(具体⻅问题描述)最⼩的那个,如果全部 都是⿊纸条也满⾜情况的话,那么输出0
样例输⼊
2
1 0
1 0
样例输出
0
样例输⼊
5
3 1
0 4
1 3
4 0
1 3
样例输出
35
数据规模和约定
n<=8
分析:
1.枚举所有⼈的⿊⽩字条情况,判断当前情况是否可能存在,把所有可能情况收集起来输出最 ⼩的
2.注意每⼈看不到⾃⼰头上的字条~~~
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> ansv;
pair<int, int> v[10];
int n, k, cnt, a[10];
void dfs(int num) {
if ( num == 0) {
int white = 0, black = 0, ans = 0;
for ( int i = 1; i <= n; i++) {
if (a[i] == -1) black++;
if (a[i] == 1) white++;
}
for (int i = 1; i <= n; i++) {
if (a[i] == 1 && (v[i].first != white-1 ||v[i].second !=black))
return;
if ( a[i] == -1 && (v[i].first == white && v[i].second ==black-1) )
return;
}
for ( int i = 1; i <= n; i++)
if ( a[i] == 1)
ans = ans * 10 + i;
ansv.push_back(ans);
}
else {
a[num] = -1;
dfs(num - 1);
a[num] = 1;
dfs(num - 1);
}
}
int main() {
scanf("%d", &n);;
for ( int i = 1; i <= n; i++)
scanf("%d%d", &v[i].first, &v[i].second);
dfs(n);
sort(ansv.begin(), ansv.end());
printf("%d\n", ansv[0]);
return 0;
}