[交互題] ARC070 F - HonestOrUnkind

Solution

有一句話叫作人多力量大。
所以真的人多就能判斷出來qwq
一個簡單的想法是找出真的人。
一個辦法可以構造一條有向的鏈,如果這條鏈中有真的人,那麼就可以得到鏈頭是真的人。
發現ab 是假的說明ab 之間必有一個假的。可以把他們消掉。
具體的操作的話可以維護一個棧,每次詢問棧頂和當前枚舉到的。
這樣剩下m 個人。
因爲a<b ,所以ak<bk 。這m 個人裏一定有真的人。再根據前面的操作得到的是每個人都說棧中在他上面的人是真的,那麼就從真的人開始,之後說的都是真話。
所以棧頂一定是真人。
然後n 次詢問得出答案。

#include <bits/stdc++.h>
using namespace std;

const int N = 10101;

inline void Guess(int x, int y) {
    printf("? %d %d\n", x - 1, y - 1);
    fflush(stdout);
}
inline int Receive(void) {
    static char c;
    for (c = getchar(); c != 'Y' && c != 'N'; c = getchar()) {
        swap(c, c);
    }
    return c == 'Y';
}

int a, b, n, top;
int sta[N], ans[N];
vector<int> q;

int main(void) {
    freopen("1.in", "r", stdin);
    freopen("1.out", "w", stdout);
    cin >> a >> b;
    n = a + b;
    if (a <= b) {
        printf("Impossible");
        return 0;
    }
    for (int i = 1; i <= n; i++) {
        if (!top) {
            sta[++top] = i;
        } else {
            Guess(sta[top], i);
            if (Receive()) sta[++top] = i;
            else --top;
        }
    }
    for (int i = 1; i <= n; i++) {
        Guess(sta[top], i);
        ans[i] = Receive();
    }
    putchar('!'); putchar(' ');
    for (int i = 1; i <= n; i++)
        putchar('0' + ans[i]);
    putchar('\n');
    return 0;
}
發佈了231 篇原創文章 · 獲贊 375 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章