正题

题目链接: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

#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;
}

Bob

#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;
}

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. 【springboot】给你一份Spring Boot知识清单

    目录: 一.抛砖引玉:探索Spring IoC容器 1.1.Spring IoC容器 1.2.Spring容器扩展机制 二.夯实基础:JavaConfig与常见Annotation 2.1.JavaC ...

  2. [C#]c#中数据的同步加锁机制 的几种方法

    一,锁定机制最简单的做法就是使用锁定关键字Lock.Lock关键字英文中就是锁的意思,顾名思义就是为操作加上一把锁.它的语法如下: lock(lockObj){//加锁的代码段,一般是操作共同资源的代 ...

  3. 单例对象 (Singleton)设计模式

    单例的目的是为了保证运行时Singleton类只有唯一的一个实例,用于一些较大开销的操作. 饿汉式(没有线程安全问题): ' 由于使用static关键字进行了修饰,只能获取到一个对象,从而达到了单例, ...

  4. 新书介绍 -- 《Redis核心原理与实践》

    大家好,今天给大家介绍一下我的新书 -- <Redis核心原理与实践>. 后端开发的同学应该对Redis都不陌生,Redis由于性能极高.功能强大,已成为业界非常流行的内存数据库. < ...

  5. python之数据库编程

    python之数据库编程 sqlite 1.前期准备工作 导入模块: import sqlite3 连接数据库 conn = sqlite3.connect("test.db") ...

  6. iNeuOS工业互联平台,增加OPC UA驱动,同步和订阅方式读取数据

    目       录 1.      概述... 1 2.      平台演示... 2 3.      OPC UA应用效果... 2 1.   概述 最近的项目,用户需要使用OPC UA读取数据,通 ...

  7. 微前端框架single-spa初探

    前言 最近入职的一家公司采用single-spa这个微前端框架,所以自学了此框架. single-spa这个微前端框架虽然有中文文档,但是有些零散和晦涩. 所以我想在学习之余,写篇博客拉平一下这个学习 ...

  8. Pytest 系列(24)- allure 环境准备

    如果你还想从头学起Pytest,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1690628.html allure 和 pytest 相 ...

  9. Spring中使用@within与@target的一些区别

    目录 背景 模拟项目例子 看看使用@within和@target的区别 @within @target @target 看起来跟合理一点 通知方法中注解参数的值为什么是不一样的 想用@within,但 ...

  10. OSS对象存储的文件上传、解冻、下载与查看

    上传文件 cp命令用于上传.下载.拷贝文件. # 语法 ./ossutil cp [-r] file_url cloud_url # 例如 ossutil64 cp -r /remote/closed ...