zoukankan      html  css  js  c++  java
  • AT2348 [ARC070D] HonestOrUnkind 题解

    ATcoder
    Luogu

    Description.

    交互题。
    有很多好人和坏蛋,你知道有 \(a\) 个好人和 \(b\) 个坏蛋。
    你每次可以问 \(x\)\(y\) 是不是好人。
    如果 \(x\) 是好人他会如实回答,否则会按一定策略任意回答。
    问你能否判断哪些人是好人,并交互。

    Solution1.

    首先考虑无解情况。
    如果 \(a\le b\),我们取出一个 \(b\) 的集合装成好人,肯定分不清。
    否则就一定有解,证明通过构造。
    首先,我们分别问 \(x\) \(y\) 的身份和问 \(y\) \(x\) 的身份。
    分类讨论:

    1. 互喷:那肯定有一个是坏蛋,可以先不管最后找到一个诚实的人再问两遍
      用了 \(4\) 步删除了一个人
    2. 互捧:要么两个都是坏蛋,要么都是诚实,可以少掉一个人
    3. 一捧一喷:被喷的肯定不是好人是坏蛋

    递归时 \(a\le b\) 的性质不会变。
    然后就做完了。

    发现这个做法有点 shit,找到一个诚实的人很难。
    反正博主是直接写挂了。

    Solution2.

    考虑维护一个栈,每次询问栈顶 新元素的身份。
    如果是好人就说明身份相同,否则就肯定有一个坏人。
    如果是好人的话就直接入栈,否则弹栈。
    这样构成了一个“猜疑链”,如果有一个人是好人那后面所有人都是好人。
    这样就找到了唯一好人。

    Coding2.

    点击查看代码
    //是啊……你就是那只鬼了……所以被你碰到以后,就轮到我变成鬼了{{{
    #include<bits/stdc++.h>
    using namespace std;typedef long long ll;
    template<typename T>inline void read(T &x)
    {
    	x=0;char c=getchar(),f=0;
    	for(;c<'0'||c>'9';c=getchar()) if(c=='-') f=1;
    	for(;c>='0'&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    	if(f) x=-x;
    }
    template<typename T,typename...L>inline void read(T &x,L&...l) {read(x),read(l...);}//}}}
    int n,a,b,st[100005],tp,rs[100005];
    #ifndef ONLINE_JUDGE
    int limit=0;char debug[100005];mt19937 rnd(time(0));
    #endif
    inline char qry(int x,int y)
    {
    #ifdef ONLINE_JUDGE
    	printf("? %d %d\n",x-1,y-1),fflush(stdout);
    	char ch[4];scanf("%s",ch);return *ch=='Y';
    #else
    	limit++;if(debug[x]) return debug[y];
    	else return 0;
    #endif
    }
    int main()
    {
    #ifdef ONLINE_JUDGE
    	read(a,b),n=a+b;
    #else
    	scanf("%s",debug+1),n=strlen(debug+1);
    	for(int i=1;i<=n;i++) debug[i]^=48;
    	for(int i=1;i<=n;i++) a+=debug[i],b+=!debug[i];
    #endif
    	if(a<=b) return puts("Impossible"),0;
    	for(int i=1;i<=n;i++) if(!tp) st[++tp]=i;
    	else if(qry(st[tp],i)) st[++tp]=i;else tp--;
    	int nw=st[tp];rs[nw]=1;
    	for(int i=1;i<=n;i++) if(i^nw) rs[i]=qry(nw,i);
    #ifndef ONLINE_JUDGE
    	printf("cnt = %d\nlimit = %d\n",limit,n*2);
    	for(int i=1;i<=n;i++) if(rs[i]^debug[i]) return puts("Fail"),0;
    	return puts("Succeed"),0;
    #else
    	printf("! ");for(int i=1;i<=n;i++) putchar(rs[i]^48);
    	return putchar('\n'),fflush(stdout),0;
    #endif
    }
    
  • 相关阅读:
    layui iframe版点击左侧菜单栏实现加载等待动画
    概率论基础内容
    fatal error LNK1123:转换COFF期间失败:文件无效或损坏
    ERROR 2003:Can't connect to MySQL server on ‘localhost’...
    HttpWebRequest 无法连接到远程服务器
    Android Error: java.lang.IllegalStateException: Could not execute method of the activity
    创建.aspx页面
    CodeFile Inherits
    Unable to execute dex:Target out of range
    fatal error C1083: 无法打开包括文件“jni.h”
  • 原文地址:https://www.cnblogs.com/pealfrog/p/15464142.html
Copyright © 2011-2022 走看看