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;
}

posted @ 2022-02-07 18:56  cyx001  阅读(87)  评论(0编辑  收藏  举报