UOJ Easy Round #8 T1 打雪仗 題解
阿新 • • 發佈:2018-12-23
題目連結:
第一次做通訊題,寫篇\(blog\)加深印象。
首先分析題目,根據資料,最壞情況下\(m\approx \frac23n\)
剛開始時想著把進位制壓到更高進位制輸出,不過實現不來放棄了。
那麼把\(2n\)分成一些長度為\(3\)的區間,對於\(1,2\)個字元,直接由小\(B\)告訴小\(A\)是否需要,如果需要則小\(A\)傳送字元。
對於第\(3\)個字元,無論需不需要都由小\(A\)發出。
那麼顯然小\(B\)的輸出長度正好為\(\frac23n\)。
對於小\(A\),最壞情況下沒有一個有用的字元在第\(3\)個位置,則總長度為\(n+\frac13n=\frac43n\)
那麼就可以愉快的通過此題了。
時間複雜度 \(O(n)\)
關於實現:
\(Alice.cpp:\)
#include <string> #include <fstream> #include <iostream> int n,m; std::string s; int main() { std::ifstream("alice.in")>>n>>m>>s; //檔案指標用不來,反正輸入量不大(x for(int i=0;i<=1995;i+=3) { if(std::cin.get()==49)std::cout<<s[i]; if(std::cin.get()==49)std::cout<<s[i+1]; //對應前2個字元,需要才輸出。 (std::cout<<s[i+2]).flush(); //對於第三個字元,必須輸出。 //同時注意在輸出之後立即清空緩衝區,讓$Bob$可以接收。 } (std::cout<<s[1998]<<s[1999]).flush();//最後2個單獨處理,直接輸出,影響不大。 return 0; }
\(Bob.cpp:\)
#include <string> #include <fstream> #include <iostream> int n,m; bool v[2005]; std::string s; int main() { std::ifstream Fin("bob.in"); Fin>>n>>m; for(int i=1,x;i<=1000;++i) Fin>>x,v[x-1]=true; for(int i=0;i<=1995;i+=3) { (std::cout<<v[i]<<v[i+1]).flush(); //是否需要前2個字元 if(v[i])s+=std::cin.get(); if(v[i+1])s+=std::cin.get(); char c=std::cin.get(); if(v[i+2])s+=c; //第三個字元必須輸入,防止影響後面。 } if(v[1998])s+=std::cin.get(); if(v[1999])s+=std::cin.get(); //加上最後兩個字元 std::ofstream Fout("bob.out"); Fout<<s<<'\n'; //這裡可以不flush,因為最後return 0了,自動清空快取。 return 0; }