• 【UOJ 454】打雪仗(通信题)(分块)


    打雪仗

    题目链接:UOJ 454

    题目大意

    通信题。
    两个人 A 有一个 2n 的 01 的字符串,B 有 n 个要知道的位置。
    两个人可以传 01 给对方,然后最多的人不能传超过 4/3n(会多一点)个字符。
    要你操作,使得 B 知道每个位置是 0 是 1。

    思路

    发现大概是 2 n 2n 2n 2 3 \frac{2}{3} 32,考虑能不能均摊一下了两个人的消费。
    (因为你最暴力可以理解为一个人不说话,第二个把所有人都丢给他,考虑让那个不说话也说说话提供信息)
    然后不难想到各种 50 分的写法。

    然后再看看这个 2 3 \frac{2}{3} 32,我们考虑分块。
    给的那个通过一个一开始的信息得到最多的是哪个,然后整块给,然后剩下的就看对面的 01 串是 1 1 1 就表示要,就给。
    那这样剩下两个块至多给 2 3 n \frac{2}{3}n 32n 加上你 1 3 2 n \frac{1}{3}2n 312n 刚好 2 3 2 n \frac{2}{3}2n 322n

    然后看看要的那个,那大的块自己挑要的,然后剩下两个就你自己要全给,告诉对面每个位置要不要。
    所以就是 2 3 2 n \frac{2}{3}2n 322n,那就也没问题。

    (麻了不会编译,只会提交调试绷不住了)

    代码

    Alice

    #include 
    #include 
    #include 
    
    using namespace std;
    
    ifstream fin;
    char get_bit() {
    	return getchar();
    }
    void send_bit(char ch) {
    	putchar(ch);
    	fflush(stdout);
    }
    
    int n, m;
    string s;
    struct init_t {
    	init_t() {
    		fin.open("alice.in");
    		fin >> n >> m >> s;
    	}
    } init_t;
    
    int L1 = 1, R1 = 666, L2 = 667, R2 = 1332, L3 = 1333, R3 = 2000;
    
    int main() {
    //	if (get_bit() == '0') {
    //		for (int x = 0; x < n; ++x) send_bit(s[x]);
    //	} else {
    //		for (int x = 0; x < n; ++x) send_bit(s[x + n]);
    //	}
    	s = " " + s;
    	
    	int op = get_bit() - '0' + (get_bit() - '0') * 2;
    	if (op == 0) {
    		for (int i = L1; i <= R1; i++) send_bit(s[i]);
    		for (int i = L2; i <= R2; i++) if (get_bit() == '1') send_bit(s[i]);
    		for (int i = L3; i <= R3; i++) if (get_bit() == '1') send_bit(s[i]);
    	}
    	else if (op == 1) {
    		for (int i = L1; i <= R1; i++) if (get_bit() == '1') send_bit(s[i]);
    		for (int i = L2; i <= R2; i++) send_bit(s[i]);
    		for (int i = L3; i <= R3; i++) if (get_bit() == '1') send_bit(s[i]);
    	}
    	else if (op == 2) {
    		for (int i = L1; i <= R1; i++) if (get_bit() == '1') send_bit(s[i]);
    		for (int i = L2; i <= R2; i++) if (get_bit() == '1') send_bit(s[i]);
    		for (int i = L3; i <= R3; i++) send_bit(s[i]);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    Bob

    #include 
    #include 
    #include 
    
    using namespace std;
    
    ifstream fin;
    char get_bit() {
    	return getchar();
    }
    void send_bit(char ch) {
    	putchar(ch);
    	fflush(stdout);
    }
    ofstream fout;
    void answer(string s) {
    	fout << s << endl, exit(0);
    }
    
    const int N = 1000;
    
    int n, m, pos[N + 1];
    struct init_t {
    	init_t() {
    		int x;
    		fin.open("bob.in");
    		fout.open("bob.out");
    		fin >> n >> m;
    		for (x = 1; x <= n; ++x) fin >> pos[x];
    	}
    } init_t;
    
    int L1 = 1, R1 = 666, L2 = 667, R2 = 1332, L3 = 1333, R3 = 2000;
    
    int main() {
    //	if (pos[n] == n) {
    //		send_bit('0');
    //	} else {
    //		send_bit('1');
    //	}
    //	string ans = "";
    //	for (int x = 0; x < n; ++x) {
    //		ans += get_bit();
    //	}
    	int num0 = 0, num1 = 0, num2 = 0;
    	for (int i = 1; i <= n; i++) {
    		if (L1 <= pos[i] && pos[i] <= R1) num0++;
    		if (L2 <= pos[i] && pos[i] <= R2) num1++;
    		if (L3 <= pos[i] && pos[i] <= R3) num2++;
    	}
    	string s = ""; 
    	if (num0 >= num1 && num0 >= num2) {
    		send_bit('0'); send_bit('0');
    		int now = 1;
    		for (int i = L1; i <= R1; i++) {
    			char c = get_bit();
    			if (now <= n && pos[now] == i) now++, s += c;
    		}
    		for (int i = L2; i <= R2; i++)
    			if (now <= n && pos[now] == i) now++, send_bit('1'), s += get_bit();
    				else send_bit('0');
    		for (int i = L3; i <= R3; i++)
    			if (now <= n && pos[now] == i) now++, send_bit('1'), s += get_bit();
    				else send_bit('0');
    	}
    	else if (num1 >= num0 && num1 >= num2) {
    		send_bit('1'); send_bit('0');
    		int now = 1;
    		for (int i = L1; i <= R1; i++)
    			if (now <= n && pos[now] == i) now++, send_bit('1'), s += get_bit();
    				else send_bit('0');
    		for (int i = L2; i <= R2; i++) {
    			char c = get_bit();
    			if (now <= n && pos[now] == i) now++, s += c;
    		}
    		for (int i = L3; i <= R3; i++)
    			if (now <= n && pos[now] == i) now++, send_bit('1'), s += get_bit();
    				else send_bit('0');
    	}
    	else if (num2 >= num0 && num2 >= num1) {
    		send_bit('0'); send_bit('1');
    		int now = 1;
    		for (int i = L1; i <= R1; i++)
    			if (now <= n && pos[now] == i) now++, send_bit('1'), s += get_bit();
    				else send_bit('0');
    		for (int i = L2; i <= R2; i++)
    			if (now <= n && pos[now] == i) now++, send_bit('1'), s += get_bit();
    				else send_bit('0');
    		for (int i = L3; i <= R3; i++) {
    			char c = get_bit();
    			if (now <= n && pos[now] == i) now++, s += c;
    		}
    	}
    	
    	answer(s);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
  • 相关阅读:
    常用linux命令
    vmware虚拟机启动、使用ubuntu问题
    基于单片机的机械臂运行轨迹在线控制系统设计
    【类和对象+this引用】
    【图论】图的遍历 - 构建领接表(无向图)
    Go语言网络编程(socket编程)UDP
    常用工具类Commons-Configuration2简介
    网络技术十三:DNS(域名服务器)
    通过索引名(行、列名)提取DataFrame中的数据loc()通过索引号(行、列号)提取DataFrame中的数据iloc()
    pinia的常用知识点及搭配“script setup”的使用
  • 原文地址:https://blog.csdn.net/weixin_43346722/article/details/126277871