uva 592 Island of Logic

题目地址:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=107&page=show_problem&problem=533


题目描述:


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 ABCDE, 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 ABCDE. 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!



Miguel A. Revilla 
1998-03-10




题意:

说一个叫逻辑岛的地方住着三种生物,神族  人族   和 虫族(对应于星际争霸。。。)  这三个种族有以下特点:

1.神族只能说真话

2.虫族只能说假话

3.人族 在白天 只能说真话  在晚上只能说假话

先给出一系列对话  让你做出相应的判断。


题解:

注意到仅有ABCDE五个生物的判断,所以直接穷举出ABCDE的全部种族可能性 然后再用每一种穷举出的可能去验证一系列对话的真实性。

在验证过程中 实际上就是求所有可能出现的矛盾。

然后我们用一个答案数组来存储所有情况中合理的情况。

在验证的过程中,若检测出矛盾 则这种情况是不被加入答案数组的,若是合理的则加入。当所有情况遍历完后,整理答案数组(合并求最大交集)。

若整理后的答案数组中  仅有一个答案 则输出具体的答案结果。

  若有多个答案 则是不能推出任何确切的答案 即No facts are deducible。

  若有零个答案 自然就是impossible了。


所涉及的struct结构  info。

将input中的叙述转化为info的结构

info结构有{叙述者,被叙述者,肯定语气or否定语气,叙述内容/叙述宾语};

算法伪代码:
procedure
{

    switch(A)//A is divine or evil or human
    {
        swtich(B)
        {
            ......
            {
                swtich(E)
                {
                    swtich(weather)//weather is day or night
                    {
                        if(check()==true)//这一种枚举情况是合理的,那么加入答案数组
                        {
                            AddAns();
                        }
                    }
                }
            }
        }
    }
    ArrangeAns();//整理答案,包括去除重复答案,空/无意义 答案,合并等价答案 //等等,求答案的最大交集 若不为空 将答案集数量置1 并且内容值即为最大交集的内容
    if(count==1)
    {
        OutputAns();
    }
    else if(count==0)
    {
        impossible;
    }
    else
    {
        no facts....
    }
}


check 的矛盾检测:

for:遍历n条叙述
{
    按叙述分类讨论:I am 类  ,X is 类 ,It is类
    {
        case I am:
        {
            按叙述宾语展开:
            {
                按叙述者身份展开讨论:
                {
                    按肯定和否定展开
                    {
                        按被叙述者展开:
                        {
                            讨论存在的矛盾 若矛盾return(false);
                        }
                    }
                }
            }
        }
        ..............//后面的类型讨论与上述大同小异。
    }
}


代码:

/*
uva:592 - Island of Logic
	
evil cannot tell the truth that is he always is lying

if lying then it must not be truth and it must be false

I want to use brute force to deal with it

5 persons A B C D E

for every one that can be three states: divine  evil   human



then we could know who lying according to this and who tell the truth
and that we will check the suppose whether it is correct


think about that the case of the "conflict" occurs is what

1.divine tell not truth or divine lying
2.evil tell the truth
3.human say truth in night and say lying in day

we think about the ans again
1.success means the valid answer is unique
2.impossible means the all possible answer is conflict
3.undeducible means there are more than two answers is success

so we should save every deducible result
and in the end we would analysis these result


I don't know the sample 2
how dose it is maked???

now it's so upset for me that the code is WA for the test data of discuss#############


I can not pass  the test data # 7  #8  #15 at present in 2013 4.15
I have passed all the given test data in 2013 4.16 but still get WA in uva OJ
	take the standard program and i will make the random test data
*/
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
using namespace std;

int Inhabitants[5]={0};//means A B C D E;
int OldInhabitants[5]={0};
//0 means no this person
//1 means divine
//2 means evil
//3 means human
//4 means this person is exist but can not comfirm his ID
int Weathers=0;//0->did not know the weather 1->day 2->night
int OldWeathers=0;

int Result[243][5]={0};//3*3*3*3*3  Resuilt[i][0]==-1 is invalid
bool IsValid[243]={false};
int ResultWea[243]={0};
int ValidCnt=0;
int cnt=0;//count the number of the results
int Strongs[243]={0};//the value of strong the more divine human or evil the bigger the value is
int MaxStrongs=0;//save the max strongs
int Refer[5]={0};//0 is not refer  1 is refer

