这个题目我自己想的时候就是不知道怎么才算判断出有解和无解,然后看了个博主的题解,真的棒,这题真有意思,很有价值,收藏收藏!!
我修改了一下代码方便了我自己去理解,下面贴的代码是改过之后的,然后据说蓝桥杯测试数据有误,,emm或许吧。
转载的链接如下
http://m.blog.csdn.net/qq_34845121/article/details/60339177
代码如下
#include<stdio.h>
#define SIZE 8
int n;
int data[SIZE][2]; //使用SIZE * 2存储数据
int v[SIZE]; //记录黑白 白1 和 黑0
int yes[SIZE];
int ifz = 0; //全局判断是否有0 (如果全部都是黑纸条也满足情况的话,那么输出0)
void judge () {
int i;
int t = 0,f = 0;
int judge = 0; //记录该猜测有几组数据对的上
for(i = 0; i < n; i ++){ //当前猜测下的白的人数,黑的人数
if(v[i] == 1){
t ++;
} else {
f ++;
}
}
int ifZero = 1; //判断是否在全部为黑的时候也通过 (如果全部都是黑纸条也满足情况的话,那么输出0)
for(i = 0; i < n; i ++){ //当前预测下各组数是否满足要求
if(v[i] == 1){ //当前预测下的i+1组数为白是否满足
if(data[i][0] == t-1 && data[i][1] == f)
judge ++;
ifZero = 0; //一旦有白就不可能有0 (如果全部都是黑纸条也满足情况的话,那么输出0)
} else { //当前预测下的i+1组数为黑否满足
if(data[i][0] != t || data[i][1] != f-1)
judge ++;
}
}
if(judge == n){ //该猜测正确
if(ifZero == 1){ //判断是否有0 (如果全部都是黑纸条也满足情况的话,那么输出0)
ifz = 1;
}
for(i = 0; i < n; i ++){ //记录可能的组数
if(v[i] == 1)
yes[i] = 1;
}
}
}
void fun (int k) {
if(k > n-1){ //k为0开始循环全部,每个人有两种可能,两个分支 (0 - 4 )
judge();
return ;
}
v[k] = 1;
fun(k+1); //k+1 为假 (0 - 4 )
v[k] = 0;
fun(k+1); //k+1 为真 (0 - 4 )
}
int main () {
int i,j;
scanf("%d", &n);
for(i = 0; i < n; i ++){
scanf("%d%d", &data[i][0], &data[i][1]);
}
for(i = 0; i < n; i ++){ //初始化
yes[i] = 0;
}
fun(0);
if(ifz == 1){ //有0(如果全部都是黑纸条也满足情况的话,那么输出0)
printf("0");
} else {
int temp = 0; //判断是否无解
for(i = 0; i < n; i ++){ //将记录的数依次输出
if(yes[i] == 1)
printf("%d",i+1);
temp = 1;
}
if(temp == 0){
printf("NoSolution");
}
}
return 0;
}