noip2003提高组之侦探推理

点击下载noip2003提高组题目_代码_测试数据.rar

点击察看关于组合算法的另一篇文章

 

 此题相当锻炼编程的基本功夫,参加Noip的新手不要错过!

 

  1 ExpandedBlockStart.gif ContractedBlock.gif /**/ /*
  2=========程序信息========
  3对应题目:noip2003提高组_侦探推理
  4使用语言:c++
  5使用编译器:dev c++
  6使用算法:穷举模拟
  7算法运行时间:O(p*C(m,n)) + O(m*C(m,n)) [其中C(m,n)是从m个数中取n个数的组合数]
  8作者:贵州大学05级 刘永辉 
  9昵称:SDJL
 10编写时间:2008年8月
 11联系QQ:44561907
 12E-Mail:44561907@qq.com
 13获得更多文章请访问我的博客:www.cnblogs.com/sdjl
 14如果发现BUG或有写得不好的地方请发邮件告诉我:)
 15=========题目解析========
 16在做此题之前,我们需要搞清楚几点,这是我从测试数据中看出而从题目上不容易看出来的:
 17题目补充点一:如果有4个人a、b、c、d,当a、b说谎话时我们推出了c是罪犯,然后当a、c说谎话时我们又推出了c是罪犯,此时我们仅推出一个罪犯,而不是两个,因此输出为c,而不是输出Cannot Determine,注意不要重复计数。
 18题目补充点二:如果有4个人a、b、c、d,当我们推出a、b、c三人都不是罪犯而d未知时,那么d就是罪犯,这是从某些测试数据中发现的规则,题目没有明说。
 19题目补充点三:不会出现重名情况。
 20题目补充点四:注意“I am guilty.”、“Today is Monday.”等语句的后面均有一个“.”号。
 21
 22在确定上面几点后我们来思考此题如何做,首先我想到的是用模拟方法,并且此程序使用的就是模拟方法,也就是说,我们用组合的方式从m个人中取出n个人假设这n个人说谎话,然后分别对这m个人所说的共p句话进行判断,如果p句话均两两不矛盾的话,那么就看看能不能正好找出一个罪犯,或者正好找出m-1个“好人”的话(“好人”指不是罪犯的人,下同),另一个便认为是罪犯。
 23同时注意分析,本质上有效的证言仅有4种类型,第一种是“谁是罪犯”,第二种是“谁不是罪犯”,第三种是“今天是星期几”,第四种是“今天不是星期几”,并且如果某个说谎者的证言类型为“谁是罪犯”,那么他的反证言“谁不是罪犯”一定成立。
 24无论在这n个人说谎的情况下能不能找出罪犯,都要从m个人中重新找出一组n个人的组合,再次进行判断(即寻找罪犯)。
 25直到所有说谎人的组合情况都考虑后再来看哪些人有可能是罪犯,如果超过两个,则输出Cannot Determine,如果正好有一个,则输出此人的名字,如果一个都没有,则输出Impossible。
 26*/

 27
 28 #include  < cstdlib >
 29 #include  < iostream >
 30 #include  < fstream >
 31
 32 using   namespace  std;
 33 const   int  maxn = 20 ; // 最多参与人数
 34 const   int  maxTestimony = 100 ; // 最多证词数
 35
 36 // 证词枚举类型,分别对应“I am guilty.”、“I am not guilty”、“Today is XXX”、“Today not is XXX”及其它废话。
 37 enum  TestimonyWordsType
 38 ExpandedBlockStart.gifContractedBlock.gif {
 39    IsGuilty,NotIsGuilty,TodayIs,TodayNotIs,NullWords
 40}
;
 41 // 星期枚举类型,分别从“星期一”对应到“星期日”,最后一个是“未知”,注意,枚举事实上是一个从0开始计数的整数,Monday事实上等于0,Tuesday等于1,Unknown等于7,因此后面代码出现诸如“isToday[Monday]=1”的代码时请不要惊讶,这表示今天是星期一
 42 enum  WeekType
 43 ExpandedBlockStart.gifContractedBlock.gif {
 44    Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday,Unknown
 45}
