P8091 Non-Transitive Dice 题解
注:连更了3篇,都是洛谷的题
因为题面上写了“所有骰子面上的数字必须是 \(1\) 到 \(10\) 的整数”,而且骰子只有4面因此考虑爆搜,时间复杂度最多 \(\Theta(10^4)\)。
实现起来也很简单,对于每个面上的数字都枚举一遍 \(1\) 到 \(10\),每一种枚举情况都尝试能不能击败骰子 A,而且被骰子 B 击败。至于如何判断骰子 X 是否击败骰子 Y,可以用这样一个函数:
bool jibai(int a[],int b[]){//判断骰子A能不能击败骰子B
int tot=0;//计算胜利可能数
for(int i=1;i<=4;i++){
for(int j=1;j<=4;j++){
if(a[i]>b[j]) tot++;//记录
if(a[i]<b[j]) tot--;
}
}
return tot>0;//A击败了B
}
不过主函数里还需要注意一些细节。最后上整体代码:
#include<iostream>
using namespace std;
int a[5],b[5];//输入a和b
bool jibai(int a[],int b[]){//刚才的击败函数
int tot=0;
for(int i=1;i<=4;i++){
for(int j=1;j<=4;j++){
if(a[i]>b[j]) tot++;
if(a[i]<b[j]) tot--;
}
}
return tot>0;
}
int c[5],ans;
void dfs(int now){//暴力枚举
if(now>4){//一种可能
if(jibai(b,c)&&jibai(c,a)) ans++;//如果没问题,就算上答案的一种
return;
}
for(int i=1;i<=10;i++){//从1到10尝试
c[now]=i;
dfs(now+1);
}
return;
}
int main(){
int t;
cin>>t;
while(t--){
ans=0;
cin>>a[1]>>a[2]>>a[3]>>a[4]>>b[1]>>b[2]>>b[3]>>b[4];//输入
if(jibai(b,a)){//让a一定能击败b
swap(a[1],b[1]);swap(a[2],b[2]);swap(a[3],b[3]);swap(a[4],b[4]);
}
if(!jibai(a,b)){//在a一定能击败b的时候a没法击败b,就是平局(这句有点绕,自行理解,上一个a一定能击败b其实指的是不会被b击败)
cout<<"no"<<endl;
continue;
}
dfs(1);//暴力枚举
if(ans) cout<<"yes"<<endl;
else cout<<"no"<<endl;
}
return 0;
}