bool IsConflict=false;

/*save the input info and construct it*/
typedef struct Info
{
	char Sayer;
	char Object[5];//A B C D E I(ABCDE) it
	bool IsOrNot;//true means is  false means is not
	char Content[20+5];
	Info()
	{
		Sayer='\0';
		memset(Object,'\0',sizeof(Object));
		IsOrNot=false;
		memset(Content,'\0',sizeof(Content));
	}
}Info;//note that sort the info array

int n=0;
char GStr[20+5]={'\0'};

/*make a proper struction*/
int MakeStruction(char GStr[],Info Information[],int i)
{
	Information[i].Sayer=GStr[0];
	if(GStr[3]=='I')
	{
		if(GStr[4]=='t')
		{
			strcpy(Information[i].Object,"It");
		}
		else
		{
			Information[i].Object[0]=GStr[0];
			Information[i].Object[1]='\0';
		}
	}
	else
	{
		Information[i].Object[0]=GStr[3];
		Information[i].Object[1]='\0';
	}
	if(strstr(GStr,"not")==NULL)
	{
		Information[i].IsOrNot=true;
	}
	else
	{
		Information[i].IsOrNot=false;
	}
	strcpy(Information[i].Content,strrchr(GStr,' ')+1);//divine lying etc.
	return(0);
}