;
 46 // 证言结构体
 47 struct  TestimonyStruct
 48 ExpandedBlockStart.gifContractedBlock.gif {
 49    TestimonyWordsType Words;//证言的类型,IsGuilty、NotIsGuilty、TodayIs、TodayNotIs、NullWords五个之一
 50    TestimonyWordsType Reverse;//证言的反类型,IsGuilty、NotIsGuilty互反,TodayIs、TodayNotIs互反,NullWords的反类型还是NullWords
 51    
 52    int PeopleNum;//说话内容里面所涉及到的人的编号,比如说“SDJL is guilty.”那么就是SDJL此人的编号,此字段仅在Words属于IsGuilty、NotIsGuilty之一时有用
 53    WeekType Week;//说话内容里面所涉及到的星期,比如说“Today is Monday.”那么Week就等于Monday,此字段仅在Words属于TodayIs、TodayNotIs之一时有用
 54
 55    int SpeakerNum;//说话者编号
 56}
;
 57 // 人结构体
 58 struct  PeopleStruct
 59 ExpandedBlockStart.gifContractedBlock.gif {
 60    string Name;//人名
 61    int Num;//编号
 62}
;
 63
 64 PeopleStruct people[maxn]; //
 65 int  n; // 说谎者人数
 66 int  m; // 总人数
 67 int  p; // 证言数,注意一个人可能有多句证言,或没有证言
 68 int  StoryPeople[maxn]; // StoryPeople[3]=5表示第3个说谎者是people[5](从第0个开始计数),此全局变量仅用于保存组合算法的状态,其它地方不会用到
 69 bool  isStoryPeople[maxn]; // isStoryPople[5]=true表示第5个人说的是谎话,此全局变量在组合算法中得到它的值,而在验证机中用来判断某人是否说谎话
 70 TestimonyStruct testimony[maxTestimony]; // 证言
 71 int  guilty[maxn]; // guilty[3]=2表示两次推出第3个人是罪犯,等于0表示不能推出此人是罪犯,这里我们不能简单的用一个整数来记录找出的罪犯数以及用一个字符串来记录罪犯的名字,这是因为要避免前面所提到的“题目补充点一”情况。
 72
 73 // 这两个全局变量用于验证机 
 74 int  peopleIsGuilty[maxn]; // peopleIsGuilty[7]=1表示第7个人是罪犯,=-1表示不是罪犯,=0表示未知 
 75 int  isToday[ 7 ]; // isToday[3]=1 表示今天是星期四, isToday[6]=-1 表示今天不是星期日,别忘了是从0开始计数,等于0时表示未知,isToday数组中最多只能有一个为1
 76
 77 // 根据人名得到此人的编号
 78 int  GetPeopleNum( string  name) // 运行时间:O(m) 
 79 ExpandedBlockStart.gifContractedBlock.gif {
 80    for(int i=0; i<m; i++)    
 81ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 82        if(people[i].Name == name)
 83            return i;    
 84    }

 85    //这里应该抛出异常,表示给出的人名错误     
 86}

 87
 88 // 根据星期名称字符串得到星期枚举类型
 89 WeekType GetWeekType( string  weekString) // 运行时间:O(1)
 90 ExpandedBlockStart.gifContractedBlock.gif {
 91    //字符串居然不能用于switch语句?这是我没有预料到的
 92    WeekType returnWeekType;
 93    if(weekString == "Monday.")
 94ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 95        returnWeekType = Monday;
 96    }

 97    else if(weekString == "Tuesday.")        
 98ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 99        returnWeekType = Tuesday;
100    }

101    else if(weekString == "Wednesday.")
102ExpandedSubBlockStart.gifContractedSubBlock.gif    {
103        returnWeekType = Wednesday;    
104    }

105    else if(weekString == "Thursday.")
106ExpandedSubBlockStart.gifContractedSubBlock.gif    {
107        returnWeekType = Thursday;    
108    }

109    else if(weekString == "Friday.")
110ExpandedSubBlockStart.gifContractedSubBlock.gif    {
111        returnWeekType = Friday;    
112    }

113    else if(weekString == "Saturday.")
114ExpandedSubBlockStart.gifContractedSubBlock.gif    {
115        returnWeekType = Saturday;    
116    }

117    else if(weekString == "Sunday.")
118ExpandedSubBlockStart.gifContractedSubBlock.gif    {
119        returnWeekType = Sunday;    
120    }

121    else 
122ExpandedSubBlockStart.gifContractedSubBlock.gif    {
123        returnWeekType = Unknown;
124    }

125    
126    return returnWeekType;
127}

