题目大意:岛上住了三种生物,生物‘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;
}