牛客训练营3 H 智乃的比较函数(normal vision)

ps:本蒟蒻看了蛮久才看懂的,感觉题解视频讲的不是很能一次听懂,故有了这篇题解

在c++标准库中,存在一个叫做std::sort的函数,它可以默认按照升序的方式排序,或者按照一种给定的自定义方式排序。


新手在使用自定义比较函数进行sort时,经常会因为没有遵守sort传入比较函数的约定而导致代码崩溃。

具体来讲,使用sort时需要定义一个比较函数cmp(x,y)cmp(x,y)cmp(x,y)他表示比较在排序的过程中xxx的顺序是否严格小于yyy的顺序,如果xxx的顺序严格小于yyy的顺序,则cmp(x,y)=1cmp(x,y)=1cmp(x,y)=1,反之cmp(x,y)=0cmp(x,y)=0cmp(x,y)=0。

新手在编写cmpcmpcmp函数时的一个易错点是在xxx和yyy的值相等时令cmp(x,y)=1cmp(x,y)=1cmp(x,y)=1,例如降序排序时将x>yx>yx>y写成了x≥yx \geq yx≥y。
 

抛开c++语言的底层实现,这样其实已经产生了逻辑矛盾。因为当xxx和yyy的值相等时cmp(x,y)=cmp(y,x)=1cmp(x,y)=cmp(y,x)=1cmp(x,y)=cmp(y,x)=1,在调用约定中,它表示在排序中xxx的顺序严格小于yyy且yyy的顺序严格小于xxx,显然这里产生了逻辑矛盾。所以此时无论c++库函数执行出任何的结果都是可能的,一般来讲这将导致运行错误。

所以在编写cmp(x,y)cmp(x,y)cmp(x,y)时,一定要注意,当xxx和yyy的值相等时,应该令cmp(x,y)=cmp(y,x)=0cmp(x,y)=cmp(y,x)=0cmp(x,y)=cmp(y,x)=0,这表示通知排序函数,不能确定在排序中xxx的顺序严格小于yyy,同时也不能确定yyy的顺序严格小于xxx,当然,从逻辑上讲,这只有一种情况,就是x=yx=yx=y,并未产生任何逻辑矛盾。


现在有三个整形变量a1,a2,a3a_{1},a_{2},a_{3}a1​,a2​,a3​(你可以认为这三个变量的值是int范围内任意的整数),告诉你NNN组cmp(ax,ay)cmp(a_x,a_y)cmp(ax​,ay​)的值,问是否产生了逻辑矛盾。

输入描述:

第一行输入一个正整数T(1≤T≤2×104)T(1\leq T \leq 2\times 10^{4})T(1≤T≤2×104)表示测试用例的组数。

对于每组测试用例,第一行输入一个正整数N(1≤N≤50)N(1\leq N \leq 50)N(1≤N≤50)表示约束条件的数目,接下来NNN行,每行输入三个整数x,y,z(x,y∈{1,2,3},z∈0,1)x,y,z(x,y\in \{1,2,3\},z\in {0,1})x,y,z(x,y∈{1,2,3},z∈0,1)表示第iii个约束关系为cmp(ax,ay)=zcmp(a_x,a_y)=zcmp(ax​,ay​)=z。

输出描述:

对于每组测试用例,若没有矛盾,则输出"Yes",否则输出"No",你可以输出任意大小写的"Yes"和"No"。

示例1

输入

复制1 3 1 2 1 2 3 1 3 1 1

1
3
1 2 1
2 3 1
3 1 1

输出

复制No

No

说明

三个变量a1<a2a_{1}<a_{2}a1​<a2​成立且a2<a3a_{2}<a_{3}a2​<a3​成立且a3<a1a_{3}< a_{1}a3​<a1​成立,显然有逻辑矛盾。

示例2

输入

复制1 4 1 2 1 1 2 1 2 1 0 2 1 0

1
4
1 2 1
1 2 1
2 1 0
2 1 0

输出

复制Yes

Yes

说明

注意输入的约束可能会重复,并不要求输入的约束条件能够完全将三者排序,仅要求不产生矛盾就输出"Yes"。

示例3

输入

复制3 1 1 1 0 1 1 1 1 2 1 2 0 1 2 1

3
1
1 1 0
1
1 1 1
2
1 2 0
1 2 1

输出

复制Yes No No

Yes
No
No

说明

注意输入的xxx和yyy可以相等

思路:

暴力枚举。l数组里存储三个数字可能会出现的所有大小关系,一共有13种。对于每一组数据,将他们与l中出现的情况逐一对比,若有一种l中出现的情况能使该组数据无矛盾,则成立,输出Yes,

否则输出No.

#include<bits/stdc++.h>
using namespace std;
int l[13][4]={//列出所有可能的情况
	{0,1,1,1},
	{0,1,1,2},
	{0,1,2,1},
	{0,2,1,1},
	{0,2,1,2},
	{0,2,2,1},
	{0,1,2,2},
	{0,1,2,3},
	{0,1,3,2},
	{0,2,1,3},
	{0,3,1,2},
	{0,3,2,1},
	{0,2,3,1},
};
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n;
		cin>>n;
		int flag=0,fflag=1;//fflag表示对l枚举的当前这组数据是否有矛盾的地方
		int x[n],y[n],z[n];
		for(int i=0;i<n;i++)//输入
			cin>>x[i]>>y[i]>>z[i];
		for(int i=0;i<13;i++)
		{	
			fflag=1;
			for(int j=0;j<n;j++)
			{
				if((l[i][x[j]]<l[i][y[j]])!=z[j])
				{
					fflag=0;//有矛盾
				}
			}
			flag=max(flag,fflag);//在l所表示的所有情况中,有一种情况成立则全部情况都成立
		}
		if(flag)cout<<"Yes"<<endl;
		else cout<<"No"<<endl;
	}
}

  • 14
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值