这题在比赛中一直wa,我的做法是把Y和N分成两个集合,然后枚举N里面的元素当成是坏的,判断剩下的条件有没有矛盾,结果一直wa。今天上课重新yy了一下这题,发现其实里面就只有三种情况。
第一种情况:x y N z N,那么x一定数坏的,因为题中说了只有一个是坏的。
第二种情况:N[x]>=2;表示有两个或两个以上的unit说x是坏的,那么x肯定是坏的。
第三种情况:N[x]==1,N[y]==1,y和x都有人说是坏的(想想为什么只可能有两个是,而不会出现三个的情况),然后如
果是z说x是坏的,然后又w说z是好的,那么x一定是坏的,同理可以对y这样讨论。那么我们可以记录一下是谁说x是坏的和是谁说y是坏的,然后讨论那两个有没有人说他们是好的即可。
全题重点是那个只有1个是坏的,那么只可能是这三种情况。
哎,当时淡定不下来推一推,yy到了做法就去敲了,下次吸取经验才行。
Run ID | User | Problem | Result | Memory | Time | Language | Code Length | Submit Time |
9913144 | 201030720425 | 1359 | Accepted | 672K | 0MS | G++ | 1466B | 2012-03-12 13:08:28 |
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#include<vector>
#define LG long long
using namespace std;
int n,m,N[105],Y[105],fa[105],res[105];
map<int ,int>mp,re;
int main()
{
int T,x,y,z,pos=0,len;
char ch[10],sh[10];
scanf("%d",&T);
while(T--)
{
mp.clear();re.clear(),pos=1;
memset(N,0,sizeof(N));
memset(Y,0,sizeof(Y));
memset(fa,0,sizeof(fa));
scanf("%d",&n);
int flag=0,ans=0;
for(int i=0;i<n;i++)
{
scanf("%d",&x);
if(mp[x]==0)mp[x]=pos,re[pos]=x,x=pos++;
else x=mp[x];
scanf("%d",&y);scanf("%s",ch);
if(mp[y]==0)mp[y]=pos,re[pos]=y,y=pos++;
else y=mp[y];
scanf("%d",&z);scanf("%s",sh);
if(mp[z]==0)mp[z]=pos,re[pos]=z,z=pos++;
else z=mp[z];
if(ch[0]=='N'&&sh[0]=='N')
flag=1,ans=x;
else if(ch[0]=='N')
N[y]++,fa[y]=x,Y[z]++;
else if(sh[0]=='N')
N[z]++,fa[z]=x,Y[y]++;
else Y[z]++,Y[y]++;
}
if(flag==1)printf("%d\n",re[ans]);
else
{
len=0;
for(int i=1;i<pos;i++)
{
if(N[i]>=2)
{
ans=i;break;
}
else if(N[i]==1)
res[len++]=i;
}
if(len==1&&Y[fa[res[0]]]!=0)
ans=res[0];
else if(len==2)
{
if(Y[fa[res[0]]]!=0)
ans=res[0];
else if(Y[fa[res[1]]]!=0)
ans=res[1];
}
if(ans==0)puts("impossible");
else printf("%d\n",re[ans]);
}
}
return 0;
}