1. 程式人生 > >簡單的列舉(人機互動題)

簡單的列舉(人機互動題)

Example

input

2

1

0

1

2

output

01

11

10

00

思路:先利用mt19937這個隨機數,隨機出正確n/2的字串。

接著,就是比較精妙的地方,用O(n)的複雜度猜出完整的字串,設我們隨機出來正確n/2的字串是s.

設ans=s

我們先這樣考慮,s[0]要麼是對的,要麼是錯的。

假設s[0]是對的,那麼對s[0]取反以後,s中正確的只有n/2-1個了,這時,我們將string tmp=s

從 i=1開始,依次猜tmp[i]^=1,也就是將tmp[i]取反以後輸出,如果能返回n/2,意味著這一位上s[i]是錯誤的,因為tmp[i]是正確的,我們將ans[i]也取反(將錯的變成對的),所以,這樣遍歷一遍以後,ans就是最後的正確答案。

假設 s[0]是錯的,那麼對s[0]取反以後,s中正確的有n/2+1個了,令string tmp=s,

還是從i=1開始,依次對tmp[i]進行取反,一旦滿足正確的有n/2個,說明原來的s[i]是正確的,取反以後變成了錯誤的,所以我們將錯就錯,將ans[i]也取反,最後得出的ans是全錯的,所以在取一次反就可以了。

程式碼:

#include <bits/stdc++.h>
using namespace std;
int n;
int main()
{
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
    mt19937 mt_rand(time(0));
    string ans;
    cin>>n;
    int tmp;
    while(1)
    {
        ans="";
        for(int i=0;i<n;i++)
        {
            ans.push_back('0'+(mt_rand()&1));
        }
        cout<<ans<<endl;
        cin>>tmp;
        if(tmp==n) return 0;
        if(tmp==n/2) break;
    }
    string ret=ans;
    ans[0]^=1;
    for(int i=1;i<n;i++)
    {
        string s=ans;
        s[i]^=1;
        cout<<s<<endl;
        cin>>tmp;
        if(tmp)
        {
            ret[i]^=1;
        }
    }
    cout<<ret<<endl;
    cin>>tmp;
    if(tmp==n) return 0;
    for(auto &t: ret)
    {
        t^=1;
    }
    cout<<ret<<endl;
    cin>>tmp;
    return 0;
}