/*check the Inhabitants whether is valid,n is the end of the check index 0~n*/
bool Check(Info Information[],int end)
{
	int i=0,j=0;
	for(i=0;i<=n-1;i++)//scan the info
	{
		bool IsOrNot=Information[i].IsOrNot;
		//I am ...
		if(Information[i].Object[0]==Information[i].Sayer)
		{
			switch(Information[i].Content[0])
			{
				case 'l'://lying
				//find this identity
				if(IsOrNot&&Inhabitants[Information[i].Sayer-'A']==1)//divine did not lying
				{
					return(false);
				}
				if(IsOrNot&&Inhabitants[Information[i].Sayer-'A']==3&&Weathers==1)//human did not lying in day
				{
					return(false);
				}
				if(IsOrNot&&Inhabitants[Information[i].Sayer-'A']==3&&Weathers==2)//human did not lying in day
				{
					return(false);
				}
				//it's uncomfirmed
				if(IsOrNot&&Inhabitants[Information[i].Sayer-'A']==2)//evil did not tell the truth he did not say he is lying
				{
					return(false);
				}
				if(IsOrNot&&Weathers==0&&Inhabitants[Information[i].Sayer-'A']==3)
				{
					return(false);
				}
				if(!IsOrNot&&Inhabitants[Information[i].Sayer-'A']==2)//divine did not lying
				{
					return(false);
				}
				if(!IsOrNot&&Inhabitants[Information[i].Sayer-'A']==3&&Weathers==2)//human did not lying in day
				{
					return(false);
				}
				if(!IsOrNot&&Inhabitants[Information[i].Sayer-'A']==3&&Weathers==0)
				{
					return(false);
				}
				break;
				case 'd'://divine,two ways thinking,who can not say this words that is to say it's conflict
				if(IsOrNot&&Inhabitants[Information[i].Sayer-'A']==3&&Weathers==1)
				{
					return(false);
				}
				if(IsOrNot&&Inhabitants[Information[i].Sayer-'A']==3&&Weathers==0)
				{
					return(false);
				}
				if(!IsOrNot&&Inhabitants[Information[i].Sayer-'A']==3&&Weathers==2)
				{
					return(false);
				}
				if(!IsOrNot&&Inhabitants[Information[i].Sayer-'A']==3&&Weathers==0)
				{
					return(false);
				}
				if(!IsOrNot&&Inhabitants[Information[i].Sayer-'A']==1)
				{
					return(false);
				}
				if(!IsOrNot&&Inhabitants[Information[i].Sayer-'A']==2)
				{
					return(false);
				}
				break;
				case 'e'://evil
				if(IsOrNot&&(Inhabitants[Information[i].Sayer-'A']==2||Inhabitants[Information[i].Sayer-'A']==1))//evil did not tell the truth
				{
					return(false);
				}
				if(IsOrNot&&Inhabitants[Information[i].Sayer-'A']==3&&Weathers==1)
				{
					return(false);
				}
				if(IsOrNot&&Inhabitants[Information[i].Sayer-'A']==3&&Weathers==0)
				{
					return(false);
				}
				if(!IsOrNot&&Inhabitants[Information[i].Sayer-'A']==3&&Weathers==2)
				{
					return(false);
				}
				if(!IsOrNot&&Inhabitants[Information[i].Sayer-'A']==3&&Weathers==0)
				{
					return(false);
				}
				//#####################Inhabitants[Information[i].Sayer-'A']==3&&Weathers==0 is also false
				break;
				case 'h'://human
				if(IsOrNot&&Inhabitants[Information[i].Sayer-'A']==1)
				{
					return(false);
				}
				if(IsOrNot&&Weathers==2&&Inhabitants[Information[i].Sayer-'A']==3)
				{
					return(false);
				}
				if(IsOrNot&&Weathers==0&&Inhabitants[Information[i].Sayer-'A']==3)
				{
					return(false);
				}
				if(!IsOrNot&&Inhabitants[Information[i].Sayer-'A']==2)
				{
					return(false);
				}
				if(!IsOrNot&&Weathers==1&&Inhabitants[Information[i].Sayer-'A']==3)
				{
					return(false);
				}
				if(!IsOrNot&&Weathers==0&&Inhabitants[Information[i].Sayer-'A']==3)
				{
					return(false);
				}
				//human always match to the weather  that is to say  if there are human it must we konw the weather
				//the comfirm of human need the comfirm fo weather
				//if(Weathers==0)
//				{
//					return(false);
//				}
				break;
				default:
				break;
			}
		}
		//X is ...
		else if(Information[i].Object[0]!=Information[i].Sayer&&Information[i].Object[1]!='t')
		{
			switch(Information[i].Content[0])
			{
				case 'l'://lying
				if(IsOrNot&&Inhabitants[Information[i].Sayer-'A']==1)//divine say the truth
				{
					if(Inhabitants[Information[i].Object[0]-'A']==1)//divine did not lying
					{
						return(false);
					}
					if(Inhabitants[Information[i].Object[0]-'A']==3&&Weathers==1)
					{
						return(false);
					}
					if(Inhabitants[Information[i].Object[0]-'A']==3&&Weathers==0)
					{
						return(false);
					}
					//how about weather is 0??
				}
				if(IsOrNot&&Inhabitants[Information[i].Sayer-'A']==2)//evil say not the truth
				{
					if(Inhabitants[Information[i].Object[0]-'A']==2)
					{
						return(false);
					}
					if(Inhabitants[Information[i].Object[0]-'A']==3&&Weathers==2)
					{
						return(false);
					}
					if(Inhabitants[Information[i].Object[0]-'A']==3&&Weathers==0)
					{
						return(false);
					}
				}
				if(IsOrNot&&Inhabitants[Information[i].Sayer-'A']==3)//human the day and night
				{
					if(Weathers==1)
					{
						if(Inhabitants[Information[i].Object[0]-'A']==1)//divine did not lying
						{
							return(false);
						}
						if(Inhabitants[Information[i].Object[0]-'A']==3&&Weathers==1)
						{
							return(false);
						}
					}
					else if(Weathers==2)
					{
						if(Inhabitants[Information[i].Object[0]-'A']==2)
						{
							return(false);
						}
						if(Inhabitants[Information[i].Object[0]-'A']==3&&Weathers==2)
						{
							return(false);
						}
					}
					else
					{
						return(false);
					}
				}
				if(!IsOrNot&&Inhabitants[Information[i].Sayer-'A']==1)//divine
				{
					if(Inhabitants[Information[i].Object[0]-'A']==2)
					{
						return(false);
					}
					if(Inhabitants[Information[i].Object[0]-'A']==3&&Weathers==2)
					{
						return(false);
					}
					if(Inhabitants[Information[i].Object[0]-'A']==3&&Weathers==0)
					{
						return(false);
					}
				}
				if(!IsOrNot&&Inhabitants[Information[i].Sayer-'A']==2)
				{
					if(Inhabitants[Information[i].Object[0]-'A']==1)
					{
						return(false);
					}
					if(Inhabitants[Information[i].Object[0]-'A']==3&&Weathers==1)
					{
						return(false);
					}
					if(Inhabitants[Information[i].Object[0]-'A']==3&&Weathers==0)
					{
						return(false);
					}
				}
				if(!IsOrNot&&Inhabitants[Information[i].Sayer-'A']==3)
				{
					if(Weathers==1)
					{
						if(Inhabitants[Information[i].Object[0]-'A']==2)
						{
							return(false);
						}
						if(Inhabitants[Information[i].Object[0]-'A']==3&&Weathers==2)
						{
							return(false);
						}
					}
					else if(Weathers==2)
					{
						if(Inhabitants[Information[i].Object[0]-'A']==1)
						{
							return(false);
						}
						if(Inhabitants[Information[i].Object[0]-'A']==3&&Weathers==1)
						{
							return(false);
						}
					}
					else
					{
						return(false);
					}
				}
				break;
				case 'd'://divine
				if(IsOrNot&&Inhabitants[Information[i].Sayer-'A']==1)//divine say the truth
				{
					if(Inhabitants[Information[i].Object[0]-'A']!=1)
					{
						return(false);
					}
				}
				if(IsOrNot&&Inhabitants[Information[i].Sayer-'A']==2)//evil say not the truth
				{
					if(Inhabitants[Information[i].Object[0]-'A']==1)
					{
						return(false);
					}
					if(Inhabitants[Information[i].Object[0]-'A']==3&&Weathers==0)
					{
						return(false);
					}
				}
				if(IsOrNot&&Inhabitants[Information[i].Sayer-'A']==3)//human the day and night
				{
					if(Weathers==1)
					{
						if(Inhabitants[Information[i].Object[0]-'A']!=1)
						{
							return(false);
						}
					}
					else if(Weathers==2)
					{
						if(Inhabitants[Information[i].Object[0]-'A']==1)
						{
							return(false);
						}
					}
					else
					{
						return(false);
					}
				}
				if(!IsOrNot&&Inhabitants[Information[i].Sayer-'A']==1)
				{
					if(Inhabitants[Information[i].Object[0]-'A']==1)
					{
						return(false);
					}
					if(Inhabitants[Information[i].Object[0]-'A']==3&&Weathers==0)
					{
						return(false);
					}
				}
				if(!IsOrNot&&Inhabitants[Information[i].Sayer-'A']==2)
				{
					if(Inhabitants[Information[i].Object[0]-'A']!=1)
					{
						return(false);
					}
				}
				if(!IsOrNot&&Inhabitants[Information[i].Sayer-'A']==3)
				{
					if(Weathers==1)
					{
						if(Inhabitants[Information[i].Object[0]-'A']==1)
						{
							return(false);
						}
					}
					else if(Weathers==2)
					{
						if(Inhabitants[Information[i].Object[0]-'A']!=1)
						{
							return(false);
						}
					}
					else
					{
						return(false);
					}
				}
				break;
				case 'e'://evil
				if(IsOrNot&&Inhabitants[Information[i].Sayer-'A']==1)//divine say the truth
				{
					if(Inhabitants[Information[i].Object[0]-'A']!=2)
					{
						return(false);
					}
				}
				if(IsOrNot&&Inhabitants[Information[i].Sayer-'A']==2)//evil say not the truth
				{
					if(Inhabitants[Information[i].Object[0]-'A']==2)
					{
						return(false);
					}
					if(Inhabitants[Information[i].Object[0]-'A']==3&&Weathers==0)
					{
						return(false);
					}
				}
				if(IsOrNot&&Inhabitants[Information[i].Sayer-'A']==3)//human the day and night
				{
					if(Weathers==1)
					{
						if(Inhabitants[Information[i].Object[0]-'A']!=2)
						{
							return(false);
						}
					}
					else if(Weathers==2)
					{
						if(Inhabitants[Information[i].Object[0]-'A']==2)
						{
							return(false);
						}
					}
					else
					{
						return(false);
					}
				}
				if(!IsOrNot&&Inhabitants[Information[i].Sayer-'A']==1)
				{
					if(Inhabitants[Information[i].Object[0]-'A']==2)
					{
						return(false);
					}
					if(Inhabitants[Information[i].Object[0]-'A']==3&&Weathers==0)
					{
						return(false);
					}
				}
				if(!IsOrNot&&Inhabitants[Information[i].Sayer-'A']==2)
				{
					if(Inhabitants[Information[i].Object[0]-'A']!=2)
					{
						return(false);
					}
				}
				if(!IsOrNot&&Inhabitants[Information[i].Sayer-'A']==3)
				{
					if(Weathers==1)
					{
						if(Inhabitants[Information[i].Object[0]-'A']==2)
						{
							return(false);
						}
					}
					else if(Weathers==2)
					{
						if(Inhabitants[Information[i].Object[0]-'A']!=2)
						{
							return(false);
						}
					}
					else
					{
						return(false);
					}
				}
				break;
				case 'h'://human
				//uncomfirmed
				if(IsOrNot&&Inhabitants[Information[i].Sayer-'A']==1)//divine say the truth
				{
					if(Inhabitants[Information[i].Object[0]-'A']!=3)
					{
						return(false);
					}
				}//we forgot the is and is not..................................
				if(IsOrNot&&Inhabitants[Information[i].Sayer-'A']==2)//evil say not the truth
				{
					if(Inhabitants[Information[i].Object[0]-'A']==3)
					{
						return(false);
					}
				}
				if(IsOrNot&&Inhabitants[Information[i].Sayer-'A']==3)//human the day and night
				{
					if(Weathers==1)
					{
						if(Inhabitants[Information[i].Object[0]-'A']!=3)
						{
							return(false);
						}
					}
					else if(Weathers==2)
					{
						if(Inhabitants[Information[i].Object[0]-'A']==3)
						{
							return(false);
						}
					}
					else
					{
						return(false);
					}
				}
				if(!IsOrNot&&Inhabitants[Information[i].Sayer-'A']==1)
				{
					if(Inhabitants[Information[i].Object[0]-'A']==3)
					{
						return(false);
					}
				}
				if(!IsOrNot&&Inhabitants[Information[i].Sayer-'A']==2)
				{
					if(Inhabitants[Information[i].Object[0]-'A']!=3)
					{
						return(false);
					}
				}
				if(!IsOrNot&&Inhabitants[Information[i].Sayer-'A']==3)
				{
					if(Weathers==1)
					{
						if(Inhabitants[Information[i].Object[0]-'A']==3)
						{
							return(false);
						}
					}
					else if(Weathers==2)
					{
	  					if(Inhabitants[Information[i].Object[0]-'A']!=3)
						{
							return(false);
						}
					}
					else
					{
						return(false);
					}
				}
				break;
				default:
				break;
			}
		}
		//It is ...  no isornot bool
		else//if there are two weathers which one we should select to our standard weathers??
		{//sorry that we have burte forced the standard weathers
			int day=(Information[i].Content[0]=='d')?1:2;
			if(Weathers>0)
			{
				if(Inhabitants[Information[i].Sayer-'A']==1)
				{
					if(Weathers!=day)
					{
						return(false);
					}
				}
				if(Inhabitants[Information[i].Sayer-'A']==2)
				{
					if(Weathers==day)
					{
						return(false);
					}
				}
				if(Inhabitants[Information[i].Sayer-'A']==3)
				{
					if(Weathers==1)
					{
						if(Weathers!=day)
						{
							return(false);
						}
					}
					else//2
					{
						if(Weathers==day)
						{
							return(false);
						}
					}
				}
			}
		}
	}
	return(true);
}

