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 }
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 }
需要注意的地方:数组和变量的初始化以及其作用的范围!!!好好想清楚再写
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 }
用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 }
D题
思路:(还没有写代码,停电停水了)暂时的想法是计算每个数质因数的个数存下来,两两合并看是不是3的倍数这样子(待补