UvaOJ 592 Island of Logic

来源:互联网 发布:hadoop与云计算的关系 编辑:程序博客网 时间:2024/05/16 11:39

此题也是poj 1478

解题思路:将所有语句存成结构体的形式,只需要记录说话人,被说人,说话肯否定(not),和对象。处理方法就是将所有情况K列举出来,情况K中包含了每个人的种族a[i]和昼夜w的枚举,然后用所有语句S进行判断。如果存在一个k属于K,且满足所有S,则称k被满足。如果出现两个不同的k被满足,就将两组中相同的保留(这些是可以确定的)。

具体在程序中,我全部用一组宏来进行判断。

Impossible的含义是:不存在一个k,使得满足所有的S(即不存在一个状态满足所有这些对话,所以这些对话不可能存在)

No deducible的含义是:存在多个k满足所有的S,但对这些k取“与”,不存在一个i使得a[i]在所有k中状态相同,否则i可以被推出是a[i](即可能存在多个状态满足这些对话,但这些状态相互冲突,无法推导出其中一个人唯一的结论)

更多的样例数据参见 http://www.cnblogs.com/jiangu66/p/3239199.html

#include <stdio.h>#include <string.h>// a数组用于保存A-E的状态 divine:2human:1evil:0 若为-1表示没有用到该人物// w用于保存昼夜的状态昼1夜0// r数组和rw保存结果// dedu保存是否有过满足所有条件的一次推导,每次初始为0int a[5], w, r[5], rw, dedu;// x是说话人// y是被评论者// p是为此谓词:是1否0// h是种族0-2当h==3时,y是昼夜当h==4时,p是“是否撒谎”struct Statement {char x, y, p, h;}sta[51];int n;#define sta1(y, p, h) ((a[y] == h) == p)#define sta2(u) (u == w)#define sta3(y, l) ((a[y] + w >= 2) ^ l)#define sta0(y, p, h) (h < 3 ? sta1(y, p, h) : (h == 3 ? sta2(y) : sta3(y, p)))#define stai(x, y, p, h) ((a[x] + w >= 2) == sta0(y, p, h))#define staok(i) stai(sta[i].x, sta[i].y, sta[i].p, sta[i].h)void search(const int layer) {if (layer == 5)for (w = 0 ; w <= 1 ; w++) {int i;for (i = 0 ; i < n ; i++)if (!staok(i))break;if (i == n) {if (dedu == 0) {memcpy(r, a, sizeof(a));rw = w;dedu = 1;}else {for (i = 0 ; i < 5 ; i++)if (a[i] != r[i])r[i] = -1;if (rw != w)rw = -1;}}}else if (a[layer] == -1)search(layer + 1);elsefor (a[layer] = 0 ; a[layer] <= 2 ; a[layer]++)search(layer + 1);}int main() {int i, c;char cmd[10];for (c=1 ; scanf("%d", &n) != EOF && n ; c++) {memset(a, 0xff, sizeof(a));memset(sta, 0, sizeof(sta));dedu = 0;printf("Conversation #%d\n", c);for (i=0 ; i<n ; i++) {scanf("%s", cmd);sta[i].x = cmd[0] - 'A';scanf("%s", cmd);sta[i].y = (cmd[0] == 'I') ? sta[i].x : (cmd[0] - 'A');a[sta[i].x] = a[sta[i].y] = 0;scanf("%s", cmd);scanf("%s", cmd);if (cmd[0] == 'n' && cmd[1] == 'o') {sta[i].p = 0;scanf("%s", cmd);}elsesta[i].p = 1;switch(cmd[0]) {case 'd':if (cmd[1] == 'a')sta[i].y = 1, sta[i].h = 3;elsesta[i].h = 2;break;case 'n':sta[i].y = 0, sta[i].h = 3;break;case 'l':sta[i].h = 4;break;case 'h':sta[i].h = 1;break;case 'e':sta[i].h = 0;break;default:printf("error cmd %s\n", cmd);}}search(0);if (dedu == 0)printf("This is impossible.\n");else {const char* inhabitStr[3] = {"evil", "human", "divine"};for (i=0 ; i<5 ; i++)if (r[i] != -1)printf("%c is %s.\n", 'A'+i, inhabitStr[r[i]]);if (rw != -1)printf("It is %s.\n", rw ? "day" : "night");else {for (i=0 ; i<5 ; i++)if (r[i] != -1)break;if (i == 5)printf("No facts are deducible.\n");}}printf("\n");}}


0 0
原创粉丝点击