被传说中的训练计划虐了一个下午。一个搜索图论DP都没做出来,只好找找简单题做做,其实这题我一开始也想的太简单了,以为统计掉了所有平衡的就可以判断了,感觉其实还是要想挺多的,后来经百度提醒要存不等关系时出现的硬币,做完后还是WA,就找discuss的数据,终于过了。
这题的思路就是开个bool a[],如果遇到=就把那些硬币都变成true,遇到不等号就存起来,小的存left[]中,大的存right[]中,left[i]++,right[i]++,如果一个硬币同时在left和right中出现,那么他肯定是真的,但是这样的判断还不够,还是会WA,因为有一组数据5 3 2 1 3 2 4 > 2 3 5 2 4>1 1 4>,答案是4,left中出现了2 4,right中出现了1 3 5,没有重叠出现的数但是我们发现4出现了3次,于是又有了如果某个数在left或者right中出现次数等于不等关系出现的次数,那么他就是假的,当然只有一个硬币出现这种情况,如果是多个营部有种情况,那么应该用a[]中false的个数判断。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int b[105][1005];
int left1[1005];//存不等关系中小的数
int right1[1005];//存不等关系中大的数
int main()
{
int n,k,p,y=0;
char c;
bool a[1005];
memset(a,0,sizeof(a));
memset(left1,0,sizeof(left1));
memset(right1,0,sizeof(right1));
scanf("%d %d",&n,&k);
for(int i=0; i<k; i++)
{
scanf("%d",&p);
for(int j=1; j<=2*p; j++)
{
scanf("%d",&b[i][j]);
}
getchar();//吃回车
scanf("%c",&c);
if(c=='=')
{
for(int j=1; j<=2*p; j++)
a[b[i][j]]=true;
}
if(c=='>')
{
y++;//记录不等情况出现次数
for(int j=1; j<=p; j++) right1[b[i][j]]++;
for(int j=p+1; j<=2*p; j++) left1[b[i][j]]++;
}
if(c=='<')
{
y++;
for(int j=1; j<=p; j++) left1[b[i][j]]++;
for(int j=p+1; j<=2*p; j++) right1[b[i][j]]++;
}
}
int flag=0;
int x=0;
for(int j=1; j<=n; j++)
{
if(left1[j]&&right1[j]) a[j]=true;
if(left1[j]==y||right1[j]==y)
{
flag++;
x=j;
}
}
int ans=0;
int count=0;
if(flag==1) printf("%d\n",x);//只有一个数出现次数等于不等关系的次数
else
{
for(int j=1; j<=n; j++)
{
if(!a[j])
{
ans=j;
count++;
}
}
if(count==1) printf("%d\n",ans);
else printf("0\n");
}
return 0;
}