/*result[cnt++]=inhabitants*/
int AddResult()
{
	int i=0;
	int strongs=0;
	for(i=0;i<=5-1;i++)
	{
		Result[cnt][i]=Inhabitants[i];
		if(Inhabitants[i]!=4&&Inhabitants[i]!=0)
		{
			strongs++;
		}
	}
	ResultWea[cnt]=Weathers;
	Strongs[cnt]=strongs;
	IsValid[cnt]=true;
	if(MaxStrongs<strongs)
	{
		MaxStrongs=strongs;
	}
	cnt++;
	return(0);
}

/*output the onlu one successful case*/
int OutputTruth()
{
	int i=0,j=0;
	for(i=0;i<=cnt-1;i++)
	{
		if(IsValid[i])
		{
			for(j=0;j<=5-1;j++)
			{
				switch(Result[i][j])
				{
					case 1://divine
					printf("%c is divine.\n",j+'A');
					break;
					case 2://evil
					printf("%c is evil.\n",j+'A');
					break;
					case 3://human
					printf("%c is human.\n",j+'A');
					break;
					default:
					break;
				}
			}
			if(ResultWea[i]>0)
			{
				if(ResultWea[i]==1)
				{
					printf("It is day.\n");
				}
				else
				{
					printf("It is night.\n");
				}
			}
		}
	}
	return(0);
}

