UOJ Easy Round #8 T1 打雪仗 题解

Posted lanrtabe

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UOJ Easy Round #8 T1 打雪仗 题解相关的知识,希望对你有一定的参考价值。

题目链接:

【UER #8】打雪仗

第一次做通信题,写篇(blog)加深印象。


首先分析题目,根据数据,最坏情况下(mapprox 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<<'
';
    //这里可以不flush,因为最后return 0了,自动清空缓存。
    return 0;
}

以上是关于UOJ Easy Round #8 T1 打雪仗 题解的主要内容,如果未能解决你的问题,请参考以下文章

UER #8打雪仗

UOJ Round 19 题解

UOJ Round #11 简要题解

uoj Goodbye Dingyou Round 题解

UOJ 30 CF Round #278Tourists

UOJ #30. CF Round #278Tourists