Codeforces Round #564 (div. 2)

Posted jhseng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #564 (div. 2)相关的知识,希望对你有一定的参考价值。

出题人全是thu的,时间也很友好(晚上八点)。赛前确定是中国场(数据结构场)无疑了。

结果开题之后发现根本不是这么一回事……虽然题目区分度挺高的。

题目链接:https://codeforces.com/contest/1173


A:

给定x,y,z三个数,代表有三堆人投票。一堆人投赞成票,一堆人投反对票,还有一堆人不确定投哪一票(不会弃权)。问最终结果是否可确定且为什么结果。

傻逼题。

技术图片
 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define dou double
 6 #define pb emplace_back
 7 #define mp make_pair
 8 #define sot(a,b) sort(a+1,a+1+b)
 9 #define rep1(i,a,b) for(int i=a;i<=b;++i)
10 #define rep0(i,a,b) for(int i=a;i<b;++i)
11 #define eps 1e-8
12 #define int_inf 0x3f3f3f3f
13 #define ll_inf 0x7f7f7f7f7f7f7f7f
14 #define lson curpos<<1
15 #define rson curpos<<1|1
16 /* namespace */
17 using namespace std;
18 /* header end */
19 
20 int x, y, z;
21 
22 int main() 
23     cin >> x >> y >> z;
24     int ans = x - y;
25     if (!ans && !z) puts("0");
26     else if (ans + z > 0 && ans - z > 0) puts("+");
27     else if (ans + z < 0 && ans - z < 0) puts("-");
28     else puts("?");
29     return 0;
30 
View Code

B:

给定n,问能构造多小的n*n矩形,使得能填入n个数字(从1到n,每个数字只出现一次)。而且对于第i个数字和第j个数字,满足abs(Xi-Xj)+abs(Yi-Yj)>=abs(i-j)。

没啥好说的,贪心就完事了。

技术图片
 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define dou double
 6 #define pb emplace_back
 7 #define mp make_pair
 8 #define sot(a,b) sort(a+1,a+1+b)
 9 #define rep1(i,a,b) for(int i=a;i<=b;++i)
10 #define rep0(i,a,b) for(int i=a;i<b;++i)
11 #define eps 1e-8
12 #define int_inf 0x3f3f3f3f
13 #define ll_inf 0x7f7f7f7f7f7f7f7f
14 #define lson curpos<<1
15 #define rson curpos<<1|1
16 /* namespace */
17 using namespace std;
18 /* header end */
19 
20 int n;
21 
22 int main() 
23     cin >> n;
24     cout << n / 2 + 1 << endl;
25     rep1(i, 1, n) cout << (i + 1) / 2 << " " << i / 2 + 1 << endl;
26     return 0;
27 
View Code

C:

有2n张牌,其中n张是空的,另外n张被1到n共n个数字标记。现在把这2n张牌打乱,并把n张牌叠起来放在桌上,另外n张放到手里。唯一操作:挑选手里的任意某张牌,放到牌堆底部,并把牌堆顶部的一张牌放到手中。

问最少要多少步使得牌堆里的牌都是被标记的牌,且自底向上有序(从大到小)。

贪心。看手中的牌是没有用的,不停判断牌堆中的牌状态即可。首先尝试不打空白牌能否完成,若不能,则必然是打出若干张空白牌之后就再也不打空白牌。

记录每张牌在牌堆的初始位置pos[i],若不在则为0。显然ans=max(pos[i]-i+1+n)。

因为我们的最终目标是把1-n叠在桌子上且有序。那么存在牌k,在经过操作后,使得[1,2,...,k]在牌堆的底端,并且接下来的操作只用标号为[k+1,....,n]的牌,将其依次插入牌堆的底端。这种情况下,答案就为pos[k]+1+n-k。其中pos[k]+1是将牌 k 插入牌堆底端需要的最小操作,n-k是将[k+1,....,n]依次插入牌堆的最小操作。

技术图片
 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define dou double
 6 #define pb emplace_back
 7 #define mp make_pair
 8 #define sot(pos,b) sort(pos+1,pos+1+b)
 9 #define rep1(i,pos,b) for(int i=pos;i<=b;++i)
10 #define rep0(i,pos,b) for(int i=pos;i<b;++i)
11 #define eps 1e-8
12 #define int_inf 0x3f3f3f3f
13 #define ll_inf 0x7f7f7f7f7f7f7f7f
14 #define lson curpos<<1
15 #define rson curpos<<1|1
16 /* namespace */
17 using namespace std;
18 /* header end */
19 
20 const int maxn = 2e5 + 10;
21 int n, pos[maxn], x, flag = 0;
22 
23 int main() 
24     scanf("%d", &n);
25     rep1(i, 1, n) scanf("%d", &x);
26     rep1(i, 1, n) 
27         scanf("%d", &x);
28         if (x > 0) pos[x] = i; // record sequence
29         if (x == 1) flag = 1; // start sign
30         else 
31             if (flag && x == flag + 1) flag++; // start and in increasing order
32             else flag = 0;
33         
34     
35     if (flag)   // special judge
36         int flag2 = 1;
37         rep1(i, flag + 1, n)
38         if (pos[i] >= i - flag) flag2 = 0;
39         if (flag2) 
40             return printf("%d\n", n - flag), 0;
41         
42     
43     int tmp = 0;
44     rep1(i, 1, n) tmp = max(tmp, pos[i] - i + 1);
45     printf("%d\n", n + tmp);
46     return 0;
47 
View Code