/*compare for the sort*/
bool cmp(Info A,Info B)
{
	return(A.Sayer<B.Sayer);
}

/*compare the array*/
bool IsEqual(int a[],int b[],int M)
{
	int i=0;
	for(i=0;i<=M-1;i++)
	{
		if(a[i]!=b[i])
		{
			return(false);
		}
	}
	if(OldWeathers!=Weathers)
	{
		return(false);
	}
	return(true);
}

/*copy the value sets*/
int HabCpy(int a[],int b[],int M)
{
	int i=0;
	for(i=0;i<=M-1;i++)
	{
		a[i]=b[i];
	}
	return(0);
}

/*check the repeat element*/
bool IsRepeat()
{
	int i=0;
	for(i=0;i<=cnt-1;i++)
	{
		if(IsValid[i]==false)
		{
			continue;
		}
		//Weathers==ResultWea[i]&&
		if(Inhabitants[0]==Result[i][0]&&Inhabitants[1]==Result[i][1]&&Inhabitants[2]==Result[i][2]&&Inhabitants[3]==Result[i][3]&&Inhabitants[4]==Result[i][4])
		{
			if(Weathers==ResultWea[i])
			return(true);
		}
	}
	return(false);
}

/*is all 4 them we could not add*/
bool IsAllNotKnow()
{
	int i=0;
	for(i=0;i<=5-1;i++)
	{
		if(Inhabitants[i]==4||Inhabitants[i]==0)
		{
			;
		}
		else
		{
			return(false);
		}
	}
	
	//weathers??
	return(true);
}

