CodeForces Round #298 Div.2

A. Exam

果然,并没有3分钟秒掉水题的能力,=_=||

n <= 4的时候特判。n >= 5的时候将奇数和偶数分开输出即可保证相邻的两数不处在相邻的位置。

 1 #include <bits/stdc++.h>

 2 using namespace std;

 3 

 4 int main()

 5 {

 6     int n;

 7     cin >> n;

 8     if(n <= 2) puts("1\n1");

 9     else if(n == 3) puts("2\n1 3\n");

10     else if(n == 4) puts("4\n2 4 1 3\n");

11     else

12     {

13         printf("%d\n", n);

14         vector<int> ans;

15         for(int i = 1; i <= n; i+=2) ans.push_back(i);

16         for(int i = 2; i <= n; i+=2) ans.push_back(i);

17         int sz = ans.size();

18         for(int i = 0; i < sz; i++)

19         {

20             if(i) printf(" ");

21             printf("%d", ans[i]);

22         }

23         puts("");

24     }

25 

26     return 0;

27 }
代码君

 

B. Covered Path (贪心)

第一秒的速度为v1,第t秒的速度为v2.

因为d很小,对于中间的每一秒,从d到-d枚举下一秒速度的变化量,只要保证在剩下的时间内能够减速到v2,这个速度变化量就是合法的。

 1 #include <bits/stdc++.h>

 2 

 3 using namespace std;

 4 

 5 int main()

 6 {

 7     int v1, v2, t, d;

 8     cin >> v1 >> v2 >> t >> d;

 9 

10     vector<int> v; v.push_back(v1);

11     int now = v1;   //当前车速

12     for(int i = 2; i <= t-1; i++)

13     {

14         int dd;

15         for(dd = d; dd >= -d; dd--)

16             if(now + dd <= (t - i) * d + v2)

17                 break;

18         now += dd;

19         v.push_back(now);

20     }

21     v.push_back(v2);

22     int s = 0;

23     for(int i = 0; i < v.size(); i++) s += v[i];

24     printf("%d\n", s);

25 

26     return 0;

27 }
代码君

 

C. Polycarpus' Dice

这n个骰子的点数之和为A。

对于某一个骰子,这个骰子的点数不能过大,因为这样可能使得其他骰子点数出现0的情况。

这个骰子点数也不能过小,因为可能剩余的骰子全部置为最大点也不能使总点数为A。

从这两个方面考虑,就能计算出每个骰子不可能出现的点数有多少种。

 1 #include <iostream>

 2 #include <bits/stdc++.h>

 3 using namespace std;

 4 

 5 typedef long long LL;

 6 

 7 const int maxn = 200000 + 10;

 8 LL a[maxn];

 9 

10 int main()

11 {

12     LL n, A, s = 0;

13     cin >> n >> A;

14     for(int i = 0; i < n; i++) { scanf("%I64d", &a[i]); s += a[i]; }

15     for(int i = 0; i < n; i++)

16     {

17         if(i) printf(" ");

18         LL ans = 0;

19         ans += max(0LL, a[i] + n - 1 - A);

20         LL ss = s - a[i];

21         ans += max(0LL, A - ss - 1);

22         printf("%I64d", ans);

23     }

24     puts("");

25 

26     return 0;

27 }
代码君

 

D. Handshakes (贪心 模拟 链表)

要和k个人握手的人可能有多个,所以我们用一个链表把他们连接起来。

以第二个样例为例:

9
0 2 3 4 1 1 0 2 2

和0个人握手的人有:1 7

和1个人握手的人有:5 6

和2个人握手的人有:2 8 9

和3个人握手的人有:3

和4个人握手的人有:4

这样我们可以先使7 6 9 3 4入场,然后没有人要和5个人握手,但是如果这五个人有三个人结成一队的话,那么8入场会和两个人握手。

这样还剩3个人,发现没有人要和3个人握手,于是这3个人结成一队。

1 5 2依次入场。

 1 #include <cstdio>

 2 

 3 const int maxn = 200000 + 10;

 4 

 5 int repr[maxn], next[maxn], a[maxn];

 6 

 7 int main()

 8 {

 9     //freopen("in.txt", "r", stdin);

10 

11     int n; scanf("%d", &n);

12     for(int id = 1; id <= n; id++)

13     {//id为和x个人握手的链表的编号

14         int x; scanf("%d", &x);

15         next[id] = repr[x]; //将id插入和x个人握手的链表的头部

16         repr[x] = id;   //修改头指针

17     }

18 

19     int p = 0, now = 0;

20     while(repr[now])

21     {

22         a[p++] = repr[now];

23         repr[now] = next[repr[now]];    //这个人已入场,修改头指针,相当于将其从链表中删除

24         now++;

25         while(repr[now] == 0 && now >= 3) now -= 3;

26     }

27     if(p == n)

28     {

29         puts("Possible");

30         for(int i = 0; i < n-1; i++) printf("%d ", a[i]);

31         printf("%d\n", a[n-1]);

32     }

33     else puts("Impossible");

34 

35     return 0;

36 }
代码君

 

你可能感兴趣的:(codeforces)