Codeforces Round #564 比赛总结

本文深入解析了CodeForces平台上四道经典算法题目的解题思路与代码实现,包括A.NauuoandVotes、B.NauuoandChess、C.NauuoandCards以及D.NauuoandCircle,涵盖投票策略、棋盘布局、卡片操作和树状结构的复杂算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这次是中国大佬出题,结果被虐惨了。

A. Nauuo and Votes

 1 #include<bits/stdc++.h>
 2 #define Rint register int
 3 using namespace std;
 4 typedef long long LL;
 5 int x, y, z;
 6 int main(){
 7     scanf("%d%d%d", &x, &y, &z);
 8     if(x + z - y < 0) puts("-");
 9     else if(x - y - z > 0) puts("+");
10     else if(x == y && z == 0) puts("0");
11     else puts("?");
12 }
CF1173A

B. Nauuo and Chess

 1 #include<bits/stdc++.h>
 2 #define Rint register int
 3 using namespace std;
 4 typedef long long LL;
 5 int n, m;
 6 int main(){
 7     scanf("%d", &n);
 8     m = (n >> 1) + 1;
 9     printf("%d\n", m);
10     for(Rint i = 1;i <= m;i ++)
11         printf("%d %d\n", 1, i);
12     for(Rint i = 2;i <= n - m + 1;i ++)
13         printf("%d %d\n", i, m);
14 }
CF1173B

C. Nauuo and Cards

(乱搞能力有待加强)

首先我们分两种情况,手上会拿到1和不会拿到1.

对于后者,初始的时候1要在队列中并且它之后是$2,3,4,\ldots,i-1$,然后之后可以把$i,i+1,\ldots,n$放进队列中,需要$n-i+1$步。

对于前者,用$p_i$表示$i$初始在队列的位置,不在则为0,也就是至少$p_i$步之后可以拿到这张牌,将$i$从$p_i$这个位置转移到$i$需要$p_i-i+n+1$步,取最大值即为答案。

感性理解:首先如果后者可以那么后者一定比前者更优,对于前者,我们可以通过先扔一些空牌来拿到足够的牌,然后依次把$1,2,3,\ldots n$扔出去,不会更优。

 1 #include<bits/stdc++.h>
 2 #define Rint register int
 3 using namespace std;
 4 const int N = 200003;
 5 int n, a[N], b[N], p[N], ans;
 6 int main(){
 7     scanf("%d", &n);
 8     for(Rint i = 1;i <= n;i ++){
 9         scanf("%d", a + i); p[a[i]] = 0;
10     }
11     for(Rint i = 1;i <= n;i ++){
12         scanf("%d", b + i); p[b[i]] = i;
13     }
14     if(p[1]){
15         int i, j;
16         for(i = 2;p[i] == p[1] + i - 1;i ++);
17         if(p[i - 1] == n){
18             for(j = i;j <= n && p[j] <= j - i;j ++); 
19             if(j > n){
20                 printf("%d\n", n - i + 1);
21                 return 0;
22             }
23         }
24     }
25     for(Rint i = 1;i <= n;i ++) ans = max(ans, p[i] - i + n + 1);
26     printf("%d", ans);
27 }
CF1172A

D. Nauuo and Circle

我们发现,对于节点$x$的子树,它在排列中必定是一段连续的区间,否则就会跟其他的子树导致边相交。

这个排列是可以旋转的,所以钦定$p_1=1$。

设节点$i$的度数为$deg_i$。

我们使用捆绑法,将必须要连在一起的先捆绑起来,之后再对子树进行递归。

例如样例1,2就是这样的:

$$(1,(2,4),3)$$

$$(1,2,3,4)$$

(同个括号里的表示必须要连续)

对于节点$1$,我们可以任意排列它的$deg_1$棵子树,对于其他节点$x$,我们可以排列它自己和$deg_x-1$棵子树

$$Ans=n\prod_{i=1}^ndeg_i!$$

 1 #include<bits/stdc++.h>
 2 #define Rint register int
 3 using namespace std;
 4 typedef long long LL;
 5 const int N = 200003, mod = 998244353;
 6 int n, fac[N], deg[N], ans;
 7 int main(){
 8     scanf("%d", &n);
 9     for(Rint i = 1;i < n;i ++){
10         int a, b;
11         scanf("%d%d", &a, &b);
12         deg[a] ++; deg[b] ++;
13     }
14     fac[0] = ans = 1;
15     for(Rint i = 1;i <= n;i ++) fac[i] = (LL) i * fac[i - 1] % mod;
16     for(Rint i = 1;i <= n;i ++) ans = (LL) ans * fac[deg[i]] % mod;
17     printf("%d\n", (LL) ans * n % mod);
18 }
CF1137D

 

转载于:https://www.cnblogs.com/AThousandMoons/p/10989460.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值