UVA 592 逻辑之岛

I/O 操作太麻烦,转一篇

#include <stdio.h>

#define DIVINE 0

#define EVIL   1

#define HUMAN  2

#define DAY   0

#define NIGHT 1

#define MAXPERSONS 5

#define STATENUM 3*3*3*3*3*2

char state[STATENUM];


//Auxiliary functions 
int type(int state, int p)

{

    state /= 2;

    while(p--) state /= 3;

    return (state % 3);

}

int lying(int state, int p)

{

    int daynight,t;

   

    daynight = state % 2;

    t = type(state,p);

    return (t == EVIL || (t == HUMAN && daynight == NIGHT));

}

void init()

{

    int i;

   

    for(i=0;i<STATENUM;i++) state[i] = 1;

}

void scanline()

{

    int i,neg,speaker,target,t,truee;

    char s[50];

   

    gets(s);

    speaker = s[0] - 'A';

   

    // Case 1: It is day or night.

    if(s[3] == 'I' && s[4] == 't')

    {

        for(i=0;i<STATENUM;i++)

        {

            truee = ((i%2 == DAY && s[9] == 'd') ||

                (i%2 == NIGHT && s[9] == 'n'));

            if(lying(i,speaker) == truee) state[i] = 0;

        }

        return;

    }

   

    if(s[5] == 'a')

        target = speaker;    // speaking about oneself

    else

        target = s[3] - 'A'; // speaking about someone else

   

    neg = (s[8] == 'n'); // statement negated?

   

    switch(s[8+4*neg])

    {

        case 'd': t = DIVINE; break;

        case 'e': t = EVIL; break;

        case 'h': t = HUMAN; break;

        case 'l':

        for(i=0;i<STATENUM;i++)

        {

            truee = neg ^ lying(i,target);

            if(lying(i,speaker) == truee) state[i] = 0;

        }

        return;

    }

    for(i=0;i<STATENUM;i++)

    {

        truee = neg ^ (type(i,target) == t);

        if(lying(i,speaker) == truee) state[i] = 0;

    }

    return;

}

void output()

{

    int deduction,i,j,possible[MAXPERSONS],daynight;

    static int caseno = 1;

    char *names[] = { "divine", "evil", "human" };

   

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

   

    for(i=0;i<MAXPERSONS;i++)

        possible[i] = -1;

    daynight = -1;

   

    for(i=0;i<STATENUM;i++)

        if(state[i])

        {

            if(daynight != -1 && daynight != i%2)

                daynight = -2;

            else if(daynight == -1)

                daynight = i%2;

            for(j=0;j<MAXPERSONS;j++)

            {

                if(possible[j] != -1 && possible[j] != type(i,j))

                    possible[j] = -2;

                else if(possible[j] == -1)

                    possible[j] = type(i,j);

            }

        }

    if(daynight == -1)

    {

        printf("This is impossible.\n\n");

        return;

    }

       

    deduction = 0;

    for(i=0;i<MAXPERSONS;i++)

        if(possible[i] >= 0)

        {

            printf("%c is %s.\n",i+'A',names[possible[i]]);

            deduction = 1;

        }

    if(daynight >= 0)

    {

        printf("It is %s.\n",daynight==DAY?"day":"night");

        deduction = 1;

    }

    if(!deduction)

        printf("No facts are deducible.\n");

    printf("\n");

}

int main()

{

    int i,n;

    while(scanf("%d ",&n) && n != 0)

    {

        init();

        for(i=0;i<n;i++) scanline();

        output();

    }

    return 0;

}


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值