`
hellobin
  • 浏览: 65510 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

UVA 592 - Island of Logic

    博客分类:
  • UVA
 
阅读更多

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.

 

比较繁琐,思维要缜密。

参考了 http://jianquan.iteye.com/blog/1663651

heavy comment

 

#define RUN
#ifdef RUN

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <vector>
#include <list>
#include <cctype> 
#include <algorithm>
#include <utility>
#include <math.h>
#include <ctime>

using namespace std;

#define MAXN 60

typedef struct Statement{
	// Speaker: [A|B|C|D|E]
	// Subject: [A|B|C|D|E|t]	t:It
	// Status: [d|h|e|l|d|n] d:divine, h:human, e:evil, l:lying, d:day, n:night
	char speaker, subject, status;
	bool positive;
}Statement;

Statement stmt[MAXN];
int lines;
int res[5][4];//保存枚举的结果

void printout(){
	for(int i=0; i<lines; i++){
		cout << "lines:" << i << ",speaker:" << stmt[i].speaker << ",subject:" << stmt[i].subject << ",status:" << stmt[i].status << ",positive:" << stmt[i].positive << endl;
	}
}

void printout2(){
	for(int i=0; i<5; i++){
		for(int j=1; j<=3; j++){
			cout << res[i][j] << " ";
		}
		cout << endl;
	}
}

void saveString(string s){

	//构建一个没有空格的s
	string s2 = "";
	for(int i=0; i<s.length(); i++){
		if(s[i] != ' '){
			s2 += s[i];
		}
	}

	//cout << s2 << endl;

	stmt[lines].speaker = s2[0];


	//输入的是关于day或者night的
	//eg,A:Itisday. 或 A:Itisnight.
	if(s2[3] == 't'){
		stmt[lines].subject = s2[3];
		stmt[lines].status = s2[6];
		stmt[lines].positive = true;
	}
	else{
		
		if(s2[2] == 'I'){
			stmt[lines].subject = stmt[lines].speaker;
		}
		else{
			stmt[lines].subject = s2[2];
		}

		//包含了not
		if(s2[5] == 'n'){
			stmt[lines].status = s2[8];
			stmt[lines].positive = false;
		}
		else{
			stmt[lines].status = s2[5];
			stmt[lines].positive = true;
		}
	}

	lines++;
}

bool judge(int X, int T, bool positive, char status){
	//For X:  1:divine, 2:evil, 3:human
	//For T:  1:day, 2:night
	//For positive: true | false
	//For status:  [d|h|e|l] d:divine, h:human, e:evil, l:lying
	
	char XX;
	switch(X){
	case 1:
		XX = 'd';	break;
	case 2:
		XX = 'e';	break;
	case 3:
		XX = 'h';	break;
	}

	//先判断关于lying的问题
	// is lying
	if(status=='l' && positive){
		//如果对方真的在撒谎,则要么对方是evil,要么对方是晚上的human
		if(XX=='e' || (XX=='h' && T==2)){
			return true;
		}
		else{
			return false;
		}
	}
	
	
	if(status=='l' && !positive){	// is NOT lying
		// 如果对方真的没有在撒谎,则要么对方是divine,要么对方是白天的human
		if(XX=='d' || (XX=='h' && T==1)){
			return true;
		}
		else{
			return false;
		}
	}

	//在判断关于角色的问题
	//同真同假
 	if((status==XX) == positive){
		return true;
	}
	else{
		return false;
	}
}


bool isLegal(int A, int B, int C, int D, int E, int T, int i){
	// Speaker: [A|B|C|D|E]
	// Subject: [A|B|C|D|E|t]	t:It
	// Status: [d|h|e|l|d|n] d:divine, h:human, e:evil, l:lying, d:day, n:night
	char speaker = stmt[i].speaker;
	char subject = stmt[i].subject;
	char status = stmt[i].status;
	bool positive = stmt[i].positive;

	//根据假设条件和所说的话来判断该话是否为真
	bool stateIsTrue = false;
	
	//根据subject来区别判断
	//先判断时间
	if(subject == 't'){
		char time;
		if(T == 1){
			time = 'd';
		}
		else{
			time = 'n';
		}

		//判断假设与说的话是否相同
		stateIsTrue = (time==status);
	}
	else{
		// Subject: [A|B|C|D|E]
		// Status: [d|h|e|l] d:divine, h:human, e:evil, l:lying
		// 再根据subject区别判断
		switch (subject)
		{
		case 'A':
			stateIsTrue = judge(A, T, positive, status);
			break;
		case 'B':
			stateIsTrue = judge(B, T, positive, status);
			break;
		case 'C':
			stateIsTrue = judge(C, T, positive, status);
			break;
		case 'D':
			stateIsTrue = judge(D, T, positive, status);
			break;
		case 'E':
			stateIsTrue = judge(E, T, positive, status);
			break;
		}
	}


	//对照stateIsTrue判断假设是否符合说话人speaker的身份
	if(stateIsTrue){
		//divine或者白天的human说的话必需为真
		switch (speaker)
		{
		case 'A':
			if(A==1 || (A==3 && T==1)){
				return true;
			}
			else{
				return false;
			}
		case 'B':
			if(B==1 || (B==3 && T==1)){
				return true;
			}
			else{
				return false;
			}
		case 'C':
			if(C==1 || (C==3 && T==1)){
				return true;
			}
			else{
				return false;
			}
		case 'D':
			if(D==1 || (D==3 && T==1)){
				return true;
			}
			else{
				return false;
			}
		case 'E':
			if(E==1 || (E==3 && T==1)){
				return true;
			}
			else{
				return false;
			}
		}
	}
	else{
		//evil或者晚上的human说的话必需为假
		switch (speaker)
		{
		case 'A':
			if(A==2 || (A==3 && T==2)){
				return true;
			}
			else{
				return false;
			}
		case 'B':
			if(B==2 || (B==3 && T==2)){
				return true;
			}
			else{
				return false;
			}
		case 'C':
			if(C==2 || (C==3 && T==2)){
				return true;
			}
			else{
				return false;
			}
		case 'D':
			if(D==2 || (D==3 && T==2)){
				return true;
			}
			else{
				return false;
			}
		case 'E':
			if(E==2 || (E==3 && T==2)){
				return true;
			}
			else{
				return false;
			}
		}
	}
}



void test(){

	int A, B, C, D, E, T;
	int i;

	int day=0,night=0;
	memset(res,0,sizeof(res)); 

	//1:divine, 2:evil, 3:human
	for(A=1; A<=3; A++){
		for(B=1; B<=3; B++){
			for(C=1; C<=3; C++){
				for(D=1; D<=3; D++){
					for(E=1; E<=3; E++){

						//时间参数,1为白天,2为晚上
						for(T=1; T<=2; T++){

							//检测lines行说的话
							for(i=0; i<lines; i++){
								if(!isLegal(A,B,C,D,E,T,i)){
								//if(!islegal(i,A,B,C,D,E,T)){
									break;
								}
							}

							//表示检验通过
							if(i == lines){
								//cout << "A:" << A << ",B:" << B << ",C:" << C << ",D:" << D << ",E:" << E << endl;
								res[0][A]=1;  
								res[1][B]=1;  
								res[2][C]=1;  
								res[3][D]=1;  
								res[4][E]=1;

								if(T == 1){
									day = 1;
								}
								else{
									night = 1;
								}
							}
						}
					}
				}
			}
		}
	}

	//printout2();


	int impossible=0,nodeducible=1;

	//关于角色的判定
	for(int i=0;i<5;i++)  
	{
		int cnt=0,index;  
		for(int j=1;j<=3;j++){
			if(res[i][j])  
			{  
				cnt++;  
				index=j;  
			}
		}

		//说明X的条件不符合3种角色中的任意一种
		if(cnt==0)  
		{
			impossible=1;  
			break;  
		}
		else if(cnt==1)		//合理的情况是,X只担任一种角色
		{
			char person = i + 'A';
			if(index==1)  
				cout<<person<<" is divine."<<endl;  
			else if(index==2)  
				cout<<person<<" is evil."<<endl;  
			else  
				cout<<person<<" is human."<<endl;  
			nodeducible=0;
		}
	}

	//关于时间的判定
	if(!day && !night) impossible=1;  
	else if(day && !night)   
	{  
		cout<<"It is day."<<endl;  
		nodeducible=0;  
	}  
	else if(night && !day)  
	{  
		cout<<"It is night."<<endl;  
		nodeducible=0;  
	}

	if(impossible) cout<<"This is impossible."<<endl;  
	else if(nodeducible) cout<<"No facts are deducible."<<endl;  
	putchar('\n');  
}


int main(){

#ifndef ONLINE_JUDGE
	freopen("592.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif

	int n;
	int cases=0;

	cin >> n;
	//cout << "n:" << n << endl;
	getchar();
	while(n != 0){
		cases++;
		cout << "Conversation #" << cases << endl;  
		while(n--){
			string s;
			getline(cin, s);

			//cout << "n:" << n << endl;
			//cout << "s:" << s << endl;

			saveString(s);
		}

		//printout();
		test();


		cin >> n;
		getchar();
		memset(stmt, 0, sizeof(stmt));
		lines = 0;
	}


}


#endif

 

 

 

 

 

分享到:
评论

相关推荐

    UVaOJ-401(Palindromes).zip_401 Palindromes

    标题中的"UVaOJ-401(Palindromes)"表明这是一个关于解决UVa Online Judge(UVa OJ)上编号为401的编程挑战,该挑战的主题是"Palindromes",即回文串。回文串是指一个字符串无论从前读到后还是从后读到前都是相同的,...

    Uva 1510 - Neon Sign

    ### Uva 1510 - Neon Sign #### 问题背景与描述 在题目“Uva 1510 - Neon Sign”中,我们面对的是一个霓虹灯招牌设计问题。该霓虹灯招牌由一系列位于圆周上的角点组成,并通过发光管连接这些角点。发光管有两种...

    uva705-Slash-Maze-.rar_Slash_uva705

    【标题】"uva705-Slash-Maze-.rar_Slash_uva705" 指向的是一个在UVa Online Judge (UVa OJ) 上提交并通过的编程问题,具体为问题编号705,名为"Slash Maze"。这个压缩包很可能包含了该问题的解决方案源代码。 ...

    UVA100~200---52道题accept代码,均顺利accept过

    这些文件名代表的是在UVA(University of Virginia)在线判题系统上解决的编程题目,主要是C++语言编写的解决方案。UVA是一个知名的在线编程竞赛平台,它提供了大量的算法问题供程序员挑战,有助于提高编程技能和...

    开源项目-codingsince1985-UVa#uva-online-judge-solutions-in-golang.zip

    开源项目-codingsince1985-UVa#uva-online-judge-solutions-in-golang.zip,两年来每天都在解决一个uva在线裁判问题,算起来…

    UVA133-TheDoleQueue.zip_site:www.pudn.com_uva133

    UVA(University of Virginia)在线判题系统提供了丰富的算法题目供程序员挑战,其中编号为133的"The Dole Queue"(救济金发放问题)是一个典型的算法问题,旨在测试程序员对优先级队列(Priority Queue)的理解和...

    Algorithm-UVA-Solutions-in-Python.zip

    "Algorithm-UVA-Solutions-in-Python.zip"这个压缩包文件正是针对UVA竞赛中问题的Python 3解决方案集合。 Python作为一门易学且功能强大的编程语言,因其简洁的语法和丰富的库支持,成为了许多算法爱好者和开发者的...

    uva532-Dungeon-Master.rar_dungeon

    在计算机科学与编程领域,UVA(University of Virginia)在线判题系统是一个深受程序员喜爱的平台,它提供了丰富的算法题目供学习者挑战。其中,编号为532的"Dungeon Master"题目是一个关于策略和计算的迷宫游戏,其...

    tpcw-nyu-uva-client 客户端

    "tpcw-nyu-uva-client 客户端"是一个专为TPCW(Transaction Processing Performance Council Workloads)设计的应用程序,由纽约大学(NYU)和弗吉尼亚大学(UVA)共同开发。这个客户端软件主要用于模拟和评估数据库...

Global site tag (gtag.js) - Google Analytics