UOJ#454-[UER #8]打雪仗【通信题】

1|0正题

题目链接:https://uoj.ac/problem/454


1|1题目大意

Alice有一个长度为2n01串,Bobn个在[1,2n]位置的下标表示它想要得到01串中这些位置的值,现在两个人可以向对方传输不超过m0/1字符,要求使得Bob可以得到答案。

1n1000,m=1350


1|2解题思路

两种方法,都是平均两边的传输信息。
第一种方法是从左到右传输01串,由Bob考虑若一个位置需要传输,那么传输1,然后Alice传输这个位置给他并考虑下一个位置。否则传输0,然后Alice跳过这个位置传输下一个位置给她然后再考虑下一个位置。
不难发现这样对于01隔开的情况可以省略很多次数,所以我们直接随机打乱整个序列然后这样做即可。

第二种方法是将序列分为三块,Bob用二进制告诉Alice需要信息最多的那个块。然后剩下两个块由Bob告诉Alice需要传输哪些位置。
这样的次数Alice严格小于23n×2Bob严格小于43n+2,都在1350次内。

因为第二种方法比较普遍所以代码使用的是第一种方法


1|3code

1|0Alice

#include <iostream> #include <fstream> #include <string> #include<cstdlib> #include<cstdio> #include<algorithm> using namespace std; ifstream fin; char get_bit() { return getchar(); } void send_bit(char ch) { putchar(ch); fflush(stdout); } int n, m,c[2100],r[2100]; string s; void init_t() { fin.open("alice.in"); fin >> n >> m >> s; } int Z=17; int randd(){ Z++; return (Z*1931ll+Z*Z*3ll)%32767; } int main() { init_t(); for(int i=1;i<=2*n;i++)r[i]=i; for(int i=1;i<=20*n;i++)swap(r[randd()%(2*n)+1],r[randd()%(2*n)+1]); for(int i=1;i<=2*n;i++)c[r[i]]=s[i-1]; int i=1; // for(int i=1;i<=2*n;i++)send_bit(c[i]); while(i<=2*n){ char z=get_bit(); if(z==EOF)break; if(z=='1'){send_bit(c[i]);i++;} else{i++;if(i>2*n)break;send_bit(c[i]);i++;} } return 0; }

1|0Bob

#include <iostream> #include <fstream> #include<cstdlib> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; ifstream fin; char get_bit() { return getchar(); } void send_bit(char ch) { putchar(ch); fflush(stdout); } const int N = 1000; int n, m, p[N + 1],r[N*2+10],w[N*2+10]; char s[N+1]; ofstream fout; void answer() { fout.open("bob.out"); for(int i=1;i<=n;i++) fout<<s[i]; fout<<endl; exit(0); } void init_t() { int x; fin.open("bob.in"); fin >> n >> m; for (x = 1; x <= n; ++x) fin >> p[x]; } int Z=17; int randd(){ Z++; return (Z*1931ll+Z*Z*3ll)%32767; } int main() { init_t(); for(int i=1;i<=2*n;i++)r[i]=i; for(int i=1;i<=20*n;i++)swap(r[randd()%(2*n)+1],r[randd()%(2*n)+1]); for(int i=1;i<=n;i++)p[i]=r[p[i]],w[p[i]]=i; sort(p+1,p+1+n); int z=1,i=1; while(i<=n){ if(p[i]==z){send_bit('1');s[w[p[i]]]=get_bit();z++;i++;} else{ send_bit('0');z++; if(z>2*n)break; s[w[p[i]]]=get_bit(); if(p[i]==z)i++;z++; } } answer(); return 0; }

__EOF__

本文作者QuantAsk
本文链接https://www.cnblogs.com/QuantAsk/p/15128098.html
关于博主:退役OIer,GD划水选手
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   QuantAsk  阅读(124)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示