比赛链接:https://atcoder.jp/contests/abc043
A - Children and Candies (ABC Edit)
题目大意:
求 (1+2+ldots+n)。
答案:(frac{n cdot (n+1)}{2})。
示例程序:
#include <bits/stdc++.h>
using namespace std;
int n;
int main() {
cin >> n;
cout << n * (n + 1) / 2;
return 0;
}
B - Unhappy Hacking (ABC Edit)
题目大意:
模拟一个按键的过程,这个键盘只有 '0'、'1' 和退格键('B'),给你一个敲键盘的指令,求最终的输出结果。
解题思路:
开一个数组模拟一下这个过程即可。
示例程序:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 20;
char s[maxn], ans[maxn];
int n;
int main() {
cin >> s;
for (int i = 0; s[i]; i ++) {
if (s[i] != 'B') ans[n++] = s[i];
else if (n) n --;
}
ans[n] = 0;
cout << ans << endl;
return 0;
}
C - Be Together
题目大意:
把 (n) 个整数都变成一个相同的数,将 (x) 转成 (y) 的代价为 ((x-y)^2)。求最小总代价。
解题思路:
如果数据量放大一点的话感觉可以用三分做
最终变成的数肯定在最小值和最大值之间,所以从最小值到最大值枚举一下答案即可。
示例程序:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 110;
int n, a[maxn], ans = INT_MAX;
int cal(int x) {
int res = 0;
for (int i = 0; i < n; i ++) res += (x - a[i]) * (x - a[i]);
return res;
}
int main() {
cin >> n;
for (int i = 0; i < n; i ++) cin >> a[i];
sort(a, a+n);
for (int i = a[0]; i <= a[n-1]; i ++) ans = min(ans, cal(i));
cout << ans << endl;
return 0;
}
D - Unbalanced
题目大意:
给你一个字符串 (s),请你求出它的一个子串,这个子串中同一个字符出现次数大于一半,输出任意一个满足条件的子串的起止位置。
解题思路:
我做这道题目的时候,想到的方法有点类似于 “最大子段和” 的 DP/贪心 思想。
就是对于任意一个字符 (c),字符串中等于 (c) 的权值等于 (1),其它字符权值等于 (-1),然后 (f[i]) 表示到 (s[i]) 为止的最大子段和,如果 (s[i]=c) 且 (f[i] gt 0) 且之前出现过 (c) 且中间没有断过(断过指某个 (f[j] lt 0) 的情况出现),则OK。
示例代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
char s[maxn];
int f[maxn], st, ed;
bool _check(char c) {
int cnt = 0;
bool ok = false;
for (int i = 1; s[i]; i ++) {
if (s[i] != c) {
if (f[i-1] > 0) f[i] = f[i-1] - 1;
else f[i] = 0, ok = false;
}
else {
if (f[i-1] >= 0 && ok) {
ed = i;
return true;
}
f[i] = 1, st = i, ok = true;
}
}
return false;
}
bool check() {
for (char c = 'a'; c <= 'z'; c ++) if (_check(c)) return true;
return false;
}
int main() {
cin >> s+1;
if (check()) cout << st << " " << ed << endl;
else puts("-1 -1");
return 0;
}