您的位置:首页 > 其它

UVA 592 逻辑之岛(暴力枚举)

2013-08-04 12:53 381 查看


  Island of Logic 
The Island of Logic has three kinds of inhabitants: divine beings that always tell the truth, evil beings that always lie, and human beings that are truthful during the day and lie at night. Every inhabitant
recognizes the type of every other inhabitant.
A social scientist wants to visit the island. Because he is not able to distinguish the three kinds of beings only from their looks, he asks you to provide a communication analyzer that deduces facts
from conversations among inhabitants. The interesting facts are whether it is day or night and what kind of beings the speakers are.

Input 

The input file contains several descriptions of conversations. Each description starts with an integer n,
the number of statements in the conversation. The following n lines each contain one statement by an inhabitant. Every statement
line begins with the speaker's name, one of the capital letters A, B, C, D, E,
followed by a colon `:'. Next is one of the following kinds of statements:

I am [not] ( divine | human | evil | lying ).

X
 is [not] ( divine | human | evil | lying ).

It is ( day | night ).

Square brackets [] mean that the word in the brackets may or may not appear, round brackets () mean that exactly one of the alternatives separated by 
|
 must appear. X stands
for some name from A, B, C, D, E. There will be no two consecutive spaces in any statement line, and at most 50 statements in a conversation.
The input is terminated by a test case starting with n = 0.

Output 

For each conversation, first output the number of the conversation in the format shown in the sample output. Then print ``This is impossible.'',
if the conversation cannot happen according to the rules or ``No facts are deducible.'', if no facts can be deduced. Otherwise print all the facts that can be deduced. Deduced facts
should be printed using the following formats:

X
 is ( divine | human | evil ).

It is ( day | night ).

X is to be replaced by a capital letter speaker name. Facts about inhabitants must be given first (in alphabetical order), then it may be stated whether it is day or night.
The output for each conversation must be followed by a single blank line.

Sample Input 

1
A: I am divine.
1
A: I am lying.
1
A: I am evil.
3
A: B is human.
B: A is evil.
A: B is evil.
0


Sample Output 

Conversation #1
No facts are deducible.

Conversation #2
This is impossible.

Conversation #3
A is human.
It is night.

Conversation #4
A is evil.
B is divine.


Reasoning made easy 

To make things clearer, we will show the reasoning behind the third input example, where A says ``I am evil.''. What can
be deduced from this? Obviously A cannot be divine, since she would be lying, similarly A cannot be evil, since she would tell the truth. Therefore, A must be human, moreover, since she is lying, it must be night. So the correct output is as shown.
In the fourth input example, it is obvious that A is lying since her two statements are contradictory. So, B can be neither human nor evil, and consequently must be divine. B always tells the truth, thus
A must be evil. Voil‘a!
题意并不难理解:一座岛上有ABCDE 5个人 给出n条语句。。每条语句的格式为 陈述者:被陈述者 是(不是) 神族 | 人族| 虫族。或者是 陈述者:这是白天 | 夜晚。。神族总是说真话,人族在白天说真话在夜晚说假话, 虫族在白天说真话在夜晚说假话。
然后根据这些语句,推断出每个人的身份和白天黑夜。。如果没有一个能推断出来的信息 输出No facts are deducible. 如果语句中有矛盾,输出This is impossible. 否则输出所有可推断出的信息。。

思路:暴力枚举。。每个人有3种身份。有白天黑夜。一共枚举3 ^ 5 * 2种情况。如果有符合的就保存下来。。然后如果有身份不唯一的人。就记录下来。。后面要输出的是身份(夜晚)唯一确定的。。。

挺恶心的。。一开始写WA了,找不到错哪,先放着。后来看到一个论坛上的数据。。测试了下才找到,,一个很小的细节。。 哎

http://online-judge.uva.es/board/viewtopic.php?f=6&t=2682&p=113439&hilit=592#p113439

这题的测试数据。。。。

代码:

#include <stdio.h>
#include <string.h>

int n;
struct yuju
{
int say;
int to;
int ju;
int tode;
int d_n;
} yu[5555];

int i;
int pnum;
int d_n;
int n_num;
char sb[55];
int de[55];
int vis[55];
int output[55];
int dn;
int outputn[55];
int dni;
void judge()
{
int v = 0;
for (int i = 0; i < n; i ++)
{
if (yu[i].ju == 1)
{
if (de[yu[i].say] == 0 || (de[yu[i].say] == 1 && d_n == 0))
{
if (yu[i].to == -1)
{
if (yu[i].d_n != d_n)
{
v = 1;
break;
}
else
{
continue;
}
}
else
{
if (yu[i].tode == -1)
{
if (yu[i].say == yu[i].to)
{
v = 1;
break;
}
if (de[yu[i].to] == 0 || (de[yu[i].to] == 1 && d_n == 0))
{
v = 1;
break;
}
}
else
{
if (de[yu[i].to] != yu[i].tode)
{
v = 1;
break;
}
}
}
}
if (de[yu[i].say] == 2 || (de[yu[i].say] == 1 && d_n == 1))
{

if (yu[i].to == -1)
{
if (yu[i].d_n == d_n)
{
v = 1;
break;
}
else
{
continue;
}
}
else
{
if (yu[i].tode == -1)
{
if (yu[i].say == yu[i].to)
{
v = 1;
break;
}
if (de[yu[i].to] == 2 || (de[yu[i].to] == 1 && d_n == 1))
{
v = 1;
break;
}
}
else
{
if (de[yu[i].to] == yu[i].tode)
{
v = 1;
break;
}
}
}
}
}
else
{
if (de[yu[i].say] == 0 || (de[yu[i].say] == 1 && d_n == 0))
{
if (yu[i].tode == -1)
{
if (yu[i].say == yu[i].to)
{
continue;
}
if (de[yu[i].to] == 2 || (de[yu[i].to] == 1 && d_n == 1))
{
v = 1;
break;
}
}
else
{
if (de[yu[i].to] == yu[i].tode)
{
v = 1;
break;
}
}
}
if (de[yu[i].say] == 2 || (de[yu[i].say] == 1 && d_n == 1))
{
if (yu[i].tode == -1)
{
if (yu[i].say == yu[i].to)
{
continue;
}
if (de[yu[i].to] == 0 || (de[yu[i].to] == 1 && d_n == 0))
{
v = 1;
break;
}
}
else
{
if (de[yu[i].to] != yu[i].tode)
{
v = 1;
break;
}
}
}
}
}
if (v == 0)
{
for (int i = 0; i < 5 ; i++)
{
if(vis[i] == 1)
{
if (output[i] != de[i])
{
output[i] = de[i];
outputn[i] ++;
}
}
}
if (dn != d_n)
{
dn = d_n;
dni ++;
}
n_num ++;
}
}
void find(int star, int num)
{
if (star == 5)
return;
if(vis[star] == 1)
{
de[star] = 0;
if (num == pnum)
{
judge();
}
find(star + 1, num + 1);
de[star] = 1;
if (num == pnum)
{
judge();
}
find(star + 1, num + 1);
de[star] = 2;
if (num == pnum)
{
judge();
}
find (star + 1, num + 1);
}
else
find(star + 1, num);
}
int main()
{
int t = 1;
while(scanf("%d", &n) != EOF && n)
{
getchar();
dni = 0;
dn = -1;
pnum = 0;
n_num = 0;
d_n = 0;
memset(yu, 0 ,sizeof(yu));
memset(outputn, 0 ,sizeof(outputn));
memset(output, -1, sizeof(output));
memset(de, -1, sizeof(de));
memset(vis, 0, sizeof(vis));
for (i = 0 ; i < n; i ++)
{
gets(sb);
yu[i].say = sb[0] - 'A';
vis[sb[0] - 'A'] = 1;
if (sb[3] != 'I')
{
yu[i].to = sb[3] - 'A';
vis[sb[3] - 'A'] = 1;
}
else if (sb[3] == 'I' && sb[4] != 't')
{
yu[i].to = yu[i].say;
}
else if(sb[3] == 'I' && sb[4] == 't')
{
yu[i].ju = 1;
if(strncmp(sb + 9, "day", 3) == 0)
{
yu[i].to = -1;
yu[i].d_n = 0;
}
if(strncmp(sb + 9, "night", 5) == 0)
{
yu[i].to = -1;
yu[i].d_n = 1;
}
continue;
}
if (strncmp(sb + 8, "not", 3) != 0)
{
yu[i].ju = 1;
if(strncmp(sb + 8, "divine", 6) == 0)
{
yu[i].tode = 0;
}
if(strncmp(sb + 8, "human", 5) == 0)
{
yu[i].tode = 1;
}
if(strncmp(sb + 8, "evil", 4) == 0)
{
yu[i].tode = 2;
}
if(strncmp(sb + 8, "lying", 5) == 0)
{
yu[i].tode = -1;
}
}
else
{
yu[i].ju = 0;
if(strncmp(sb + 12, "divine", 6) == 0)
{
yu[i].tode = 0;
}
if(strncmp(sb + 12, "human", 5) == 0)
{
yu[i].tode = 1;
}
if(strncmp(sb + 12, "evil", 4) == 0)
{
yu[i].tode = 2;
}
if(strncmp(sb + 12, "lying", 5) == 0)
{
yu[i].tode = -1;
}
}
}
for (i = 0; i < 5; i ++)
{
if (vis[i] == 1)
{
pnum ++;
}
}
for(d_n = 0; d_n <= 1; d_n ++)
{
find(0, 1);
}

int fkn = 0;
for ( i = 0 ; i < 5; i ++)
{
if (outputn[i] == 1)
fkn ++;
}
printf("Conversation #%d\n", t ++);
if (n_num == 0)
{
printf("This is impossible.\n\n");
continue;
}
if (n_num > 0 && fkn == 0 && dni > 1)
{
printf("No facts are deducible.\n\n");
continue;
}
if (n_num > 0 && fkn > 0)
{
for(int i = 0; i < 5; i ++)
{
if(vis[i] == 1)
{
if (output[i] == 0 && outputn[i] == 1)
printf("%c is divine.\n", i + 'A');
if (output[i] == 1 && outputn[i] == 1)
{
printf("%c is human.\n", i + 'A');
}
if (output[i] == 2 && outputn[i] == 1)
printf("%c is evil.\n", i + 'A');
}
}
}
if (dni == 1)
{
if (dn == 1)
printf("It is night.\n");
if (dn == 0)
printf("It is day.\n");
}
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: