Codeforces Round #695(Div.2)【ABC题解】
这题的解法就是找规律,输出98901234567890123456789...
下面是代码
#include <bits/stdc++.h>
using namespace std;
void solve(int n) {
if (n == 1) cout << 9;
else if (n == 2) cout << 98;
else if (n == 3) cout << 989;
else {
n -= 3;
int tmp = n / 10;
cout << 989;
while (tmp -- ) cout << "0123456789";
int cnt = n % 10, now = 0;
while (cnt -- ) cout << now ++ ;
}
cout << endl;
}
int main () {
int t; cin >> t;
while (t -- ) {
int n; cin >> n;
solve(n);
}
return 0;
}
这题可以直接暴力模拟,扫一遍数组,如果存在波峰或者波谷的,那么我们就模拟
例如...2 3 6 5 3 ...这样一个数组,6就是一个波峰的位置,假如我们想要消除它,可以将6变成5
如果对上面那个数组稍加改造,例如...2 4 6 3 2...就要将6变成4,我们可以试着推广到一般性
对于一个波峰,即...a[i-1] a[i] a[i+1]...可以通过将a[i]变成a[i-1]或者a[i+1]来消除这个峰,波谷同理
考虑到连续峰有机会可以互相抵消,所以我们都试一试,取最优解
#include <bits/stdc++.h>
using namespace std;
const int N = 3e5 + 10;
int a[N];
int get(int i) {
if (a[i] > a[i - 1] && a[i] > a[i + 1] || a[i] < a[i - 1] && a[i] < a[i + 1]) return 1;//找到了波峰或者波谷
return 0;
}
int main () {
int t; cin >> t;
while (t -- ) {
int n; cin >> n;
int ans = 0, ma = 0;
for (int i = 1; i <= n; i ++ ) cin >> a[i];
a[0] = a[1], a[n + 1] = a[n];//防止之后的寻找波峰波谷时候错误,因为边界不是波峰或者波谷
for (int i = 2; i < n; i ++ ) {
if (get(i)) {//找到了波峰/波谷
ans ++ ;
int tmp = a[i];//拿数字储存一下,因为等会要变a[i]
int origin = get(i - 1) + get(i) + get(i + 1);//这是原来的时候,连续波峰/谷的情况
a[i] = a[i + 1];
int now_1 = get(i - 1) + get(i) + get(i + 1);//这是修改之后连续波峰/谷的情况
a[i] = a[i - 1];
int now_2 = get(i - 1) + get(i) + get(i + 1);//这是修改之后连续波峰/谷的情况
a[i] = tmp;
ma = max(ma, origin - min(now_1, now_2));//ma的含义是,通过修改一个数组值,最多能少几个波峰/谷
}
}
cout << ans - ma << endl;
}
return 0;
}
这题的内容是贪心,但是比较难想,我通过别人的AC代码加上和群友讨论得出了这么个方法
核心思想就是可以通过借助数组中的一个数,将另外两个数组中的数加到一起并存放到这两个数组中的其中一个去
通过这个,我们可以推出可以通过两个数组中的各一个数字,或者一个数组,将所有的数字并到一个数组中去
这个可以自己模拟一下来理解
方法知道了,接下来就是找最优解
我们还要知道,题目的意思是,从三个数组中的一个取出一个b,然后从另一个取出一个a,然后将a-b放到取出a的那个数组中去
也就是说,假设原来的三个数组之和是sum,也就是说一波操作之后,sum会减去2b,变成sum-2b
我们需要让最后的数字尽可能大,因此减的就要尽可能小
假设我们有数组a,b,c,我们可以通过a数组中的最小值a1,将b和c加起来放到b中,假设sum是原来三个数组之和,最后sum变成了sum-2a1
因此我们选的那个最小值得是三个数组中最小的
也就是说我们上文中提到的两个数组中的各一个数字或者一个数组得取最小才行
sum[i]指第i的数组的和
也就是说答案应该是sum[3] + sum[2] + sum[1] - 2min(sum[1], mi[1] + mi[2])
#include <bits/stdc++.h>
using namespace std;
long long n[4], sum[4], mi[4];
int main () {
cin >> n[1] >> n[2] >> n[3];
mi[1] = mi[2] = mi[3] = INT_MAX;//每个数组中的最小值
for (int i = 1; i <= 3; i ++ ) {
long long x;
while (n[i] -- && cin >> x) {
sum[i] += x; mi[i] = min(mi[i], x);
}
}
sort(sum + 1, sum + 4), sort(mi + 1, mi + 4);//排序求出最小值
cout << sum[3] + sum[2] + sum[1] - 2 * min(sum[1], mi[1] + mi[2]) << endl;
return 0;
}