犯罪嫌疑人--逻辑推理

福尔摩斯是个大侦探,他总是在解决疑难案件。这一次的案件也不例外,案件是这样的:有编号为1到N的N位嫌疑犯,他们其中有一个犯了罪,然后每个嫌疑犯都被询问,“哪一个人犯了罪?”犯罪嫌疑人的答案只能“编号ai的嫌疑犯犯了罪”或者“编号ai的嫌疑犯没有犯罪”。当然嫌疑犯也可以说他自己(ai = i).

福尔摩斯凭着他敏锐的侦探直觉,确定地对华生说,只有M个人说了真话,其余人都是说谎。然后就没有然后了,但华生却想知道哪些人说谎哪些人又是讲真话。这个时候同样聪明的你,被誉为红旗下的名侦探是否愿意秀一下自己的侦探天赋,帮助可怜的华生嘛?

Input

第一行一个整数T(1 <= T <= 10),表示测试数据的组数。

每组数据第一行包含N(1 <= N <=10^5)和M(0 <= M <= N)两个整数,含义见题面。接下来N行,第i行是一个整数+ai或者-ai(1<= ai <= N),如果是+ai,代表第i个人说编号ai犯了罪,如果是-ai,则表示编号ai没有犯罪。

输入数据保证至少存在一个人,使得如果是他犯了罪,则恰好有 M 个人说了真话。

Output

输出为N行,第i行是第i个嫌疑犯的输出。如果第i个嫌疑犯说了是真话,输出“Truth”;如果说谎,则输出“Lie”,如果不确定,则输出“Not defined”。

Sample Input
2
3 2
-1
-2
-3
4 1
+2
-3
+4
-1
Sample Output
Not defined
Not defined
Not defined
Lie
Not defined
Lie

Not defined

分析:逻辑推理题,具体过程如下:

先统计出来可能的罪犯数目,接下来分两种情况:

①如果数目等于一,那么如果某个人被说是罪犯,并且他是可能的罪犯,那么就是true,否则即false;

如果某个人被说不是罪犯,并且他是可能的罪犯,那么就是false,否则即true

如果数目大于一,那么如果某个人被说是罪犯,并且他是可能的罪犯,那么就是不确定,否则即false;

如果某个人被说不是罪犯,并且他是可能的罪犯,那么就是不确定,否则即true

上代码咯:

/* 逻辑推理判断题:
 *  思路分析如上
 *  具体见代码
 * */
import java.util.*;
public  class Main{
   static Scanner in = new Scanner(System.in);
   static int MAX = 100010;
   static int[] isSuspe = new int[MAX];//统计编号为i的人被指控的次数
   static int[] notSuspe = new int[MAX];//统计编号为i的人被不指控的次数
   static int[] posible = new int[MAX];//统计可能的罪犯的编号
   static int[] a = new int[MAX];//存放输入
   public static void main(String args[]){  
       int k = in.nextInt();
       while(k-->0) {
    	   //注意每次清空
    	   Arrays.fill(isSuspe, 0);
    	   Arrays.fill(notSuspe, 0);
    	   Arrays.fill(posible, 0);
    	   Arrays.fill(a, 0);
    	   int n = in.nextInt();   	   
    	   int m = in.nextInt();
    	   int notPri=0;
    	   for (int i = 1; i <= n; i++) {
			  a[i] = in.nextInt();
			  if(a[i]>0){
				  isSuspe[a[i]]++;			  
			  }
			  else{
				  notSuspe[-a[i]]++;
				  notPri++;
			  }
		   }
    	   int cnt = 0;
    	   for (int i = 1; i <= n; i++) {
     //这句话的意思是:如果i号可能是罪犯,那么此时真话的数目为:他被指控的次数+(总的不被指控的次数-减去
     //他不被指控的次数)
     //因为他被指控的次数肯定是真话,同时他不被指控的次数肯定是假话,同时不指控他而指控别人的也肯定是真话
			  if(isSuspe[i]+notPri-notSuspe[i]==m){
				   posible[i]=1;
				   cnt++;
				   }
		   }
    	  if(cnt>1){
    		  for (int i = 1; i <= n; i++) {
				 if(a[i]>0){
					  if(posible[a[i]]==1)
						 System.out.println("Not defined");
					  else
						 System.out.println("Lie");
				  }
				 else{
					 if(posible[-a[i]]==1)
						 System.out.println("Not defined");
					  else
						 System.out.println("Truth"); 
				 }
			  }
    	  }
    	  else{
    		  for (int i = 1; i <= n; i++) {
				if(a[i]>0){
					if(posible[a[i]]==1)
						System.out.println("Truth");
					else
						System.out.println("Lie");
				 }
				else{
					if(posible[-a[i]]==1)
						System.out.println("Lie");
					else
						System.out.println("Truth");
				}
			 }
    	  }
      }  
    }  
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值