Codeforces Round #695 (Div. 2) 2021.01.08
https://codeforces.com/contest/1467
A
有n个灯,每个灯一开始都是0,每一秒钟每个灯显示的数字会往上一位,但是由于每个灯只能显示单个数位,所以从9增大时得到的是0.在任意时刻,你可以指定唯一一个灯被停止,下一秒后,他相邻的两个灯也会进入暂停状态.问,在合理的设置一个灯被停止之后,所有灯停止,显示的最大的数是多少.
注:先增加数位,后停止.
#include <bits/stdc++.h> using namespace std; void handing(int n) { int res = 0; if (n==1) cout<<9; else if (n==2) cout<<98; else { cout<<989; for (int i=4; i<=n; ++i) { cout<<(res++)%10; } } } int main() { int t; int n; scanf("%d", &t); while (t--) { scanf("%d", &n); handing(n); cout<<"\n"; } return 0; }
B
题目大意
对于任意一个j∈[2,n−1]来说如果他满足aj严格小于身边两个元素,或者aj严格大于身边两个元素,分别称为波谷和波峰.令一个数组a的牛逼值是整个数组中波谷和波峰的数量之和,现在你可以修改数组中任意一个元素,使他变成任意一个值,问这个数组最小的牛逼值是多少.
数据范围:
1≤n≤3∗105
1≤ai≤109
思路
首先肯定统计一下原来数组的波谷波峰的个数,随便捣鼓一下就算完了,记为sum.
考虑如何做这个修改:这是一个非常显然的套路,因为只能修改一个数,所以直接枚举每一个数被修改的情况即可,进而可以想到,加入要修改ai那么最好的修改策略就是让ai=ai−1或者ai=ai+1因为这样简单又能消灭波峰和波谷,之后我们直接枚举每一位被修改的情况就可以了.
首先从sum里面挖掉与i相关的,构成三元组的部分,其次把ai修改,统计新的三元组的贡献,枚举获得最小值即可.
#include<bits/stdc++.h> using namespace std; #define N 300010 int a[N],n; int check(int index) { if(index==1||index==n) return 0; if(a[index]>a[index-1]&&a[index]>a[index+1]) return 1; if(a[index]<a[index-1]&&a[index]<a[index+1]) return 1; return 0; } int main() { int t; cin>>t; while(t--) { int high=0,sum=0; cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=2;i<n;i++) { if(check(i)) sum++; } for(int i=2;i<n;i++) { int f=check(i)+check(i-1)+check(i+1); int temp=a[i]; a[i]=a[i-1]; int x=check(i+1); high=max(high,f-x); a[i]=a[i+1]; x=check(i-1); high=max(high,f-x); a[i]=temp; } cout<<sum-high<<endl; } }
C
#include<bits/stdc++.h> using namespace std; LL mn[3] = { INF,INF,INF }, sum[3], t; LL n[3]; int main() { scanf("%d%d%d", &n[0], &n[1], &n[2]); for (int i = 0; i < 3; ++i) { while (n[i]--) { scanf("%lld", &t); sum[i] += t; mn[i] = min(mn[i], t); } } printf("%lld", sum[0] + sum[1] + sum[2] - 2 * min({ mn[0] + mn[1],mn[1] + mn[2],mn[0] + mn[2],sum[0],sum[1],sum[2] })); }

浙公网安备 33010602011771号