/*judge this type , onliy one bit is diffrent besides it's 1 2 3 struction*/
bool IsFourType(int &FourPos,int Prev2,int Prev1,int Now)
{
	int j=0;
	int diffCnt=0;
	int diffPos=0;
	for(j=0;j<=5-1;j++)
	{
		if(Result[Prev2][j]==Result[Prev1][j]&&Result[Prev1][j]==Result[Now][j])
		{
			
		}
		else
		{
			diffCnt++;
			diffPos=j;
		}
	}
	if(diffCnt==1&&ResultWea[Prev2]==ResultWea[Prev1]&&ResultWea[Prev1]==ResultWea[Now]&&Result[Prev2][diffPos]==1&&Result[Prev1][diffPos]==2&&Result[Now][diffPos]==3)
	{
		FourPos=diffPos;
		return(true);
	}
	else
	{
		return(false);
	}
}

/*weather 1  weather 2->0*/
bool IsWeatherType(int now,int prev)
{
	if(Result[now][0]==Result[prev][0]&&Result[now][1]==Result[prev][1]&&Result[now][2]==Result[prev][2]&&Result[now][3]==Result[prev][3]&&Result[now][4]==Result[prev][4])
	{
		if(ResultWea[now]+ResultWea[prev]==3)//1 2 or 2 1
		{
			return(true);
		}
	}
	return(false);
}

