【UER #8】打雪仗
题目:http://uoj.ac/contest/47/problem/454
第一次做通信题,看了半天才搞懂是什么意思。
考虑把字符串拆成三段,每段长度为$\frac{2}{3}n$
对于B:
统计每段中有多少个需要知道的下标,然后让A全文发送下标最多的一段,这里只要发送两个字符告知A应该发送哪一段即可
然后遍历剩下的两段,如果当前下标是需要知道的,就发送1,否则就发送0,这里需要发送$\frac{4}{3}n$个字符
所以对于B,最多只要发送$\frac{4}{3}n + 2$个字符
对于A:
先读入两个字符,然后全文发送B需要的那一段
同样遍历剩下的两段,如果读到的B发送过来的信息是1,则发送当前文字,如果是0则不输出任何字符
首先最多的那一段,它至少包含了$\frac{1}{2}n$个下标,所以在剩下的两段中,我们最多只需发送$\frac{1}{2}n$次即可
总的发送次数就是$\frac{1}{2}n + \frac{2}{3}n$
题目并不难,但这是一道通信题,要注意一些操作细节,具体见代码:
A:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int n, m; 5 char s[2010]; 6 string cur; 7 8 inline char Putchar(char c) 9 { 10 putchar(c); 11 fflush(stdout); 12 } 13 14 void init() 15 { 16 ifstream fin("alice.in"); 17 fin >> n >> m >> (s + 1); 18 } 19 20 int main() 21 { 22 ifstream fin("alice.in"); 23 fin >> n >> m >> (s + 1); 24 cur.push_back(getchar()), cur.push_back(getchar()); 25 if(cur == "00") 26 { 27 for(int i = 1; i <= 666; ++i) Putchar(s[i]); 28 for(int i = 667; i <= 2000; ++i) 29 { 30 if(getchar() == '1') Putchar(s[i]); 31 else fflush(stdout); 32 } 33 } 34 else if(cur == "01") 35 { 36 for(int i = 1; i <= 666; ++i) 37 { 38 if(getchar() == '1') Putchar(s[i]); 39 else fflush(stdout); 40 } 41 for(int i = 667; i <= 1332; ++i) Putchar(s[i]); 42 for(int i = 1333; i <= 2000; ++i) 43 { 44 if(getchar() == '1') Putchar(s[i]); 45 else fflush(stdout); 46 } 47 } 48 else 49 { 50 for(int i = 1; i <= 1332; ++i) 51 { 52 if(getchar() == '1') Putchar(s[i]); 53 else fflush(stdout); 54 } 55 for(int i = 1333; i <= 2000; ++i) Putchar(s[i]); 56 } 57 return 0; 58 }
B:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 string ans; 5 int n, m; 6 int pos[1010], cnt[2010]; 7 8 inline char Putchar(char c) 9 { 10 putchar(c); 11 fflush(stdout); 12 } 13 14 int main() 15 { 16 ifstream fin("bob.in"); 17 fin >> n >> m; 18 for(int i = 1; i <= n; ++i) 19 { 20 fin >> pos[i]; 21 cnt[pos[i]] = 1; 22 } 23 for(int i = 1; i <= 2000; ++i) cnt[i] += cnt[i - 1]; 24 int c1 = cnt[666], c2 = cnt[1332] - cnt[666], c3 = n - cnt[1332]; 25 int mx = max(c1, max(c2, c3)); 26 memset(cnt, 0, sizeof(cnt)); 27 for(int i = 1; i <= n; ++i) cnt[pos[i]] = 1; 28 if(c1 == mx) 29 { 30 Putchar('0'), Putchar('0'); 31 for(int i = 1; i <= 666; ++i) 32 { 33 if(cnt[i]) ans.push_back(getchar()); 34 else getchar(); 35 } 36 for(int i = 667; i <= 2000; ++i) 37 { 38 Putchar('0' + cnt[i]); 39 if(cnt[i]) ans.push_back(getchar()); 40 } 41 } 42 else if(c2 == mx) 43 { 44 Putchar('0'), Putchar('1'); 45 for(int i = 1; i <= 666; ++i) 46 { 47 Putchar('0' + cnt[i]); 48 if(cnt[i]) ans.push_back(getchar()); 49 } 50 for(int i = 667; i <= 1332; ++i) 51 { 52 if(cnt[i]) ans.push_back(getchar()); 53 else getchar(); 54 } 55 for(int i = 1333; i <= 2000; ++i) 56 { 57 Putchar('0' + cnt[i]); 58 if(cnt[i]) ans.push_back(getchar()); 59 } 60 } 61 else 62 { 63 Putchar('1'), Putchar('0'); 64 for(int i = 1; i <= 1332; ++i) 65 { 66 Putchar('0' + cnt[i]); 67 if(cnt[i]) ans.push_back(getchar()); 68 } 69 for(int i = 1333; i <= 2000; ++i) 70 { 71 if(cnt[i]) ans.push_back(getchar()); 72 else getchar(); 73 } 74 } 75 ofstream fout("bob.out"); 76 fout << ans << endl; 77 return 0; 78 }