题目名称 | 2361. 逻辑岛 |
---|---|
输入输出 | logicisland.in/out |
难度等级 | ★★★★ |
时间限制 | 1000 ms (1 s) |
内存限制 | 256 MiB |
测试数据 | 15 |
题目来源 | mouse 于2016-06-20加入 |
开放分组 | 全部用户 |
提交状态 | |
分类标签 | |
分享题解 |
通过:3, 提交:31, 通过率:9.68% | ||||
月落九天 | 100 | 0.003 s | 0.29 MiB | C++ |
ミント | 100 | 0.004 s | 0.31 MiB | C++ |
fmj | 100 | 0.004 s | 0.31 MiB | C++ |
Saionji | 80 | 0.021 s | 0.27 MiB | C++ |
Saionji | 80 | 0.033 s | 0.25 MiB | C++ |
Saionji | 20 | 0.004 s | 0.31 MiB | C++ |
mouse | 20 | 0.004 s | 0.31 MiB | C++ |
Saionji | 20 | 0.005 s | 0.29 MiB | C++ |
ha sa ki | 20 | 0.012 s | 0.29 MiB | C++ |
ha sa ki | 20 | 0.031 s | 0.31 MiB | C++ |
本题关联比赛 | |||
16暑期热身练习 |
关于 逻辑岛 的近10条评论(全部评论) | ||||
---|---|---|---|---|
膜拜神犇,这道题有什么卵用吗?
NVIDIA
2016-07-31 16:32
4楼
| ||||
回复 @fmj : 666666
..
2016-07-03 10:49
3楼
| ||||
#include <iostream>
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 50 + 10; class kanato{//Kanato-chan——.// public: int sp, re, st;//speaker, reference, status. bool fa;//false(is not ...). }sen[maxn];//sentence. bool night = false; int sta[maxn], is[maxn], n; inline int f(bool flag){//false==1貌似会不被判断为真...orz Update: 废话. 懒得重打就这么凑合着看吧. if(flag)return 1; return 0; } inline bool check(){ bool flag = false;//这句话是否成立. for(int i=1;i<=n;i++){//逐个检验每句话关于时间与身份的信息. if(sen[i].re==-1){//关于时间. if(sen[i].st==f(night))flag = true; else flag = false; } else if(sen[i].st<3){//关于身份. if(sen[i].st==sta[sen[i].re])flag = true; else flag = false; } else if((sta[sen[i].re]==1)||(sta[sen[i].re]==2)&&night)flag = true;//魔鬼或者是晚上的人. else flag = false; //对于说这句话的家伙. if(sen[i].fa)flag = !flag;//"Is not ...". if((sta[sen[i].sp])==1||(sta[sen[i].sp]==2&&night))flag = !flag; if(flag==false)//如果这句话不成立. return false; //那就无解咯. } return true;//找到了一个可行解. } inline bool impos(bool a){ for(int i=1;i<=5;i++)if(!is[i])return true; if(!a)return true; return false; } #define is_cha(x) ((x <= 'z' and x >= 'a') or (x <= 'Z' and x >= 'A')) #define is_sym(x) ( x == '.' or x == ':' or x == ' ') #define is_ch(x) (is_sym(x) or is_cha(x)) string get_line() { char tmp = getchar(); string ans; ans.clear(); while(!is_ch(tmp)) tmp = getchar(); while( is_ch(tmp)) { ans = ans + tmp; tmp = getchar(); } return ans; } int main(){ freopen("logicisland.in", "r", stdin); freopen("logicisland.out", "w", stdout); int kase = 0; //while(cin>>n){getchar();if(n==0)break;kase++;cout<<"Conversation #"<<kase<<endl; memset(is, 0, sizeof(is)); memset(sta, 0, sizeof(sta)); memset(sen, 0, sizeof(sen)); night = false; cin>>n;//getchar();//Read char '/n'. for(int i=1;i<=n;i++){ string str; str = get_line(); int name = str[0] - 'A' + 1, ref = -1;//Speaker, Mentioned. str = str.substr(3, str.length()); if(str[0]=='I'&&str[2]=='a'){//I am. ref = name; str = str.substr(5, str.length());//go over. } else if(str[2]=='i'&&str[3]=='s'){//X is. ref = str[0] - 'A' + 1; str = str.substr(5, str.length());//go over. } else {//It is night/day. ref = -1;//算了用中文注释吧, 没有人被提到的情况ref设为-1. str = str.substr(6, str.length());//继续往后面找相关信息. } sen[i].sp = name;sen[i].re = ref; if(str[0]=='n'&&str[1]=='o'){sen[i].fa = true;str = str.substr(4, str.length());}//Is not. else sen[i].fa = false; // string tmp = "121213413";tmp = tmp.substr(1, tmp.length()); if(str.compare("divine.")==0)sen[i].st = 0; else if(str.compare("evil.")==0)sen[i].st = 1; else if(str.compare("human.")==0)sen[i].st = 2; else if(str.compare("lying.")==0)sen[i].st = 3; else if(str.compare("day.")==0)sen[i].st = 0; else if(str.compare("night.")==0)sen[i].st = 1; else cout<<"Orz Cstdio"<<endl;//哎嘿. } //枚举, 搞大新闻. int tnight = 0, kount = 0; for(night=false;kount<=1;night=!night, kount++) for(sta[1]=0;sta[1]<=2;sta[1]++) for(sta[2]=0;sta[2]<=2;sta[2]++) for(sta[3]=0;sta[3]<=2;sta[3]++) for(sta[4]=0;sta[4]<=2;sta[4]++) for(sta[5]=0;sta[5]<=2;sta[5]++) if(check()){ for(int j=1;j<=5;j++)is[j] |= (1<<sta[j]);//拆二进制存储状态. 1, 2, 4. tnight = tnight | (1<<f(night)); } if(impos(tnight)){cout<<"This is impossible."<<endl<<endl;return 0;}//continue;} bool flag = false;//有没有找到的推论. for(int j=1;j<=5;j++){//先输出身份信息. string out;//cout<<is[j]<<endl; if(is[j]==(1<<0))out = "divine."; else if(is[j]==(1<<1))out = "evil."; else if(is[j]==(1<<2))out = "human."; else continue; flag = true; printf("%c is ", (char)(j+'A'-1));cout<<out<<endl; } if(tnight==(1<<0)){flag = true;cout<<"It is day."<<endl;} if(tnight==(1<<1)){flag = true;cout<<"It is night."<<endl;} if(flag==false)cout<<"No facts are deducible."<<endl; cout<<endl; return 0; }
fmj
2016-07-02 16:56
2楼
| ||||
|
逻辑岛上有三种居民:神、魔鬼和人,神总是说真话,魔鬼总是撒谎,而人则是白天说真话,晚上撒谎。每一个居民都能认出其它居民的身份。
一个社会学家要去逻辑岛上考察,由于他无法根据居民的长相来确定其身份,他需要你为他提供一个通信分析仪通过居民们的谈话来推理出一些事实。其中他最感兴趣的事实是现在是白天还是夜晚,以及说话的居民的身份。
输入文件第一行为一个整数n,表示谈话中语句的个数。
接下来有n行,每行为某个居民所说的一个语句,每个语句行的第一个符号为讲话者的姓名,姓名均为单个的大写字母A,B,C,D,E,姓名之后有一个冒号“:”和一个空格,语句接下来的格式如下:
I am [not] ( divine | human | evil | lying ).
X is [not] ( divine | human | evil | lying ).
It is ( day | night ).
方括号[]表示其中的单词也许会出现,也许不会出现,圆括号()表示其中由|隔开的单词只会出现一种。X为A,B,C,D,E中的一个,任一语句行都不会出现两个连续的空格,谈话中包含的语句最多不超过50个。
如果依照规则这组谈话是不可能发生的,则输出“This is impossible.”(不包括双引号,以下同);
如果无法推理出所需要的事实,输出“No facts are deducible.”;
此外则要求输出所有能够推理出的事实,输出格式如下:
X is ( divine | human | evil ).
It is ( day | night ).
X由一个大写字母即讲话者的姓名代替,居民的身份信息必须首先输出(按姓名的字母顺序),接下来输出白天或夜晚的信息(如果无法推理出来是白天还是晚上则不需输出)。
输入样例1: 1 A: I am evil. 输入样例2: 3 A: B is human. B: A is evil. A: B is evil.
输出样例1: A is human. It is night. 输出样例2: A is evil. B is divine.
在此键入。
在此键入。