D:

给定一棵树,把树的所有节点放到圆上,使得所有的边不相交,问方案数。

盲猜了一个度数的结论就过了。因为方案数由点的度数决定,肯定是每条边的两个端点度数累乘。

技术图片
 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define dou double
 6 #define pb emplace_back
 7 #define mp make_pair
 8 #define sot(a,b) sort(a+1,a+1+b)
 9 #define rep1(i,a,b) for(int i=a;i<=b;++i)
10 #define rep0(i,a,b) for(int i=a;i<b;++i)
11 #define eps 1e-8
12 #define int_inf 0x3f3f3f3f
13 #define ll_inf 0x7f7f7f7f7f7f7f7f
14 #define lson curpos<<1
15 #define rson curpos<<1|1
16 /* namespace */
17 using namespace std;
18 /* header end */
19 
20 const int maxn = 2e5 + 10, mod = 998244353;
21 int n, a[maxn];
22 
23 int main() 
24     scanf("%d", &n);
25     ll ans = n;
26     rep1(i, 1, n - 1) 
27         int x, y; scanf("%d%d", &x, &y);
28         ans = ans * (++a[x]) % mod * (++a[y]) % mod;
29     
30     printf("%lld\n", ans);
31     return 0;
32 
View Code

E:

看了一眼,图相关的概率dp题,溜了。而且题解推导很复杂……

easy和hard都不会。

F:

一个有点玄妙的模拟题。给定一个n*n的矩阵,一个人只能从第一排或第一列的格子进入矩阵,且进入后前进方向不能改变。矩阵中有若干对传送门,走到传送门上会传送到另一个传送门并保持原来的方向继续走。

给定每个入口必须走到的出口(就是一个入口对应一个出口),问矩阵中的传送门该如何放置。

显然架设一对传送门后,所有经过这两个格点的路径都会受到影响,所以1~n枚举出口使得改变后的行列后移,变得有序。故传送门架设的顺序是依次往右下方向,因为遍历1出口时,需要经过其他行的路径经过传送门已经默认从1开始。自然不会破坏前面架设门的相对关系。

技术图片
 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define dou double
 6 #define pb emplace_back
 7 #define mp make_pair
 8 #define sot(a,b) sort(a+1,a+1+b)
 9 #define rep1(i,a,b) for(int i=a;i<=b;++i)
10 #define rep0(i,a,b) for(int i=a;i<b;++i)
11 #define eps 1e-8
12 #define int_inf 0x3f3f3f3f
13 #define ll_inf 0x7f7f7f7f7f7f7f7f
14 #define lson curpos<<1
15 #define rson curpos<<1|1
16 /* namespace */
17 using namespace std;
18 /* header end */
19 
20 const int maxn = 1e3 + 10;
21 int n, x, y, a[maxn], b[maxn], tot = 0;
22 struct Door 
23     int a, b, c, d;
24     Door() 
25     Door(int x, int y, int p, int q): a(x), b(y), c(p), d(q) 
26 ;
27 Door door[maxn];
28 
29 int main() 
30     scanf("%d", &n);
31     rep1(i, 1, n) scanf("%d", &a[i]);
32     rep1(i, 1, n) scanf("%d", &b[i]);
33     rep1(i, 1, n) 
34         if (a[i] == i && b[i] == i) continue;
35         rep1(j, i, n)
36         if (a[j] == i) 
37             swap(a[i], a[j]);
38             x = j;
39             break;
40         
41         rep1(j, i, n)
42         if (b[j] == i) 
43             swap(b[i], b[j]);
44             y = j;
45             break;
46         
47         door[++tot] = Door(x, i, i, y);
48     
49     printf("%d\n", tot);
50     rep1(i, 1, tot) printf("%d %d %d %d\n", door[i].a, door[i].b, door[i].c, door[i].d);
51     return 0;
52 
View Code

 

以上是关于Codeforces Round #564 (div. 2)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #564 (div. 2)

Codeforces Round 564 题解

Codeforces Round #436 E. Fire(背包dp+输出路径)

[ACM]Codeforces Round #534 (Div. 2)

Codeforces Round #726 (Div. 2) B. Bad Boy(贪心)

Codeforces Global Round 19