正题

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


题目大意

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

\(1\leq n\leq 1000,m=1350\)


解题思路

两种方法,都是平均两边的传输信息。

第一种方法是从左到右传输\(01\)串,由\(Bob\)考虑若一个位置需要传输,那么传输\(1\),然后\(Alice\)传输这个位置给他并考虑下一个位置。否则传输\(0\),然后\(Alice\)跳过这个位置传输下一个位置给她然后再考虑下一个位置。

不难发现这样对于\(01\)隔开的情况可以省略很多次数,所以我们直接随机打乱整个序列然后这样做即可。

第二种方法是将序列分为三块,\(Bob\)用二进制告诉\(Alice\)需要信息最多的那个块。然后剩下两个块由\(Bob\)告诉\(Alice\)需要传输哪些位置。

这样的次数\(Alice\)严格小于\(\frac{2}{3}n\times 2\),\(Bob\)严格小于\(\frac{4}{3}n+2\),都在\(1350\)次内。

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


code

Alice

  1. #include <iostream>
  2. #include <fstream>
  3. #include <string>
  4. #include<cstdlib>
  5. #include<cstdio>
  6. #include<algorithm>
  7. using namespace std;
  8. ifstream fin;
  9. char get_bit() {
  10. return getchar();
  11. }
  12. void send_bit(char ch) {
  13. putchar(ch);
  14. fflush(stdout);
  15. }
  16. int n, m,c[2100],r[2100];
  17. string s;
  18. void init_t() {
  19. fin.open("alice.in");
  20. fin >> n >> m >> s;
  21. }
  22. int Z=17;
  23. int randd(){
  24. Z++;
  25. return (Z*1931ll+Z*Z*3ll)%32767;
  26. }
  27. int main()
  28. {
  29. init_t();
  30. for(int i=1;i<=2*n;i++)r[i]=i;
  31. for(int i=1;i<=20*n;i++)swap(r[randd()%(2*n)+1],r[randd()%(2*n)+1]);
  32. for(int i=1;i<=2*n;i++)c[r[i]]=s[i-1];
  33. int i=1;
  34. // for(int i=1;i<=2*n;i++)send_bit(c[i]);
  35. while(i<=2*n){
  36. char z=get_bit();
  37. if(z==EOF)break;
  38. if(z=='1'){send_bit(c[i]);i++;}
  39. else{i++;if(i>2*n)break;send_bit(c[i]);i++;}
  40. }
  41. return 0;
  42. }

Bob

  1. #include <iostream>
  2. #include <fstream>
  3. #include<cstdlib>
  4. #include<cstdio>
  5. #include<cstring>
  6. #include<algorithm>
  7. using namespace std;
  8. ifstream fin;
  9. char get_bit() {
  10. return getchar();
  11. }
  12. void send_bit(char ch) {
  13. putchar(ch);
  14. fflush(stdout);
  15. }
  16. const int N = 1000;
  17. int n, m, p[N + 1],r[N*2+10],w[N*2+10];
  18. char s[N+1];
  19. ofstream fout;
  20. void answer() {
  21. fout.open("bob.out");
  22. for(int i=1;i<=n;i++)
  23. fout<<s[i];
  24. fout<<endl;
  25. exit(0);
  26. }
  27. void init_t() {
  28. int x;
  29. fin.open("bob.in");
  30. fin >> n >> m;
  31. for (x = 1; x <= n; ++x) fin >> p[x];
  32. }
  33. int Z=17;
  34. int randd(){
  35. Z++;
  36. return (Z*1931ll+Z*Z*3ll)%32767;
  37. }
  38. int main() {
  39. init_t();
  40. for(int i=1;i<=2*n;i++)r[i]=i;
  41. for(int i=1;i<=20*n;i++)swap(r[randd()%(2*n)+1],r[randd()%(2*n)+1]);
  42. for(int i=1;i<=n;i++)p[i]=r[p[i]],w[p[i]]=i;
  43. sort(p+1,p+1+n);
  44. int z=1,i=1;
  45. while(i<=n){
  46. if(p[i]==z){send_bit('1');s[w[p[i]]]=get_bit();z++;i++;}
  47. else{
  48. send_bit('0');z++;
  49. if(z>2*n)break;
  50. s[w[p[i]]]=get_bit();
  51. if(p[i]==z)i++;z++;
  52. }
  53. }
  54. answer();
  55. return 0;
  56. }

