【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 }
posted @ 2018-12-23 18:43  Aegir  阅读(318)  评论(0编辑  收藏  举报