題目連結:
第一次做通訊題,寫篇\(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;
}