首页 > 其他 > 详细

[NOIP2003] 提高组 洛谷P1039 侦探推理

时间:2016-10-20 23:57:10      阅读:515      评论:0      收藏:0      [点我收藏+]

 

题目描述

明明同学最近迷上了侦探漫画《柯南》并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏。游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯(在明明不知情的情况下),明明的任务就是找出这个罪犯。接着,明明逐个询问每一个同学,被询问者可能会说:

技术分享

证词中出现的其他话,都不列入逻辑推理的内容。

明明所知道的是,他的同学中有N个人始终说假话,其余的人始终说真。

现在,明明需要你帮助他从他同学的话中推断出谁是真正的凶手,请记住,凶手只有一个!

输入输出格式

输入格式:

 

输入由若干行组成,第一行有二个整数,M(1≤M≤20)、N(1≤N≤M)和P(1≤P≤100);M是参加游戏的明明的同学数,N是其中始终说谎的人数,P是证言的总数。接下来M行,

每行是明明的一个同学的名字(英文字母组成,没有主格,全部大写)。

往后有P行,每行开始是某个同学的名宇,紧跟着一个冒号和一个空格,后面是一句证词,符合前表中所列格式。证词每行不会超过250个字符。

输入中不会出现连续的两个空格,而且每行开头和结尾也没有空格。

 

输出格式:

 

如果你的程序能确定谁是罪犯,则输出他的名字;如果程序判断出不止一个人可能是罪犯,则输出 Cannot Determine;如果程序判断出没有人可能成为罪犯,则输出 Impossible。

 

输入输出样例

输入样例#1:
3 1 5
MIKE
CHARLES
KATE
MIKE: I am guilty.
MIKE: Today is Sunday.
CHARLES: MIKE is guilty.
KATE: I am guilty.
KATE: How are you??
输出样例#1:
MIKE

 

惊天大模拟

惊天码农题

 

首先需要花式截取出每个人的信息,然后需要记录以下信息:

  每个人说的日期

  每个人说自己是不是罪犯

  每个人说谁是罪犯

  每个人说谁不是罪犯

 

枚举日期和嫌疑犯,进行判断:

  记说谎人数为tmp,可疑人数为cnt(可疑人数指没有说过真话,也没有说过假话的人数),题目限制说谎人数为m

  若tmp>m,说明当前枚举的情况不成立。

  若tmp+cnt<m,说明已知说谎的人和可能说谎的人加起来都不够目标值,不成立。

  除此之外的情况下,当前枚举到的嫌疑犯可能是罪犯。

