非传递骰子 C++题解

为了消磨牛棚里的时光,奶牛们喜欢玩简单的骰子游戏。

其中一种游戏使用两个骰子 XX 和 YY 进行。

两个骰子均被投掷,获胜的骰子是显示的数字较大的骰子。

如果两者显示相同的数字,则重新投掷(只要持续打平,骰子可能会被重新投掷多次)。

如果骰子 XX 比骰子 YY 赢的概率更大,我们称骰子 XX 击败骰子 YY。

考虑以下三个的 44 面骰子:

骰子 AA 在各面上有数字 44,55,66 和 77。

骰子 BB 在各面上有数字 22,44,55 和 1010。

骰子 CC 在各面上有数字 11,44,88 和 99。

这些骰子满足一个相当奇妙的性质:AA 击败 BB,BB 击败 CC,并且 CC 也击败 AA。

可以看出,三个骰子都不是「最佳的」,因为没有任意一个骰子可以击败其他两个骰子。

在这种情况下,当没有两个骰子打平,也没有一个骰子是最佳的,我们称这三个骰子的集合为「非传递的」。

在非传递的三个骰子的集合中,每个骰子击败一个其他骰子,并输给另一个其他骰子。

给定两个 44 面骰子 AA 和 BB 各面上的数字,请帮助奶牛们求出是否有方法为第三个骰子 CC 的各面分配数字,使得这个骰子的集合是非传递的。

所有骰子面上的数字必须是 11 到 1010 的整数。

输入格式

每个测试用例包含多个独立的子测试用例,必须全部回答正确才能通过整个测试用例。

输入的第一行包含 TT,为你需要求解的子测试用例的数量。

以下 TT 行,每行描述了一个子测试用例,包含 88 个整数:骰子 AA 的 44 面上的整数,以及骰子 BB 的 44 面上的整数。

所有的数均在 11 到 1010 之间,不一定排序。

可能同一个数会出现多次,即使在同一个骰子上也可能出现多个相同的数。

输出格式

输出 TT 行。如果有可能为骰子 CC 分配数字使得第 kk 个测试用例成为一个非传递的骰子集合,则第 kk 行输出 yes,否则输出 no

数据范围

1≤T≤101≤T≤10,
所有骰子面上的数字均是 11 到 1010 的整数。

输入样例:

3
4 5 6 7 2 4 5 10
2 2 2 2 1 1 1 1
1 1 1 1 2 2 2 2

输出样例:

yes
no
no

样例解释

第一个子测试用例对应题目中的例子。

在第二个子测试用例中,不存在骰子 CC 可以使得这个骰子集合是非传递的。

同理第三个子测试用例的答案也是 no

判断ABC中没有最佳也不能打平,直接暴力判断是否满足A->B->C 或者B->A->C等无法胜利的情况。

#include <bits/stdc++.h>

using namespace std;

const int N = 5;

int a[N], b[N];
int n;

bool judge(int a[],int b[])
{
	int win = 0, lose = 0;
	
	for(int i = 0; i < 4; i ++ )
	{
		for(int j = 0; j < 4; j ++ )
		{
			if(a[i] > b[j]) win ++;
			if(a[i] < b[j]) lose ++;
		}
	}
	return win > lose;
}
bool solve(int a[],int b[])
{
	for(int i = 1; i <= 10; i ++ )
	{
		for(int j = 1; j <= 10; j ++ )
		{
			for(int k = 1; k <= 10; k ++ )
			{
				for(int u = 1; u <= 10; u ++ )
				{
					int c[4] = {i, j, k, u};
					if(judge(a, b) && judge(b, c) && judge(c, a)) return true;
					if(judge(b, a) && judge(a, c) && judge(c, b)) return true;
				}
			}
		}
	}
	return false;
}
int main ()
{
	cin >> n;
	
	while(n -- )
	{
		for(int i = 0; i < 4; i ++ ) cin >> a[i];
		for(int i = 0; i < 4; i ++ ) cin >> b[i];
		
		if(solve(a, b)) cout << "yes" << endl;
		else cout << "no" << endl;
	}
	
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值