/*arrange the result clean the lower truth  and 1 2 3 => 4*/
int ArrangeResult()
{
	//find the max strong
	int i=0,j=0;
	//note that inconsecutive
	int Prev2=-1,Prev1=-1,Now=-1;
	int Count1=0,Count2=0;
	int prev=-1,now=0;//the array is inconsecutive
	Count1=1;
	Count2=1;
	while(Count1||Count2)
	{
		Count1=0;
		Prev2=-1;
		Prev1=-1;
		Now=-1;
		for(i=0;i<=cnt-1;i++)
		{
			if(IsValid[i])
			{
				Now=i;
				if(Strongs[i]<MaxStrongs)
				{
					IsValid[i]=false;
					ValidCnt--;
				}
				else
				{
					if(Now>=0&&Prev1>=0&&Prev2>=0)//is 1 2 3 =>4 type
					{
						int FourPos=0;
						if(IsFourType(FourPos,Prev2,Prev1,Now))
						{
							IsValid[i-1]=false;
							ValidCnt--;
							IsValid[i-2]=false;
							ValidCnt--;
							IsValid[i]=true;
							Result[i][FourPos]=4;
							Count1++;//if there are no fourtypes the Count is 0
						}
					}
				}
				if(IsValid[Now])
				{
					Prev2=Prev1;
					Prev1=Now;
				}
			}
		}
		Count2=0;
		prev=-1;
		now=0;
		for(i=0;i<=cnt-1;i++)
		{
			if(IsValid[i])//conbine the weathers
			{
				if(prev>=0)
				{
					now=i;
					if(IsWeatherType(now,prev))
					{
						IsValid[prev]=false;
						ValidCnt--;
						IsValid[now]=true;
						ResultWea[now]=0;
						Count2++;
					}
				}
				prev=now;
			}
		}
	}
	//all 0 or all 4  is invalid
	for(i=0;i<=cnt-1;i++)
	{
		if(IsValid[i])
		{
			int ValueCnt=0;
			int j=0;
			for(j=0;j<=5-1;j++)
			{
				if(Result[i][j]!=4&&Result[i][j]!=0)
				{
					ValueCnt++;
				}
			}
			if(ValueCnt==0)
			{
				IsValid[i]=false;
				ValidCnt--;
			}
		}
	}
	
	int Conbine[5]={0};
	int ConWea=0;
	//get the bigist U such as 21202!1 U 23202!1=20202!1
	//printf("####%d####\n",ValidCnt);
 	now=-1;
	prev=-1;
	for(j=0;j<=5-1;j++)
	{
		now=-1;
		prev=-1;
		for(i=0;i<=cnt-1;i++)
		{
			if(IsValid[i])
			{
				now=i;
				if(prev>=0)
				{
					if(Result[now][j]==Result[prev][j])
					{
						Conbine[j]=Result[now][j];
					}
					else
					{
						Conbine[j]=0;
						break;
					}
				}
				prev=now;
			}
		}
	}
	//weather
	now=-1;
	prev=-1;
	for(i=0;i<=cnt-1;i++)
	{
		if(IsValid[i])
		{
			now=i;
			if(prev>=0)
			{
				if(ResultWea[now]==ResultWea[prev])
				{
					ConWea=ResultWea[now];
				}
				else
				{
					ConWea=0;
					break;
				}
			}
			prev=now;
		}
	}
	//check the Conbine is or is not valid
	int ValueCnt=0;
	for(j=0;j<=5-1;j++)
	{
		if(Conbine[j]!=4&&Conbine[j]!=0)
		{
			ValueCnt++;
		}
	}
	if(ConWea>0)
	{
		ValueCnt++;
	}
	if(ValueCnt>0)
	{
		ValidCnt=1;
		cnt=1;
		Result[0][0]=Conbine[0];
		Result[0][1]=Conbine[1];
		Result[0][2]=Conbine[2];
		Result[0][3]=Conbine[3];
		Result[0][4]=Conbine[4];
		ResultWea[0]=ConWea;
		IsValid[0]=true;
	}
	return(0);
}

/*for test*/
int test()
{
	return(0);
}
int cases=0;