UOJ#454-[UER #8]打雪仗【通信题】的更多相关文章

  1. UOJ#454. 【UER #8】打雪仗

    UOJ#454. [UER #8]打雪仗 http://uoj.ac/problem/454 分析: 好玩的通信题~ 把序列分成三块,\(bob\)先发出这三块中询问点最多的一块给\(alice\). ...

  2. 蕞短鹭(artskjid) (⭐通信题/模拟⭐)

    文章目录 题面(过于冗长,主要是对通信题的一些解释) 题解 1.通信题什么意思 2.此题题解 CODE 实现 题面(过于冗长,主要是对通信题的一些解释) 题解 1.通信题什么意思 并不是两个程序同时跑 ...

  3. UOJ #455 [UER #8]雪灾与外卖 (贪心、模拟费用流)

    题目链接 http://uoj.ac/contest/47/problem/455 题解 模拟费用流,一个非常神奇的东西. 本题即为WC2019 laofu的讲课中的Problem 8,经典的老鼠进洞 ...

  4. [UOJ#245][UER#7]天路(近似算法)

    允许5%的相对误差,意味着我们可以只输出$\log_{1.05} V$种取值并保证答案合法.并且注意到答案随着区间长度而单增,故取值不同的答案区间是$O(\log_{1.05} V)$的. 于是初始x ...

  5. 【bzoj4736/uoj#274】[清华集训2016]温暖会指引我们前行 语文题+LCT

    题目描述 http://uoj.ac/problem/274 题解 语文题+LCT 对于这种语文题建议还是自己读题好一些... 读懂题后发现:由于温度互不相同,最大生成树上的路径必须走(不走的话温度大 ...

  6. 【UOJ#228】基础数据结构练习题 线段树

    #228. 基础数据结构练习题 题目链接:http://uoj.ac/problem/228 Solution 这题由于有区间+操作,所以和花神还是不一样的. 花神那道题,我们可以考虑每个数最多开根几 ...

  7. NOIp2018停课刷题记录

    Preface 老叶说了高中停课但是初中不停的消息后我就为争取民主献出一份力量 其实就是和老师申请了下让我们HW的三个人听课结果真停了 那么还是珍惜这次机会好好提升下自己吧不然就\(AFO\)了 Li ...

  8. 省选/NOI刷题Day2

    bzoj2616 放一个车的时候相当于剪掉棋盘的一行,于是就可以转移了,中间状态转移dp套dp,推一下即可 bzoj2878 环套树期望dp 手推一下递推式即可 bzoj3295 树状数组套权值线段树 ...

  9. uoj#300.【CTSC2017】吉夫特

    题面:http://uoj.ac/problem/300 一道大水题,然而我并不知道$lucas$定理的推论.. $\binom{n}{m}$为奇数的充要条件是$n&m=n$.那么我们对于每个 ...

随机推荐

  1. 获取访问者真实ip地址?我觉得不可能

    我们真的能通过请求来获取用户真实的ip地址嘛? 答案是不能,如果能,肯定是我学的不够深入,欢迎交流指正. 那么写这篇文章的意义是什么?我们接着往下看. IP地址相当于电脑在网络上的身份证,但事实上IP ...

  2. Spring boot集成Redis实现sessions共享时,sessions过期时间问题分析

    Springboot鼓励零配置的方式,帮你做好大部分重复劳动的事,好到不能再好:具体的Redis安装方法和Springboot集成Redis方法,可以去搜索相关文章或参考该文章http://www.c ...

  3. Ubuntu系统开放指定端口

    今天在一台Ubuntu服务器里面配置了一个Nginx服务,监听的8080端口.本机可以访问,但是局域网就是访问不到.首先怀疑防火墙没有开放8080端口,设置ufw防火墙开放8080端口 $ sudo ...

  4. C++11 weak_ptr智能指针

    和 shared_ptr.unique_ptr 类型指针一样,weak_ptr 智能指针也是以模板类的方式实现的.weak_ptr<T>( T 为指针所指数据的类型)定义在<memo ...

  5. [SWMM]模型子汇水区划分的几种方法

    子汇水区的划分是SWMM模型建模的主要步骤之一,划分的好坏对结果精度有比较大的影响.概括来讲,子汇水区的划分有以下几种思路: (1)根据管网走向.建筑物和街道分布,直接人工划分子汇水区.这个方法适用于 ...

  6. Go版本依赖--伪版本

    目录 1.简介 2. 什么是伪版本 3. 伪版本风格 4. 如何获取伪版本 1.简介 在go.mod中通常使用语义化版本来标记依赖,比如v1.2.3.v0.1.5等.因为go.mod文件通常是go命令 ...

  7. i++ ++i 理解

    i++与++i怎么运算,解决办法: i++规则是在表达式中先取i的值使用,后让i的值变化成加1后的值. 举例:如在式中 j=i++,他就会变成这样的两步,第一步先执行j=i,第二步执行i=i+1. + ...

  8. 前后端数据交互(二)——原生 ajax 请求详解

    一.ajax介绍 ajax 是前后端交互的重要手段或桥梁.它不是一个技术,是一组技术的组合. ajax :a:异步:j:js:a:和:x:服务端的数据. ajax的组成: 异步的 js 事件 其他 j ...

  9. SSL基础知识及Nginx/Tomcat配置SSL

    HTTPS 是在 HTTPS 基础之上添加 SSL/TLS 使网络通讯加密,进而确保通信安全.可简记为 HTTPS = HTTP + SSL/TLS 本文档主要讲解常规SSL格式.Nginx 与 To ...

  10. Spring Boot 入门系列(二十四)多环境配置,3分钟搞定!

    之前讲过Spring Boot 的系统配置和自定义配置,实现了按照实际项目的要求配置系统的相关熟悉.但是,在实际项目开发过程中,需要面对不同的环境,例如:开发环境,测试环境,生产环境.各个环境的数据库 ...