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