UVA 592 - Island of Logic

本文深入探讨了AI音视频处理领域中的关键技术,特别是视频分割与语义识别。详细解释了如何利用AI技术对视频进行有效分割,并实现对视频内容的准确理解与识别。

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

 

 

 

 

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值