Codeforces Round #596 (Div. 2) ABCD题

Posted moomight

tags:

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

A题

技术图片

样例

技术图片

 

 思路:分情况进行讨论,a比b小1,a和b相等,a为9 b为1的情况

代码如下:

技术图片
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <string.h>
 6 #include <vector>
 7  
 8 using namespace std;
 9  
10 int main(){
11     int a, b;
12     scanf("%d %d", &a, &b);
13     if(a == b){
14         printf("%d %d", a * 10 + 1, b * 10 + 2);
15     }
16     else if(b - a == 1){
17         printf("%d %d", a * 10 + 9, b * 10);
18     }
19     else if(a == 9 && b == 1){
20         printf("99 100");
21     }
22     else {
23         printf("%d", -1);
24     }
25     return 0;
26 }
View Code

 

B1 

技术图片

 

 样例

技术图片

 

 思路:看到数据范围没想太多直接暴力了……用双指针写的,然后发现双指针不太熟了(太久没用

    枚举每一个区间计数

代码如下:

技术图片
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <vector>
 6  
 7 using namespace std;
 8 const int N = 105;
 9 int a[N], vis[N];
10  
11 int main(){
12     int q;
13  
14     scanf("%d", &q);
15     int n, k, d;
16     while(scanf("%d %d %d", &n, &k, &d) != EOF){
17         memset(a, 0, sizeof a);
18         int minn = 0x3f3f3f3f;
19         for(int i = 0; i < n; i ++ )
20             scanf("%d", &a[i]);
21         int ans = 0;
22         for(int i = 0, j = i; i < n && i + d - 1 < n; j ++ ){
23             if(vis[a[j]] == 0) ans ++ ;
24             vis[a[j]] ++ ;
25             if(j == i + d - 1){
26                 i ++ ;
27                 j = i - 1;
28                 memset(vis, 0, sizeof vis);
29                 minn = min(minn, ans);
30                 ans = 0;
31             }
32         }
33         printf("%d
", minn);
34     }
35     return 0;
36 }
View Code

需要注意的地方:数组和变量的初始化以及其作用的范围!!!好好想清楚再写

 

B2

题目同上,范围改变了

技术图片

 

 思路:再用上面的方法肯定不行了,于是我们使用滑动窗口

    比赛的时候没想太多直接用的数组然后memset,tle了,赛后再交一边发现又过了

      由于n = 2e5, k = 1e6,两者相乘已经超过2s了

   不知道是比赛时把时间乘了一个常数还是比赛时评测机太卡了,总之这样做虽然过了但是是不严谨的。

   正确的做法是使用unordered_map来存每个数出现的次数

数组的代码如下:

技术图片
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <vector>
 6  
 7 using namespace std;
 8 const int N = 1e6 + 5;
 9 const int M = 2e5 + 5;
10 int a[M], vis[N];
11  
12 int main(){
13     int q;
14     scanf("%d", &q);
15     int n, k, d;
16     while(scanf("%d %d %d", &n, &k, &d) != EOF){
17         memset(vis, 0, sizeof vis);
18         int minn = 0x3f3f3f3f;
19         for(int i = 0; i < n; i ++ )
20             scanf("%d", &a[i]);
21         int ans = 0;
22         int cnt = 0;
23         for(int i = 0, j = 0; i < n && i + d - 1 < n; j ++ ){
24             if(i == 0){
25                 if(vis[a[j]] == 0) ans ++ ;
26                 vis[a[j]] ++ ;
27                 if(i + d - 1 == j){
28                     minn = min(minn, ans);
29                     vis[a[i]] -- ;
30                     cnt = a[i];
31                     i ++ ;
32                 }
33             }
34             else {
35                 if(a[j] == cnt) {
36                     vis[cnt] ++ ;
37                     vis[a[i]] --;
38                     cnt = a[i];
39                     i ++ ;
40                 }
41                 else{
42                     if(vis[cnt] == 0){
43                         ans -- ;
44                         if(vis[a[j]] == 0) ans ++ ;
45                         vis[a[j]] ++ ;
46                         minn = min(minn, ans);
47                         vis[a[i]] -- ;
48                         cnt = a[i];
49                         i ++ ;
50                     }
51                     else{
52                         if(vis[a[j]] == 0) ans ++ ;
53                         vis[a[j]] ++ ;
54                         minn = min(minn, ans);
55                         vis[a[i]] -- ;
56                         cnt = a[i];
57                         i ++ ;
58                     }
59                 }
60             }
61         }
62         printf("%d
", minn);
63     }
64     return 0;
65 }
View Code

用map的代码没有写……待补

 

C题

技术图片

 

 样例:

技术图片

 

 思路:设置一个flag, 计算n - p * flag 的值,并用popcount求该值二进制中1的个数。

   (就是把右边加的flag个p减到左边去,然后算二进制进行判断)

代码如下:

技术图片
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <algorithm>
 5 #include <cstring>
 6 #include <vector>
 7  
 8 using namespace std;
 9  
10 int main(){
11     int n, p;
12     int flag = 1;
13     scanf("%d %d", &n, &p);
14     int f = 0;
15     while(true){
16         if(p == 0){
17             printf("%d", __builtin_popcount(n));
18             break;
19         }
20         int x = n - p * flag;
21         if(x < flag) {
22             f = -1;
23             break;
24         }
25         //printf("%d %d
", x, __builtin_popcount(x));
26         if(__builtin_popcount(n - p * flag) <= flag){
27             f = 1;
28             break;
29         }
30         flag ++ ;
31     }
32     if(f == 1) printf("%d", flag);
33     else if(f == -1) printf("-1");
34 }
View Code

 

D题

技术图片

 

 思路:(还没有写代码,停电停水了)暂时的想法是计算每个数质因数的个数存下来,两两合并看是不是3的倍数这样子(待补

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

Codeforces Round #596 (Div. 2, based on Technocup 2020 Elimination Round 2)

Codeforces Round #596 (Div. 2) ABCD题

Codeforces Round 596 题解

Codeforces Round #596 div2 D. Power Products

Codeforces Round #596 Div1 A~E题解

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