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;
}
posted @ 2018-12-23 11:38  LanrTabe  阅读(332)  评论(0编辑  收藏  举报