⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 1600.cpp

📁 这是哈尔滨工业大学acmOJ的源代码
💻 CPP
字号:
/*  This Code is Submitted by wywcgs for Problem 1600 on 2006-03-16 at 20:03:40 */ 
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;

const int S_MAX = 3*3*3*3*3*2;
const int MAX = 50;
const char KIND[][8] = { "divine.", "human.", "evil.", "lying." };
const char WEATHER[][8] = { "day.", "night." };

int chose(int, int);
bool lie(int, int);

class Statement {
private:
	int sp, obj, kn;
	bool neg, wea;
public:
	void make();
	bool check(int) const;
};
void Statement::make() {
	char nm, ob[8], word[8];
	scanf("\n%c: %s %*s %s", &nm, ob, word); sp = nm - 'A';
	wea = !strcmp(ob, "It");
	if(!wea) obj = (ob[0] == 'I') ? sp : ob[0] - 'A';
	neg = !strcmp(word, "not");
	if(neg) scanf("%s", word);
	for(kn = 0; strcmp(word, (wea ? WEATHER : KIND)[kn]); kn++);
}
bool Statement::check(int status) const {
	bool tr = lie(status, sp), re;
	if(neg) tr = !tr;
	if(wea) re = (kn == (status&1));
	else if(kn != 3) re = (chose(status, obj) == kn);
	else re = !lie(status, obj);
	return re == tr;
}

int main()
{
	int t, i, j, n;
	Statement st[MAX];
	vector<int> truth;

	for(t = 1; scanf("%d", &n) != EOF && n != 0; t++) {
		truth.clear();
		for(i = 0; i < n; i++) st[i].make();
		for(i = 0; i < S_MAX; i++) {
			bool can = true;
			for(j = 0; j < n && can; j++)
				if(!st[j].check(i)) can = false;
			if(can) truth.push_back(i);
		}
		printf("Conversation #%d\n", t);
		if(truth.size() == 0) printf("This is impossible.\n");
		else {
			int pn = 0;
			for(i = 0; i < 6; i++) {
				bool cer = true; int tem = chose(truth[0], i);
				for(j = 1; j < (int)truth.size() && cer; j++)
					if(tem != chose(truth[j], i)) cer = false;
				if(cer) { 
					pn++;
					if(i != 5) printf("%c is %s\n", i+'A', KIND[tem]);
					else printf("It is %s\n", WEATHER[tem]);
				}
			}
			if(pn == 0) printf("No facts are deducible.\n");
		}
		putchar('\n');
	}
	
	return 0;
}

int chose(int status, int o)
{
	if(o == 5) return status&1;
	else {
		int r = 2, i;
		for(i = 0; i < o; i++) r *= 3;
		return status/r%3;
	}
}
bool lie(int status, int o)
{
	int day = status & 1, po = chose(status, o);
	return (po == 0 || (po == 1 && day == 0));
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -