1. 程式人生 > >UOJ Easy Round #8 T1 打雪仗 題解

UOJ Easy Round #8 T1 打雪仗 題解

題目連結:

【UER #8】打雪仗

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