Codeforces Round #388 (Div. 2)

 
#Name  
A
standard input/output
1 s, 256 MB
Submit Add to favourites  x6036
B
standard input/output
1 s, 256 MB
Submit Add to favourites  x4139
C
standard input/output
1 s, 256 MB
Submit Add to favourites  x2671
D
standard input/output
2 s, 256 MB
Submit Add to favourites  x1113
E
standard input/output
1 s, 256 MB
Submit Add to favourites  x247

 

 

 

A. Bachgold Problem

给出一个N,请你找出一些素数,使得素数的和为N,且素数的个数最多。注意,素数可以重复,而且N>=2。

 

解:显然用2和3拆喽,大家又不傻。

 1 VAR
 2     n:longint;
 3     a:longint;
 4     i:longint;
 5 BEGIN
 6     readln(n);
 7     a:=n div 2;
 8     writeln(a);
 9     for i:=1 to a-1 do begin
10         write(2);
11         write(' ');
12     end;
13     write(2+n mod 2);
14 END.

 

B. Parallelogram is Back

给出一个平行四边形的三个顶点,输出所有可能的第四个顶点。

 

解:小学几何问题喽,大家又不傻。

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 signed main(void)
 6 {
 7     int x1, y1;
 8     int x2, y2;
 9     int x3, y3;
10     cin    >> x1 >> y1
11         >> x2 >> y2
12         >> x3 >> y3;
13     cout << 3 << endl;
14     cout << +x1 - x2 + x3 << " " << +y1 - y2 + y3 << endl;
15     cout << +x1 + x2 - x3 << " " << +y1 + y2 - y3 << endl;
16     cout << -x1 + x2 + x3 << " " << -y1 + y2 + y3 << endl;
17 }

 

C. Voting

两个政党(D和R)的议员们在进行投票,他们的投票规则十分古怪:当前投票的议员,可以选取一个队里阵营的议员,取消他的投票权。

所有议员按照给出的顺序循环投票,最终以一个阵营的全部议员都被禁言结束,此时另一个阵营就会胜出。如果议员们都按照最优策略投票,请你模拟出投票的结果。

 

解:用两个队列维护两个政党的议员的位置,每次取出两个队首进行比较,位置在前的议员可以弹掉另一个队首,这个队首再也不会进队,而位置在前的议员以当前位置+n的新位置(循环)加入队尾。

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 int n; 
 6 string s;
 7 queue<int> D, R;
 8 
 9 signed main(void)
10 {
11     cin >> n >> s;
12     
13     for (int i = 0; i < n; ++i)
14         (s[i] == 'D' ? D : R).push(i);
15         
16     while (!D.empty() && !R.empty())
17     {
18         if (D.front() < R.front())
19             R.pop(), D.push(D.front() + n), D.pop();
20         else
21             D.pop(), R.push(R.front() + n), R.pop();        
22     }
23     
24     cout << (D.empty () ? 'R' : 'D') << endl;
25 }

 

D. Leaving Auction

一些壕在拍卖会上竞拍,首先给出了大家既定的报价。一个人可能给出多次报价,但不会自己无故压自己。有Q次询问,每次一些人会离场,请把这些人的报价从序列中清除,问最后谁以什么价格赢得拍品。赢家即为最后一个报价的人,而价格为其最低的压过其他所有人(在场)的价格。如果有不理解,可以看样例。

 

解:首先处理出所有壕的最后一个报价,然后排序。每次询问可以暴力在序列中找到没有离场的最靠后报价的壕,那么他一定会赢得拍品,问题在于是什么价格。我们需要知道他需要压住的最后的另一位壕(如果存在),这个可以继续在序列中暴力向前扫描得到(因为总的离场人数是有限制的,而至多扫过的位置是离场人数级别的,所以复杂度有保证)。我们现在需要知道赢家壕在这位壕最后一次出价的位置之后,出的第一次价。如果事先维护了每个人的出价位置,直接在序列中二分即可,复杂度可以过。注意不要像我一样每次询问memset一遍awy数组,会TLE on test8。

 1 #include <bits/stdc++.h>
 2 
 3 #define fread_siz 1024
 4 
 5 inline int get_c(void)
 6 {
 7     static char buf[fread_siz];
 8     static char *head = buf + fread_siz;
 9     static char *tail = buf + fread_siz;
10 
11     if (head == tail)
12         fread(head = buf, 1, fread_siz, stdin);
13 
14     return *head++;
15 }
16 
17 inline int get_i(void)
18 {
19     register int ret = 0;
20     register int neg = false;
21     register int bit = get_c();
22 
23     for (; bit < 48; bit = get_c())
24         if (bit == '-')neg ^= true;
25 
26     for (; bit > 47; bit = get_c())
27         ret = ret * 10 + bit - 48;
28 
29     return neg ? -ret : ret;
30 }
31 
32 using namespace std;
33 
34 const int N = 200005;
35 
36 int n, m;
37 
38 int a[N], b[N];
39 
40 int tot;
41 int vis[N];
42 int lst[N];
43 int ord[N];
44 
45 int awy[N], q;
46 
47 vector<int> p[N];
48 
49 signed main(void)
50 {
51     n = get_i();
52     
53     for (int i = 1; i <= n; ++i)
54         a[i] = get_i(),
55         b[i] = get_i();
56         
57     for (int i = 1; i <= n; ++i)
58         p[a[i]].push_back(i);
59     
60     for (int i = n; i >= 1; --i)
61         if (!vis[a[i]])
62         {
63             vis[a[i]] = 1;
64             lst[a[i]] = i;
65             ord[++tot] = a[i];
66         }
67         
68     m = get_i();
69         
70     for (int i = 1; i <= m; ++i)
71     {
72         q = get_i();
73         for (int j = 1; j <= q; ++j)
74             awy[get_i()] = i;
75         int ans1 = 0, ans2 = 0, pos;
76         for (int j = 1; j <= tot && !ans1; ++j)
77             if (awy[ord[j]] != i)ans1 = ord[j], pos = j;
78         if (!ans1)
79             puts("0 0");
80         else
81         {
82             for (++pos; pos <= tot; ++pos)
83                 if (awy[ord[pos]] != i)break;
84             if (pos > tot)
85                 printf("%d %d\n", ans1, b[p[ans1][0]]);
86             else
87             {
88                 int lim = lst[ord[pos]];
89                 ans2 = *lower_bound(begin(p[ans1]), end(p[ans1]), lim);
90                 printf("%d %d\n", ans1, b[ans2]);
91             }
92         }
93     }
94 }

 

E题看起来好烦,无限期停更,大概不会填坑。

 

@Author: YouSiki

 

posted @ 2016-12-28 09:53  YouSiki  阅读(174)  评论(0编辑  收藏  举报