Gym100851J Jump 随机数+思维

网址:https://codeforces.com/gym/100851

题意:

交互题,程序先接收$01$字符串的长度,然后程序输出一个长度是$n$的字符串,如果一半的内容正确,则评测姬返回$\frac{n}{2}$,如果所有内容正确,则评测姬返回$n$,程序终止,其他情况评测姬返回$0$,程序只允许猜测字符串$n+500$次。($n\leq1e3$)。

题解:

毕竟可以浪费猜$500$次呢!我们考虑长度是$1000$的字符串,我们猜$1$次,输出$\frac{n}{2}$的概率是$\frac{C_{1000}^{500}}{2^{1000}}$,大概是$0.02$,所以猜错的概率是$0.98$,猜$450$次的都是错误的概率就是$1.12*10^{-4}$,错了直接去买彩票好了。猜对之后,我们现在获得了一个有了一个有$\frac{n}{2}$的字符是正确的字符串,我们对于第$i$个字符($2\leq i\leq n$),把它和第$1$个字符一起取反,然后观察返回值,如果结果是$\frac{n}{2}$,则说明是它们是一对一错的,如果是$0$,就是要么都对要么都错。处理完之后,我们假定第$1$个字符是对的,把错的取反,观察返回值,如果是$n$,这个串就是答案了,如果是$0$,则全部取反,这个一定就是对的了。

AC代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 5;
map<string, int>mp;
bool g[N];
char get_rev(char s)
{
    if (s == '0')
        return '1';
    else if (s == '1')
        return '0';
    assert(0);
}
int main()
{
    int n, ans = 0;
    scanf("%d", &n);
    srand(0);
    string s(n, 0);
    while(1)
    {
        s = string(n, 0);
        for (int j = 0; j < n; ++j)
            s[j] = rand() % 2 + '0';
        if (!mp[s])
        {
            mp[s] = 1;
            printf("%s\n", s.c_str());
            fflush(stdout);
            fflush(stdin);
            scanf("%d", &ans);
            if (ans == n)
                return 0;
            else if (ans == n / 2)
                break;
        }
    }
    memset(g, 0, sizeof(g));
    for (int i = 1; i < n; ++i)
    {
        s[0] = get_rev(s[0]);
        s[i] = get_rev(s[i]);
        printf("%s\n", s.c_str());
        fflush(stdout);
        fflush(stdin);
        scanf("%d", &ans);
        if (ans == n / 2)
            g[i] = g[0] ^ 1;
        else if (ans == 0)
            g[i] = g[0];
        else if (ans == n)
            return 0;
        s[0] = get_rev(s[0]);
        s[i] = get_rev(s[i]);
    }
    for (int i = 0; i < n; ++i)
        if (g[i])
            s[i] = get_rev(s[i]);
    printf("%s\n", s.c_str());
    fflush(stdout);
    fflush(stdin);
    scanf("%d", &ans);
    if (ans == n)
        return 0;
    else
    {
        for (int i = 0; i < n; ++i)
            s[i] = get_rev(s[i]);
        printf("%s\n", s.c_str());
        fflush(stdout);
        fflush(stdin);
        scanf("%d", &ans);
    }
    return 0;
}

 

posted @   Aya_Uchida  阅读(163)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示