思路:穷举出所有运动员的排名顺序,然后对观众的话进行判断,俩句都对或两句都错就继续回溯。但是这个思路有一个测试点一直没过不知道在哪,希望大神找一下
#include<bits/stdc++.h>
#include<iostream>
using namespace std;
int n,m;
int flat=1,all_flat=0;
int lis[100][100];//输入
int x[100][2];//判断观众哪句话对哪句话错
int boy[20];//10运动员
int number[10];//输入用过的名次void look_x(){
for(int i=1;i<=m;i++){
for(int j=1;j<=2;j++){
cout<<x[i][j];
}
cout<<endl;
}
cout<<endl;
}void panduan(int i,int j){//如果说m的某句话预测到这个结过,而且是假话
for(int r=1;r<=m;r+=1){//遍历m观众r说中
if((i==lis[r][1]&&j==lis[r][2])){
x[r][1]=1;//r的第一句话说中了
}
if((i==lis[r][3]&&j==lis[r][4])){
x[r][2]=1;
}
}
}void can_it(){
for(int i=1;i<=m;i++){
if(x[i][1]==x[i][2]){
flat=0;
break;
}
}
if(flat==1){
all_flat=1;
//printf("it can\n");
for(int j=1;j<=n;j++){
if(j!=1)cout<<" ";
cout<<boy[j];
}
cout<<endl;
}
return;
}void backtrack(int num){//第几个运动员
if(num>n){//每个boy都参考完毕
for(int i=1;i<=n;i++){
//cout<<boy[i]<<" ";
panduan(i,boy[i]);
}
//cout<<endl;
flat=1;
//look_x();
can_it();
memset(x,0,sizeof(x));
return;
}
for(int i=1;i<=n;i++){//n名次
//t运动员未记录,number为该数字有没有用过
if (number[i]==0){
boy[num]=i;//1号排名i
number[i]=1;//数字用过
backtrack(num+1);
//boy[num]=0;
number[i]=0;
}
}
}int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){//m个观众猜的每俩句话
int j=1;
while(j<=4){
cin>>lis[i][j];//第i个观众句话,j1运动员j2名,j3运动员j4名
j++;
}
}
backtrack(1);//从第1个boy开始逐个检测
if(all_flat==0){
cout<<"None"<<endl;
}
return 0;
}