/*main process*/
int MainProc()
{
	while(scanf("%d",&n)!=EOF&&n>0)
	{
		getchar();//because of gets()  , we eat the \n
		int i=0;
		Info Information[n];
		memset(Inhabitants,0,sizeof(Inhabitants));
		memset(OldInhabitants,0,sizeof(OldInhabitants));
		memset(Strongs,0,sizeof(Strongs));
		MaxStrongs=0;
		memset(IsValid,false,sizeof(IsValid));
		IsConflict=false;
		cnt=0;
		cases++;
		printf("Conversation #%d\n",cases);
		OldWeathers=-1;
		for(i=0;i<=n-1;i++)//get the data and make it data struction from the input
		{
			gets(GStr);
			MakeStruction(GStr,Information,i);
			Inhabitants[GStr[0]-'A']=4;//flag the appeared inhabitants,this is refer operation
			if(GStr[3]>='A'&&GStr[3]<='E')
			{
				Inhabitants[GStr[3]-'A']=4;
			}
		}
		//sort the information
		sort(Information,Information+n,cmp);
		//for(i=0;i<=5-1;i++)
//		{
//			if(Inhabitants[i]==4)
//			{
//				int j=0;
//				for(j=1;j<=3;j++)
//				{
//					Inhabitants[i]=j;
//				}
//			}
//		}//it will set up the threes tree to travels
		int j0,j1,j2,j3,j4;
		for(j0=1;j0<=3;j0++)
		{
			if(Inhabitants[0]>0)//if the info refer to the person then we can brute force it
			{
				Inhabitants[0]=j0;
			}
			//if(Check(0)==false)//check the suppose wether have the conflict
//			{
//				Inhabitants[0]=4;//it is still uncomfirmed
//				continue;
//			}//check the middle role is a little difficult for the design of the check function
			for(j1=1;j1<=3;j1++)
			{
				if(Inhabitants[1]>0)
				{
					Inhabitants[1]=j1;
				}
				//if(Check(1)==false)
//				{
//					Inhabitants[1]=4;//it is still uncomfirmed
//					IsConflict=true;
//					continue;
//				}
				for(j2=1;j2<=3;j2++)
				{
					if(Inhabitants[2]>0)
					{
						Inhabitants[2]=j2;
					}
					//if(Check(2)==false)
//					{
//						Inhabitants[2]=4;//it is still uncomfirmed
//						IsConflict=true;
//						continue;
//					}
					for(j3=1;j3<=3;j3++)
					{
						if(Inhabitants[3]>0)
						{
							Inhabitants[3]=j3;
						}
						//if(Check(3)==false)
//						{
//							Inhabitants[3]=4;//it is still uncomfirmed
//							IsConflict=true;
//							continue;
//						}
						for(j4=1;j4<=3;j4++)
						{
							if(Inhabitants[4]>0)
							{
								Inhabitants[4]=j4;
							}
							for(Weathers=1;Weathers<=2;Weathers++)//weather brute force
							{
								//for debug
								if(j0==1&&j1==1&&j2==3&&j3==2&&j4==1)
								{
									j0=1;
								}
								//many redundancy checked
								if(!IsEqual(Inhabitants,OldInhabitants,5)&&!IsRepeat())
								{
									if(Check(Information,4)==false)
									{
										IsConflict=true;
										HabCpy(OldInhabitants,Inhabitants,5);
										OldWeathers=Weathers;
										continue;
									}
									else//it's successfully true
									{
										if(!IsAllNotKnow())
										AddResult();//result[cnt++]=inhabitants
										HabCpy(OldInhabitants,Inhabitants,5);
										OldWeathers=Weathers;
										if(Weathers==0)
										{
											break;//the weather is unnecessary
										}
									}
								}
							}
						}
					}
				}
			}
		}
		//display the Result array
		//printf("****************************\n");
//		printf("%d.\n",cnt);
//		for(i=0;i<=cnt-1;i++)
//		{
//			if(IsValid[i])
//			{
//				printf("   #%d\n",i);
//				int j=0;
//				for(j=0;j<=5-1;j++)
//				{
//					printf("%d",Result[i][j]);
//				}
//				printf("!%d",ResultWea[i]);
//				printf("\n");
//			}
//		}
		//maybe impossible or undeducible or success
		ValidCnt=cnt;
		//arrange the result array  1 2 3->4  inhabitants  and 1 2 ->0 weather
		ArrangeResult();
		if(ValidCnt==0)//impossible
		{
			printf("This is impossible.\n");
		}
		else if(ValidCnt==1)//success
		{
			OutputTruth();//judge the weather
		}
		else//undeducble
		{
			printf("No facts are deducible.\n");
			//for test
			//printf("****************************\n");
//			int i=0;
//			for(i=0;i<=cnt-1;i++)
//			{
//				if(IsValid[i])
//				{
//					printf("   #%d\n",i);
//					int j=0;
//					for(j=0;j<=5-1;j++)
//					{
//						printf("%d",Result[i][j]);
//					}
//					printf("!%d",ResultWea[i]);
//					printf("\n");
//				}
//			}
		}
		printf("\n");
	}
	return(0);
}

int main()
{
	MainProc();
	return(0);
}








  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值