592 - Island of Logic

题目:592 - Island of Logic


题目大意:岛上住了三种生物,生物‘d’只会说真话,生物‘h’到了白天说真话,晚上说假话。生物‘e’只会说假话,现在要求给你A,B,C,D,E之间的对话(可能对话人物会不满5人)要求能确定的人或是白天黑夜输出。


解题大意:枚举所有的人的角色和白天黑夜,这样一共有3*3*3*3*3*2 = 486种,这题错在数组开太小,卡了好久。还有之前题意理解错误。

然后根据这个人的情况判断描述的人是否符合假设,符合假设将结果保存起来,所以数组最小也要486,因为会存在每一种都有可能 的情况。

在输出结果的数组中判断一下A,B,C,D,E,day在 t 组结果描述中都相同的有哪些,这些是可以输出(因为被确定了),如果本来输出结果数组t就为0,那么说明这种情况不可能,如果A,B,C,D,E,day中不存在一个相同的,那么久说明没有答案被推出。

之前先要将对话保存起来,保存说话的人,被描述的人,或是被描述的天。之后就是根据每个人的角色和当时所在的白天黑夜来判断这些人描述的那些人的实际情况和假设的符不符合。这里只需要找矛盾,模凌两可的也是可以的。

对于撒谎来说,要特别的判断那个被描述的如果是人的话, 还需要看是白天还是黑夜,和之前的判断不一样。


例子的话:http://blog.csdn.net/keshuai19940722/article/details/9752689


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

const int N = 55;
int ans[500][10], n, k, flag, end[6];
char str[3] = {'d', 'e', 'h'}, s2[10], s[N];
char out[3][10] = {"divine.", "human.", "evil."};

struct word{

	char speaker, describer, role;
	int no;
} sp[N];

void handel() {

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

			gets(s);
			sp[i].speaker = s[0];
			if(s[4] == ' '){

				if(s[3] == 'I')
					sp[i].describer = s[0];
				else
					sp[i].describer = s[3];
				if(s[8] == 'n') {

					sp[i].no = 1;
					sp[i].role = s[12];
				}
				else {
					
					sp[i].no = 0;
					sp[i].role = s[8];
				}
			}
			else {
				
				 sp[i].describer = 0;
				 sp[i].speaker = s[0];
				 sp[i].role = s[9];
			}
		}
}
int judge_d(int i, char day){
	
	int a;
	for(int j = 0; j < n; j++){

		if(sp[j].speaker == 'A' + i && sp[j].describer != 0){

			a = sp[j].describer - 'A';

				if(sp[j].role != 'l'){

					if(sp[j].no){
								
						if(s2[a] == sp[j].role)
							return 0;
					}
					else if(sp[j].role != s2[a])
						return 0;
				}
				else {

					if(sp[j].no){

						if(s2[a] == 'e' || (day == 'n' && s2[a] == 'h'))
							return 0;
					}
					else {

						if(s2[a] == 'd' || (day == 'd' && s2[a] == 'h'))
							return 0;
					}
				}
		}	
		else if(sp[j].speaker == 'A' + i && sp[j].describer == 0){

			if(sp[j].role != day)
				return 0;
		}
	}
	return 1;
}

int judge_e(int i, char day){

	int a;
	for(int j = 0; j < n; j++){

		if(sp[j].speaker == 'A' + i && sp[j].describer != 0){

			a = sp[j].describer - 'A';

				if(sp[j].role != 'l'){

					if(sp[j].no){
								
						if(s2[a] != sp[j].role)
							return 0;
					}
					else if(sp[j].role == s2[a])
						return 0;
				}
				else {
				
					if(sp[j].no){

						if(s2[a] == 'd' || (day == 'd' && s2[a] == 'h'))
							return 0;
					}
					else {

						if(s2[a] == 'e' || (day == 'n' && s2[a] == 'h'))
							return 0;
					}
				}
		}
		else if(sp[j].speaker == 'A' + i && sp[j].describer == 0){

			if(sp[j].role == day)
				return 0;
		}
	}
	return 1;
}

int judge_h(int i, char day) {

	if(day == 'd'){
					
		if(!judge_d(i, day))
			return 0;
	}
	else if(day == 'n'){

		if(!judge_e(i, day))
			return 0;
	}
	return 1;
}

int solve(int a) {
	
	char day;
	if(a == 0)
		day = 'd';
	else
		day = 'n';
	int i, m = 0, flag = 1;
	for(i = 0; i < 5; i++) {
			
			if(s2[i] == 'd') {

				if(!judge_d(i, day))
					return 0;
			}
			else if(s2[i] == 'e'){

				if(!judge_e(i, day))
					return 0;
			}
			else {

				if(!judge_h(i, day))
					return 0;	
			}
	}

	return 1;
}

int judge(char a){

	if(a == 'd')
		return 0;
	if(a == 'h')
		return 1;
	if(a == 'e')
		return 2;
	return -1;
}

void search(int &t) {

	for(int i = 0; i < 3; i++)
	for(int j = 0; j < 3; j++)
	for(int g = 0; g < 3; g++)
	for(int m = 0; m < 3; m++)
	for(int v = 0; v < 3; v++){
	for(int h = 0; h < 2 ; h++) {
			
		s2[0] = str[i];
		s2[1] = str[j];
		s2[2] = str[g];
		s2[3] = str[m];
		s2[4] = str[v];
		int flag = solve(h);
		if(flag){

				for(int a = 0; a < 5; a++){
					
					if(judge(s2[a]) != -1)
						ans[t][a] = judge(s2[a]);
				}
				ans[t++][5] = h;
			}
		}

	}
}

void sure(int t) {
	
	/*for(int g = 0; g < t; g++){

		for(int l = 0; l < 6; l++) {

			printf("%c %d ", l + 'A', ans[g][l]);
		}
		printf("\n");
	}*/
	memset(end, -1, sizeof(end));
	int i, j;
	for(i = 0; i < 6; i++) {

			for(j = 1; j < t; j++){
			
				if(ans[j][i] != ans[0][i])
					break;
			}
			if(j == t)
				end[i] = ans[0][i];
	}

}
int main() {

	k = 0;
	int i;
	char ch;
	while(scanf("%d%c", &n, &ch) , n){

		k++;
		printf("Conversation #%d\n", k);

		handel();	

		memset(ans, 0, sizeof(ans));
		memset(s2, 0, sizeof(s2));
	
		int t = 0;
		search(t);

		if(!t){
			
			printf("This is impossible.\n");	
		}
		else {
			
			sure(t);
			int flag = 0;
			for(i = 0; i < 5; i++){
				if(end[i] != -1){

					printf("%c is %s\n", i + 'A', out[end[i]]);
					flag = 1;
				}
			}
			if(end[5] == 0){

				printf("It is day.\n");
				flag = 1;
			}
			else if(end[5] == 1){

				flag = 1;
				printf("It is night.\n");
			}
			if(!flag)
			printf("No facts are deducible.\n");
		}
		printf("\n");
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值