128
129 // 设置证言,speakerNum是说话者编号,testimonyWords是证词,testimony是对应的证言结构体(全局)
130 // 在函数执行前testimony是未知的(即各个字段没有初始化),而在函数执行后testimony是已知的
131 void  SetTestimony( int  speakerNum,  string  testimonyWords, TestimonyStruct  & testimony) // 运行时间:O(m) [因为调用GetPeopleNum]
132 ExpandedBlockStart.gifContractedBlock.gif {
133    //证词的前四个单词,注意证词不包括说话者姓名和姓名后面的“:”符号
134    string word1,word2,word3,word4;
135    word1 = strtok(&(testimonyWords[0])," ");
136    word2 = strtok(NULL," ");
137    word3 = strtok(NULL," ");
138    //如果第3个单词是not的话才读取第4个单词,这是为了避免一行仅有3个单词时读取第4个单词引起的错误
139    if(word3 == "not")
140        word4 = strtok(NULL," ");
141    else
142        word4 = "";
143    
144    //设置说话者    
145    testimony.SpeakerNum = speakerNum;
146            
147    //如果证言是:“I am guilty.” 
148    if((word1 == "I"&& (word2 == "am"&& (word3 == "guilty."))
149ExpandedSubBlockStart.gifContractedSubBlock.gif    {
150        testimony.Words = IsGuilty;//设置证词类型,下同
151        testimony.Reverse = NotIsGuilty;//设置证词反类型,下同
152        testimony.PeopleNum = speakerNum;//设置证词中出现的人物编号,下同
153        testimony.Week = Unknown;//设置证词中出现的星期,下同
154    }

155    //否则如果证言是:“I am not guilty.” 
156    else if((word1 == "I"&& (word2 == "am"&& (word3 == "not"&& (word4 == "guilty."))
157ExpandedSubBlockStart.gifContractedSubBlock.gif    {
158        testimony.Words = NotIsGuilty;
159        testimony.Reverse = IsGuilty;
160        testimony.PeopleNum = speakerNum;
161        testimony.Week = Unknown;    
162    }

163    //否则如果证言是:“XXX 是罪犯”
164    else if((word2 == "is"&& (word3 == "guilty.")) 
165ExpandedSubBlockStart.gifContractedSubBlock.gif    {
166        int guiltyNum = GetPeopleNum(word1);//获得证词中出现的人物编号,下同
167        testimony.Words = IsGuilty;
168        testimony.Reverse = NotIsGuilty;
169        testimony.PeopleNum = guiltyNum;
170        testimony.Week = Unknown;    
171    }

172    //否则如果证言是:“XXX 不是罪犯”
173    else if((word2 == "is"&& (word3 == "not"&& (word4 == "guilty."))
174ExpandedSubBlockStart.gifContractedSubBlock.gif    {
175        int guiltyNum = GetPeopleNum(word1);
176        testimony.Words = NotIsGuilty;
177        testimony.Reverse = IsGuilty;
178        testimony.PeopleNum = guiltyNum;
179        testimony.Week = Unknown;    
180    }

181    //否则如果证言是:“今天是星期X”
182    else if((word1 == "Today"&& (word2 == "is")) 
183ExpandedSubBlockStart.gifContractedSubBlock.gif    {
184        WeekType week = GetWeekType(word3);//获得证词中出现的星期,有可能返回的是Unknown
185        if(week != Unknown)//增加这句话是为了防止诸如“Today is Good Day.”的废话 
186ExpandedSubBlockStart.gifContractedSubBlock.gif        {
187            testimony.Words = TodayIs;
188            testimony.Reverse = TodayNotIs;
189            testimony.PeopleNum = -1;//因为此时我们不应该使用到此值,所以设置为-1,这样如果不小心使用到这个字段的话会因为引用数组下标出界而抛出异常进而提示我们程序有错误
190            testimony.Week =  week;
191        }

192        else
193            testimony.Words = NullWords;
194    }

195    else//否则证言没有意义
196        testimony.Words = NullWords;
197}
 
198
199 // 初始化全局变量,从文件中读取数据
200 void  init() // 运行时间:O(pm)
201 ExpandedBlockStart.gifContractedBlock.gif {
202    ifstream inputFile("logic.in");
203    //读取第一行的m,n,p 
204    inputFile>>m>>n>>p;
205    //读取名字,并初始化people 
206    for(int i=0; i<m; i++)//每次运行时间:O(m)
207ExpandedSubBlockStart.gifContractedSubBlock.gif    {
208        string name;
209        inputFile>>name;
210        people[i].Name = name;        
211        people[i].Num = i;        
212    }

213    //申明一个没用的字符串然后使用函数getline(inputFile,temp,'\n'),这是为了让文件读取指针指向下一行的开头
214    string temp;
215    getline(inputFile,temp,'\n');
216    
217    //读取p句证词 
218    for(int i=0; i<p; i++)//每次运行时间:O(pm)
219ExpandedSubBlockStart.gifContractedSubBlock.gif    {
220        //从文件中读取说话者姓名
221        string speakerName;
222        getline(inputFile,speakerName,':');
223        //由姓名得到说话者编号
224        int speakerNum = GetPeopleNum(speakerName);//每次运行时间:O(m)
225        
226        //从文件中读取证词
227        string testimonyWords;
228        getline(inputFile,testimonyWords,'\n');
229        //给第i句证词赋值,注意函数执行前testimony[i]的各个字段是未知的
230        SetTestimony(speakerNum,testimonyWords,testimony[i]);//每次运行时间:O(m)
231    }
 
232    inputFile.close();
233    
234    //我们假设编号从0到n-1的这n个人说谎
235    for(int i=0; i<n; i++)//每次运行时间:O(n)
236        StoryPeople[i] = i;
237    for(int i=0; i<m; i++)//每次运行时间:O(m)
238ExpandedSubBlockStart.gifContractedSubBlock.gif    {
239        isStoryPeople[i] = false;    
240    }

241    
242    for(int i=0; i<n; i++)//每次运行时间:O(n)
243ExpandedSubBlockStart.gifContractedSubBlock.gif    {
244           isStoryPeople[StoryPeople[i]] = true;
245    }

246
247    //初始化全局变量guilty
248    for(int i=0; i<n; i++)//每次运行时间:O(n)
249        guilty[i] = 0;
250}

251
252 // 初始化证言验证机器,初始化后验证机认为所有的人都是未知的,并且也不知道今天是星期几
253 void  ResetCheckupMachine() // 运行时间:O(m)
254 ExpandedBlockStart.gifContractedBlock.gif {
255    for(int i=0; i<m; i++)
256        peopleIsGuilty[i] = 0;//别忘了等于0表示未知,等于1表示是罪犯,等于-1表示不是罪犯
257    for(int i=0; i<7; i++)
258        isToday[i] = 0;//类似peopleIsGuilty
259}

260
261 // 验证一句证言,使用前要调用“初始化证言验证机”函数
262 bool  Checkup(TestimonyStruct  & testimony) // 运行时间:O(1)
263 ExpandedBlockStart.gifContractedBlock.gif {
264    //申明用于检验的证词类型
265    TestimonyWordsType testimonyWordsType;
266    //获得说话者编号
267    int speakerNum = testimony.SpeakerNum;
268    //如果他说假话
269    if(isStoryPeople[speakerNum])
270        testimonyWordsType = testimony.Reverse;//用于检验的证词为反证词
271    else//否则说真话 
272        testimonyWordsType = testimony.Words;
273
274    bool consistent;//consistent=false表示证言不一致(矛盾) 
275    //获得证词中所涉及的星期
276    int weekNum = testimony.Week;
277    //分别考虑证词的每种情况,注意证言验证机把testimonyWordsType看为正确的,哪怕它是由说谎者说出来的
278    switch(testimonyWordsType)
279ExpandedSubBlockStart.gifContractedSubBlock.gif    {
280        //如果证词是“I am guilty.”类型
281        case IsGuilty:
282            //假如证言验证机已经确定此人不是罪犯
283            if(peopleIsGuilty[testimony.PeopleNum] == -1)
284                consistent = false;//证言矛盾
285            else
286ExpandedSubBlockStart.gifContractedSubBlock.gif            {
287                //否则证言不矛盾
288                consistent = true;
289                //记下曾经有人说过这个人是罪犯
290                peopleIsGuilty[testimony.PeopleNum] = 1;
291            }

292            break;
293        //如果证词是“I am not guilty.”类型
294        case NotIsGuilty:
295            //假如证言验证机已经确定此人就是罪犯
296            if(peopleIsGuilty[testimony.PeopleNum] == 1)
297                consistent = false;//证言矛盾
298            else
299ExpandedSubBlockStart.gifContractedSubBlock.gif            {
300                //否则证言不矛盾
301                consistent = true;
302                //记下曾经有人说过这个人不是罪犯
303                peopleIsGuilty[testimony.PeopleNum] = -1;    
304            }
            
305            break;
306        //如果证言是“Today is XXX”类型,不失一般性,下面我们假设XXX代表星期三
307        case TodayIs:
308            //如果证言验证机已经确定今天不是星期三
309            if(isToday[weekNum] == -1)
310                consistent = false;//证言矛盾
311            else
312ExpandedSubBlockStart.gifContractedSubBlock.gif            {
313                //记下今天是星期三
314                isToday[weekNum] = 1;
315                //count用于记算一共确定了几次星期,比如说上一次确定是星期二,而这一次又确定是星期三,那么count就会在isToday[Tuesday]==1时增加1,和在isToday[Wednesday]==1时增加1
316                int count=0;
317                for(int i=0; i<7; i++)
318                    if(isToday[i] == 1)
319                        count++;
320                //如果仅确定了一次
321                if(count ==1)
322                    consistent = true;//证言不矛盾
323                else//否则确定过多次
324                    consistent = false;//证言矛盾
325ExpandedSubBlockStart.gifContractedSubBlock.gif                /**//*
326                Q:为什么不用一个全局变量来记录今天是星期几呢?
327                A:因为当遇到证言为“Today is not XXX”时证言验证机需要记下今天不是星期几(及设置isToday[XXX]=-1),而这是用一个全局变量做不到的
328                */

329            }
        
330            break;
331        //如果证言是:“Today is not XXX”类型,同样,下面我们假设XXX代表星期三
332        case TodayNotIs:
333            //如果证言验证机已经确定今天就是星期三
334            if(isToday[weekNum] == 1)
335                consistent = false;//证言矛盾
336            else
337ExpandedSubBlockStart.gifContractedSubBlock.gif            {
338                //记下今天不是星期三
339                isToday[weekNum] = -1;
340                //证言不矛盾
341                consistent = true;
342            }
            
343            break;
344        default:
345            //对于其它废话我们认为它与所有证言都不矛盾
346            consistent = true;
347            break;        
348    }

349    //返回此句证言是否矛盾
350    return consistent;
351}

352
353 // 计算下一组说谎话的人,当所有组合均依次出现后函数返回false,关于组合算法请参考我的另一篇文章 
354 bool  NextGroupStoryPeople() // 运行时间:O(m) [注意m>n]
355 ExpandedBlockStart.gifContractedBlock.gif {
356    bool hasNext;
357    
358    int k = n - 1;
359    while ((k >= 0&& (StoryPeople[k] + (n - k) == m))
360ExpandedSubBlockStart.gifContractedSubBlock.gif    {
361        k--;
362    }

363    if (k>=0)
364ExpandedSubBlockStart.gifContractedSubBlock.gif    {
365       if (k==n-1)
366ExpandedSubBlockStart.gifContractedSubBlock.gif       {
367           StoryPeople[k]++;
368       }

369       else
370ExpandedSubBlockStart.gifContractedSubBlock.gif       {
371            StoryPeople[k]++;
372            k++;
373            while (k<n)
374ExpandedSubBlockStart.gifContractedSubBlock.gif            {
375                StoryPeople[k] = StoryPeople[k - 1+ 1;
376                k++;
377            }

378       }

379       hasNext = true;
380       //计算说谎的人,别忘了StoryPeople用来保存组合的状态,便于生成下一个组合,并不用于其它函数,而isStoryPeople在验证证言时会用到
381       for(int i=0; i<m; i++)//每次运行时间:O(m)
382ExpandedSubBlockStart.gifContractedSubBlock.gif       {
383            isStoryPeople[i] = false;    
384       }

385       for(int i=0; i<n; i++)
386ExpandedSubBlockStart.gifContractedSubBlock.gif       {
387            isStoryPeople[StoryPeople[i]] = true;
388       }

389    }

390    else
391ExpandedSubBlockStart.gifContractedSubBlock.gif    {
392        hasNext = false;
393    }

394    return hasNext;    
395}

396
397 // 运行整个模拟查找过程
398 void  run() // 运行时间:O(p*C(m,n))+O(m*C(m,n)) [是否等于O((m+p)*C(m,n))???]
399 ExpandedBlockStart.gifContractedBlock.gif {
400    
401    do//运行时间:C(m,n)*(O(p)+O(m))
402ExpandedSubBlockStart.gifContractedSubBlock.gif    {        
403        //重置证言验证机,以便开始验证接下来的证言
404        ResetCheckupMachine();     //每次运行时间:O(m)
405        
406        
407        bool consistent = true;//consistent=false表示证言出现矛盾 
408        //依次验证p句证言
409        for(int i=0; i<p; i++)//每次运行时间:O(p)
410ExpandedSubBlockStart.gifContractedSubBlock.gif        {
411            consistent = Checkup(testimony[i]);//每次运行时间:O(1)
412            //如果证言出现矛盾
413            if(!consistent)
414                break;//跳出验证循环
415        }
 
416        //如果证言不矛盾 
417        if(consistent)
418ExpandedSubBlockStart.gifContractedSubBlock.gif        {
419            //统计罪犯数
420            int guiltyCount=0;
421            for(int i=0; i<m; i++)//每次运行时间:O(m)
422ExpandedSubBlockStart.gifContractedSubBlock.gif            {
423                //如果第i个人是罪犯,注意peopleIsGuilty在每次重置证言验证机时被初始化
424                if(peopleIsGuilty[i] == 1)
425ExpandedSubBlockStart.gifContractedSubBlock.gif                {
426                    //罪犯数增加1
427                    guiltyCount++;    
428                }

429            }
    
430            //如果根据证言能够恰好有一个罪犯(表示在这次由n个人组成说谎者的情况下正好找到了一个罪犯)
431            if(guiltyCount == 1)
432ExpandedSubBlockStart.gifContractedSubBlock.gif            {
433                //寻找到那个罪犯
434                for(int i=0; i<m; i++)//每次运行时间:O(m)
435ExpandedSubBlockStart.gifContractedSubBlock.gif                {
436                    if(peopleIsGuilty[i] == 1)
437ExpandedSubBlockStart.gifContractedSubBlock.gif                    {
438                        guilty[i]++;//此步不懂的话到申明处看看guilty的注释
439                        break;
440                    }

441                }
    
442            }
    
443            else//否则不能恰好找到一个罪犯(根据题目补充点四,我们判断是否恰好有m-1个人不是罪犯)
444ExpandedSubBlockStart.gifContractedSubBlock.gif            {
445                //统计不是罪犯的人数
446                int notGuiltyCount = 0;
447                for(int i=0; i<m; i++)//每次运行时间:O(m)
448ExpandedSubBlockStart.gifContractedSubBlock.gif                {
449                    if(peopleIsGuilty[i] == -1)
450ExpandedSubBlockStart.gifContractedSubBlock.gif                    {
451                        notGuiltyCount++;    
452                    }

453                }
    
454                //如果根据证言能够恰好有m-1个人不是罪犯
455                if(notGuiltyCount == m-1)
456ExpandedSubBlockStart.gifContractedSubBlock.gif                {
457                    //找出那个不能推出是不是罪犯的人
458                    for(int i=0; i<m; i++)//每次运行时间:O(m)
459ExpandedSubBlockStart.gifContractedSubBlock.gif                    {                        
460                        if(peopleIsGuilty[i] != -1)
461ExpandedSubBlockStart.gifContractedSubBlock.gif                        {
462                            //那么我们认为他是罪犯
463                            guilty[i]++;
464                            break;
465                        }

466                    }
    
467                }
            
468            }

469        }

470    }
while(NextGroupStoryPeople());//直到所有说谎组合均考虑过后。运行次数C(m,n),NextGroupStoryPeople运行时间为:O(m) 
471ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//*
472    我们也可以在找到两个罪犯时退出模拟寻找过程以便提高程序效率,因为题目要求当能找到多于1个罪犯时仅输出“Cannot Determine”
473    */

474}

475
476 // 输出结果,此函数说明略
477 void  show() // 运行时间:O(m)
478 ExpandedBlockStart.gifContractedBlock.gif {
479    int guiltyCount = 0;
480    string guiltyName;
481
482    for(int i=0; i<m; i++)
483ExpandedSubBlockStart.gifContractedSubBlock.gif    {
484        if(guilty[i]>0)
485ExpandedSubBlockStart.gifContractedSubBlock.gif        {
486            guiltyCount++;
487            guiltyName = people[i].Name;
488        }

489    }

490    switch(guiltyCount)
491ExpandedSubBlockStart.gifContractedSubBlock.gif    {
492        case 0:
493            cout<<"Impossible"<<endl;
494            break;    
495        case 1:
496            cout<<guiltyName<<endl;
497            break;
498        default:
499            cout<<"Cannot Determine"<<endl;
500            break;
501    }

502    
503}

504
505 int  main( int  argc,  char   * argv[]) // 运行时间:O(p*C(m,n))+O(m*C(m,n))
506 ExpandedBlockStart.gifContractedBlock.gif {
507    init();//初始化全局变量,从输入文件中读取数据
508    run();//运行模拟查找过程
509    show();//输出结果
510    system("PAUSE");
511    return EXIT_SUCCESS;
512}

513

转载于:https://www.cnblogs.com/SDJL/archive/2008/08/20/1272047.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值