【JZOJ 杂题选讲】【UER #8】打雪仗

题目

通信题
A知道一个长为2n的01串,B知道n个位置
AB之间可以互相发送01字符,每个人所发不超m个
让AB互相通信,使B得到n个位置的具体值
n=1000 m=1350
子问题:m=1600

思路

4/3n<1350
把串分成三块,每块2/3n
让B告诉A最多所需的块,A把整块发给B
B把剩下所需的位置发给A,A回复所需的值
由于第一次减掉至少1/3n的询问,A在第二次只会发2/3n次,加上第一次的总共为4/3n
B发的总数为两块的长度,同为4/3n

代码

#include<bits/stdc++.h>
using namespace std;
char w[2050];
void pr(char s) {
    putchar(s);
    fflush(stdout);
}
int L[4],R[4];
int main() {
    FILE *fp=fopen("alice.in","r");
    int n,m;
    fscanf(fp,"%d%d%s",&n,&m,w+1);
    fclose(fp);
    int i;
    int block=667;
    L[1]=1; R[1]=block; L[2]=block+1; R[2]=block*2; L[3]=R[2]+1; R[3]=2*n; 
 
    int x=getchar()-'0',y=getchar()-'0';
    x=x*2+y;
 
    for(i=L[x];i<=R[x];i++) pr(w[i]);
 
    for(i=1;i<L[x];i++) {
        y=getchar();
        if(y=='1') pr(w[i]);
    }
    for(i=R[x]+1;i<=2*n;i++) {
        y=getchar();
        if(y=='1') pr(w[i]);
    }
}

#include<bits/stdc++.h>
using namespace std;
char w[2050];
void pr(char s) {
    putchar(s);
    fflush(stdout);
}
void print(int x) {
    pr(x/2+'0'); pr((x&1)+'0');
}
int n,m,p[2050],is[2050],L[4],R[4];
int main() {
    FILE *fp=fopen("bob.in","r");
    int n,m,i;
    fscanf(fp,"%d%d",&n,&m);
    for(i=1;i<=n;i++) fscanf(fp,"%d",&p[i]),is[p[i]]=1;
    fclose(fp);
 
    int block=667,c1=0,c2=0,c3=0;
    for(i=1;i<=block;i++) c1+=is[i];
    for(i=block+1;i<=2*block;i++) c2+=is[i];
    for(i=block*2+1;i<=2*n;i++) c3+=is[i];
    L[1]=1; R[1]=block; L[2]=block+1; R[2]=block*2; L[3]=R[2]+1; R[3]=2*n; 
 
    int x=0;
    if(c1>=333) x=1;
    if(c2>=333) x=2;
    if(c3>=333) x=3;
 
    print(x);
 
    for(i=L[x];i<=R[x];i++) w[i]=getchar();
 
    for(i=1;i<L[x];i++) {
        pr(is[i]+'0');
        if(is[i]) w[i]=getchar();
    }
    for(i=R[x]+1;i<=2*n;i++) {
        pr(is[i]+'0');
        if(is[i]) w[i]=getchar();
    }
 
    fp=fopen("bob.out","w");
    for(i=1;i<=n;i++) fprintf(fp,"%c",w[p[i]]);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值