您的位置:首页 > 其它

HOJ 1022 Spacecraft Malfunction

2012-06-07 23:19 621 查看
先看下题目:

It is said that court intrigues started with people lying about other people, and then lying about other people’s lying, and so it went. The intriguers constantly looked for scapegoat who inevitably proved to be someone with the least power, though not always
the least morality.

We have faced a similar problem, but this time, in our malfunctioning spacecraft! There are a number of units in the spacecraft. The units are so reliable that it would surprise us very much if more than one unit were faulty. If more than one is faulty, we
would lose the probe, so we are sure that exactly one unit is faulty in our spacecraft.

We know that each unit checks exactly two others, and each unit will be checked by at least one other unit. A good unit will give accurate diagnosis of the units it checks. For example, if unit X is good and it says that Y is faulty and Z is good, then, in
fact, Y is faulty and Z is good. However, a bad unit is unreliable. So, if unit X is faulty and makes the same statements, then Y may or may not be good, and Z may or may not be good either. Note that a unit cannot check itself.

Now suppose that you have the reports from all units and your duty is to find which unit is indeed faulty.

Input

The first line of the input file contains a single integer t (1 <= t <=10), the number of test cases, followed by the input data for each test case. The first line of each test case contains an integer n (3 <= n <= 100), the number of units, followed by n lines
each describing a unit and the result of its checks. The line starts with a positive integer number which shows the identification number of the unit. After the id number, there are two pairs of checked unit id's and check results. A check result is a single
character which is either Y or N, showing whether the result of checking is good or faulty respectively. As an example, the fourth line in the Sample Input section shows that unit 16 has checked unit 8 saying it is good, and has checked unit 32 saying it is
faulty.

Output

There should be one line per test case containing either the id number of the faulty unit, or the word impossible (with lower-case letters), if it is impossible to find the faulty unit from the input data.

Sample Input

1
5
2 16 Y 32 N
16 8 Y 32 N
32 8 N 4 Y
8 4 Y 2 Y
4 2 Y 16 Y

Sample Output

32

题目可以形象的描述为,一堆人在一起,其中有一个骗子,每个人只能并且必须评论两个人,比如上面的例子,2号说16号说的是真话,32号说的是假话。16号说8号说的是真话,32说的是假话....让你找到这几个人里面的骗子,有可能会找不出来,那就打出impossible。

解题思路:

这是一个搜索问题,首先我们先假定2号说的是真的,那么根据2号的话,16号也是真的,然后8号也是真的,然后4号和2号是真的,然后4号说2号和16号真的,出现一个循环,那么假设验证过程结束,说明2号的话没问题。然后我们假定32说的是真的,那么4号是真的,然后2号是真的,然后2号说32号是假的,这里出现矛盾,说明假设不成立,最后32号是骗子。

这里要注意个问题,如果假定某个人说的是真的,而他说的话是某某是假的,另个某某也是假的,这个人光说哪两个人是骗子,没说哪个人的话是真的。这时候我们就先不处理这个假设,先处理其他假设,如果其他假设都是真的,那么这个假设就是假的。否则他就是真的。如果出现两人以上这样的只说谁是骗子的人,而其余假设都是真的,那么就打出impossible。具体代码如下:

#include <iostream>

#include <cstring>

#include <set>

#define MAX 1000

using namespace std;

bool judge(int **p,int unit[],int flag[],int n,int x,set<int>s)

{

int i;

for(i=0;i<n;i++)

{

if(p[x][unit[i]]==1)

{

if(flag[unit[i]]==0)

{

flag[unit[i]]=1;

}

else if(flag[unit[i]]==-1)

{

return false;

}

}

else if(p[x][unit[i]]==-1)

{

if(flag[unit[i]]==0)

{

flag[unit[i]]=-1;

}

else if(flag[unit[i]]==1)

{

return false;

}

}

}

bool st=true;

for(i=0;i<n;i++)

{

if(p[x][unit[i]]==1)

{

if(!s.count(unit[i]))

{

s.insert(unit[i]);

st=st&&judge(p,unit,flag,n,unit[i],s);

}

}

}

return st;

}

int main()

{

int t,i,n;

cin>>t;

for(i=0;i<t;i++)

{

int x,y1,j;

char y2;

cin>>n;

int *q=new int[MAX*MAX];

memset(q,0,MAX*MAX*sizeof(int));

int **p=new int*[MAX]; //存储输入

for(j=0;j<MAX;j++)

{

p[j]=q+MAX*j;

}

int flag[MAX]={0}; //存储验证假设的过程中,每个人的标志

int unit
; //存储每个人的标号

for(j=0;j<n;j++)

{

cin>>x>>y1>>y2;

unit[j]=x;

if(y2=='Y')

{

p[x][y1]=1;

}

else

{

p[x][y1]=-1;

}

cin>>y1>>y2;

if(y2=='Y')

{

p[x][y1]=1;

}

else

{

p[x][y1]=-1;

}

}

int fg=1;

int xx=-1;

set<int>s;

for(j=0;j<n;j++)

{

int ii;

int fgg=1;

for(ii=0;ii<n;ii++)

{

if(p[unit[j]][unit[ii]]==1)

{

fgg=0;

break;

}

}

if(fgg) //全是N的情况

{

xx=j;

continue;

}

s.clear();

memset(flag,0,sizeof(int)*MAX);

s.insert(unit[j]);

flag[unit[j]]=1;

if(!judge(p,unit,flag,n,unit[j],s))

{

cout<<unit[j]<<endl;

fg=0;

break;

}

}

if(fg)

{

if(xx!=-1)

{

cout<<unit[xx]<<endl;

}

else

{

cout<<"impossible"<<endl;

}

}

delete q;

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: