• ARC070F HonestOrUnkind


    题目传送门

    Description

    交互题

    (n)个人((n=a+bleq 10^3)),编号(0)(n-1),其中(a)个人诚实地回答问题,(b)个人会任意选择诚实或不诚实地回答问题(以某种策略)。

    询问次数(2n),询问格式为(? x y),指问第(x)个人第(y)个人的身份,确定无解或(n)个人的身份。

    Solution

    先判定无解,(aleq b)时显然无解,因为(b)个人中有(a)个人可以按照诚实的人的回答方式回答问题(回答自己的(a)个人时答诚实,回答其它(b)个人答不诚实)。

    首先确定一个思路:先要找到一个诚实的人,这个最多花(n+1)步必须完成。

    那我们如何从回答中获取诚实的人的信息呢?

    注意一个重要的性质:如果回答(No),两人中一定有一人不诚实。

    那么我们若同时不考虑这两个人,仍保证了(a>b),且问题规模变小了。

    于是我们按照(0 and 1, 1 and 2,dots)这样询问就可以了,遇到(No)就把两个一起取走,最后剩下一个序列。因为(a>b),所以其中一定有诚实的人。而且出现了诚实的人,那么后面出现的一定全是诚实的人,于是取最后一个再问(n-1)次即可。

    这样乱搞似乎是(O(n^2))的?其实用栈维护就是(O(n))的。

    空栈或(Yes)就压栈,(No)就弹栈,最后取栈顶即可。

    题外话:这个一步步抵消的思路让我想到了摩尔投票法,也就是这道经典题目的解法。

    Code

    #include<stack>
    #include<cstdio>
    using namespace std;
    const int N = 4005;
    int ans[N];
    
    inline int read()
    {
     	int x = 0, f = 1; char ch = getchar();
    	for (; ch < '0' || ch > '9'; ch = getchar()) if (ch == '-') f = -1;
    	for (; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
    	return x * f;
    }
    
    bool query(int x, int y)
    {
        printf("? %d %d
    ", x, y);
        fflush(stdout);
        char s[3]; scanf("%s", s);
        return s[0] == 'Y';
    }
    
    int main()
    {
        int a = read(), b = read();
        if (a <= b) return puts("Impossible"), 0;
        
        stack<int> Stack;
        for (int i = 0; i < a + b; ++i)
        {
            if (Stack.empty()) Stack.push(i);
            else
            {
                if (query(Stack.top(), i)) Stack.push(i);
                    else Stack.pop();
            }
        }
        
        for (int i = 0; i < a + b; ++i) if (query(Stack.top(), i)) ans[i] = 1;
        printf("! ");
        for (int i = 0; i < a + b; ++i) printf("%d", ans[i]);
        return 0;
    }
    
  • 相关阅读:
    Spring Annotation注解进行aop的学习
    使用ADO读取SQL数据库
    GetInventTable组装SQL语句使用通配符
    获取当前用户所属的所有仓位,DictRelation,
    UnitConvert,单位换算,单位转换
    数字货币书写转英文货币书写
    导出xml
    存储过程IN参数疑难问题解决方法
    TempTable 临时表
    多栏报表 多列报表
  • 原文地址:https://www.cnblogs.com/ACMSN/p/11030146.html
Copyright © 2020-2023  润新知