若可能是罪犯的人数大于1人,cannot determine

 

 

  1 /*By SilverN*/
  2 #include<iostream>
  3 #include<cstdio>
  4 #include<algorithm>
  5 #include<cstring>
  6 #include<cmath>
  7 #include<vector>
  8 #include<map>
  9 using namespace std;
 10 string pp[5]={"am guilty","am not guilty","is guilty.","is not guilty."};
 11 string week[8]={" ","is Monday","is Tuesday","is Wednesday","is Thursday","is Friday","is Saturday","is Sunday"};
 12 //
 13 int n,m,p;
 14 //
 15 string name[30];
 16 map<string,int>mp;
 17 //人名
 18 string s[30];
 19 struct person{
 20     bool is;//是否确定是罪犯 
 21     int wk;//每个人对天气的判断
 22     int guil[30];//每个人对其他人身份的判断
 23     vector<int>g_list,nog_list;//每个人指认的罪犯 
 24 }a[30];
 25 //身份信息 
 26 bool posi[30];
 27 int work(int day,int uso){
 28     int cnt=0,tmp=0;//不确定的人,确定的凶手 
 29     
 30     for(int i=1;i<=n;i++){
 31         bool f_true=0,f_false=0;
 32         if(a[i].is || (a[i].wk && a[i].wk!=day)){//天气说错 
 33             f_false=1;
 34         }
 35         if(a[i].guil[uso]==-1){//说罪犯不是罪犯 
 36             f_false=1;
 37         }
 38         if(a[i].guil[uso]==1)f_true=1;//说罪犯是罪犯 
 39         if(i!=uso && a[i].guil[i]==1){//不是罪犯说自己是罪犯 
 40             f_false=1;
 41         }
 42         for(int j=0;j<a[i].g_list.size();j++)if(a[i].g_list[j]!=uso){//说不是罪犯的人是罪犯 
 43             f_false=1;
 44         }
 45         for(int j=0;j<a[i].nog_list.size();j++)if(a[i].nog_list[j]!=uso){//说不是罪犯的人不是罪犯 
 46             f_true=1;
 47         }
 48         if(a[i].wk==day)f_true=1;
 49         if(i==uso && a[i].guil[uso]==1) f_true=1;//凶手说自己是凶手 
 50         if(i!=uso && a[i].guil[i]==-1) f_true=1;//不是凶手说自己不是凶手 
 51         if(f_true && f_false)return 0;//不合法 
 52         if(f_false)tmp++; 
 53         if(!f_true && !f_false)cnt++;//不确定的人 
 54     }
 55 //    printf("day:%d  uso:%d cnt:%d tmp:%d\n",day,uso,cnt,tmp);
 56     
 57     if(tmp>m)return 0;
 58     if(tmp+cnt<m)return 0;
 59     return 1;
 60 }
 61 int target=0;
 62 void solve(){
 63     int tmp=0;
 64     int i,j;
 65     for(i=1;i<=7;i++)//枚举日期 
 66       for(j=1;j<=n;j++)//枚举凶手 
 67       { 
 68           if(posi[j])continue; 
 69         if(work(i,j)){
 70             ++tmp;
 71             posi[j]=1;
 72             if(tmp>=2){
 73                 printf("Cannot Determine\n");
 74                 return;
 75             }
 76             target=j;
 77         }
 78     } 
 79     if(!target)printf("Impossible\n");
 80     cout<<name[target]<<endl;
 81     return;
 82 }
 83 // 
 84 int main(){
 85     scanf("%d%d%d",&n,&m,&p);//总人数 说谎人数 证言数 
 86     int i,j;
 87     for(i=1;i<=n;i++){
 88         cin>>name[i];
 89         mp[name[i]]=i;
 90     }
 91     for(i=1;i<=p;++i){
 92         cin>>s[i];
 93 //        cout<<"test"<<s[i]<<endl;
 94         s[i]=s[i].substr(0,s[i].find(:));
 95 //        cout<<"finn"<<endl;
 96         int id=mp[s[i]];
 97         getchar();
 98         getline(cin,s[i]);
 99 //        cout<<"now-"<<s[i]<<endl;
100         //判断 
101         if(s[i][0]==I){
102             if(s[i].find(pp[0])!=-1){//I am guilty
103                 a[id].guil[id]=1;    continue;
104             }
105             else if(s[i].find(pp[1])!=-1){//I am not guilty
106                 a[id].guil[id]=-1;    continue;
107             }
108         }
109         else{
110             int tmp=0;
111             tmp=s[i].find(pp[2]);
112             if(tmp!=-1){//is guilty
113 //                printf("is guilty: %d\n",tmp);
114                 s[i]=s[i].substr(0,tmp-1);
115 //                printf("mp:%d\n",mp[s[i]]);
116 //                cout<<"test: "<<s[i]<<"eld"<<endl;
117                 a[id].guil[mp[s[i]]]=1;
118                 a[id].g_list.push_back(mp[s[i]]);
119                 continue;
120             }
121             tmp=s[i].find(pp[3]);
122             if(tmp!=-1){//is not guilty
123                 s[i]=s[i].substr(0,tmp-1);
124 //                printf("mp:%d\n",mp[s[i]]);
125 //                cout<<"test: "<<s[i]<<"eld"<<endl;
126                 a[id].guil[mp[s[i]]]=-1;
127                 a[id].nog_list.push_back(mp[s[i]]);
128                 continue;
129             }
130             for(j=1;j<=7;j++)//天气判定 
131             {
132                 tmp=s[i].find(week[j]);
133                 if(tmp!=-1){
134                     if(!a[id].wk)
135                         a[id].wk=j;
136                     else a[id].is=1;//天气前后矛盾,肯定是骗子 
137                     break;
138                 }
139             }
140         }
141         //
142     }
143     //结束读入
144     /*
145     for(i=1;i<=n;i++){
146         printf("info of %d:\n",i);
147         cout<<name[i]<<endl;
148 
149         printf("wk: %d\n",a[i].wk);
150         printf("self: %d\n",a[i].guil[i]);
151         for(j=0;j<a[i].g_list.size();j++)printf("%d ",a[i].g_list[j]);
152         printf("\n");
153         for(j=0;j<a[i].nog_list.size();j++)printf("%d ",a[i].nog_list[j]);
154         printf("\n");
155     }*/
156     //
157     solve(); 
158     
159     return 0;
160 }

 

[NOIP2003] 提高组 洛谷P1039 侦探推理

原文:http://www.cnblogs.com/SilverNebula/p/5982765.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!