FZU 2202 犯罪嫌疑人(模拟、推理)

题目链接:

http://acm.fzu.edu.cn/problem.php?pid=2202

思路:

逻辑推理题。

对于每个人i,如果他被指控,则a[i]++;

如果他被澄清,则b[i]++;

然后统计总人数中,澄清的语句的条数s。

那么对于i来说,如果i是罪犯,那么真话数x=a[i]+s-b[i]。

那么我们就可以判断出这个人是否是嫌疑犯了。依据这个我们可以知道哪些人是嫌疑犯。

如果已经确定的嫌疑犯只有一个,那么这个人就是罪犯了,这样所有人说的话是真是假就很容易知道了。

如果已经确定的嫌疑犯有多个,对每一个人i说得话h[i]进行判断:

如果h[i]是正数,那么就看h[i]是否是嫌疑犯,如果是则i说的话难以确定,否则表明i说的是假话。

如果h[i]是负数,那么就看h[i]是否是嫌疑犯,如果不是则i说的难以确定,否则表明i说的是真话。


代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
  int vis[120005],p[120005],a[120005],b[120005],x[120005];
int main()
{
    int T,i,j,k,n,m,s1,s2;
    scanf("%d",&T);
    while(T--)
    {
        memset(vis,0,sizeof(vis));
        memset(p,0,sizeof(p));
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(x,0,sizeof(x));
        s1=s2=0;
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++)
        {
             cin>>x[i];
            if(x[i]>0){a[x[i]]++;s1++;}
            else if(x[i]<0){b[-x[i]]++;s2++;}
        }
        int t=0;
        for(i=1;i<=n;i++)
        {
            int s=a[i]+s2-b[i];
            if(s==m){vis[i]=1;t++;}
        }
        if(t==1)
        {

            for(i=1;i<=n;i++)
            {
                if(x[i]>0)
                {
                    if(vis[x[i]])printf("Truth\n");
                    else printf("Lie\n");
                }
                else if(x[i]<0){
                    if(vis[-x[i]])printf("Lie\n");
                    else printf("Truth\n");
                }
            }
        }
        else
        {
            for(i=1;i<=n;i++)
        {
            int y=x[i];
            if(y>0){
                if(vis[y])p[i]=2;
                else p[i]=3;
            }
            if(y<0)
            {
                if(vis[-y])p[i]=2;
                else p[i]=1;
            }
        }
         for(i=1;i<=n;i++)
        {
            if(p[i]==1)printf("Truth\n");
            else if(p[i]==2)printf("Not defined\n");
            else if(p[i]==3)printf("Lie\n");
        }
        }

    }
    return 0;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值