簡單的列舉(人機互動題)
阿新 • • 發佈:2018-12-01
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; }