1 条题解

  • 0
    @ 2025-8-18 18:30:51

    这个题数据范围比较小,考虑枚举,但是枚举谁说真话谁说假话也比较耗时,但是我们发现日期只有一天,罪犯也只有一个,考虑枚举罪犯是谁,和今天是星期几。

    在读入每一句话时,把这一句的主人(即冒号前的人)对应到它的编号,这里推荐使用std::map,然后判断种类,如果语句不合法就不读这句话,并用gets()把这一行读完进入下一句。如果发现第一个单词是人名,则用std::map找到它的编号,然后看它是肯定句还是否定句。对于每一个点开一个vector用来存它说过的合法的话,区分一下这句话是说人的信息还是日期,如果说人的信息还需要对应到对象,这里最好把I转化为自己的名字。

    接着就可以枚举罪犯和日期了,因为有的人自始至终都没有说过一句合法的话,这样的人既可能说真话也可能说假话,我们用一个变量ran来存有多少个这样的人,剩下的人根据它第一句话来确定它是说真话还是说假话。如果一个人前后矛盾,即前面说真话后面说假话,那么这次枚举就不合法,可以直接跳到下次枚举去。

    在一次成功的枚举中,我们得知了有多少人说假话,有多少人不确定,假设说假话的人有cnt个,并有ran个人不确定,那么当要求说假话的人数在[cnt,cnt+ran]范围内就合法。

    如果一个罪犯被多次确定,是不会对答案造成额外影响的,但是当确定一个罪犯时发现前面已经确定一个人了,此时就要输出Cannot Determine了。当程序结束时还没有找到一个罪犯,则输出Impossible。找到罪犯了输出名字即可。

    stl还是非常方便的,std::string用来存名字并进行字符串处理;std::map用来映射人名;std::vector用来存每个人说的话。不过这个题有一个比较坑的地方,必须要确定一个人说的一句话每个单词都合法后,才能把这整句话当作合法的。&&一定要注意单词后面的冒号和句号!

    • 1

    信息

    ID
    5315
    时间
    1000ms
    内存
    256MiB
    难度
    5
    标签
    递交数
    8
    已通过
    2
    上传者