@Dmaxiya
2018-08-17T10:15:40.000000Z
字数 4260
阅读 967
Codeforces
Contests 链接:Codeforces Round #474 (Div. 1 + Div. 2)
过题数:2
排名:1055/8670
一个只包含有
a
,b
,c
三种字符的字符串,字符串分为三段,依次为连续的a
字符、连续的b
字符和连续的c
字符,其中c
字符的个数等于a
字符或者b
字符的个数,问给定的字符串是否满足以上条件。
输入为一个字符串 ,字符串中只包含
a
,b
,c
三种字符。
如果满足条件,则输出 ,否则输出 。
输入 |
---|
aaabccc |
输出 |
YES |
提示 |
c 字符的数量等于 a 字符的数量。 |
输入 |
---|
bbacc |
输出 |
NO |
提示 |
c 字符的数量等于 b 字符的数量,但是字符的顺序不正确。 |
输入 |
---|
aabc |
输出 |
YES |
提示 |
c 字符的数量等于 b 字符的数量。 |
按题意检查格式。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <algorithm>
#include <functional>
#include <iomanip>
using namespace std;
#define LL long long
const int maxn = 5000 + 100;
int Count[3];
char str[maxn];
int main() {
#ifdef LOCAL
freopen("test.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif // LOCAL
ios::sync_with_stdio(false);
while(scanf("%s", str) != EOF) {
bool flag = true;
int cnt = 0;
memset(Count, 0, sizeof(Count));
for(int i = 0; str[i]; ++i) {
int w = str[i] - 'a';
++Count[w];
if(cnt + 1 == w) {
++cnt;
} else if(cnt != w) {
flag = false;
break;
}
}
for(int i = 0; i < 3; ++i) {
if(Count[i] == 0) {
flag = false;
break;
}
}
if(!flag) {
printf("NO\n");
continue;
}
if(Count[2] == Count[0] || Count[1] == Count[2]) {
printf("YES\n");
} else {
printf("NO\n");
}
}
return 0;
}
给定两个长度为 的序列 和 ,定义两个序列的误差 ,可以对 序列进行 次操作,对 序列进行 次操作,每次操作可以选择序列中任意一个字符,将它的值加 或减 ,问两个序列分别经过 次和 次操作后的最小误差值。
第一行为三个整数 ,第二行为 个整数 ,第三行为 个整数 ,其中 。
输出修改后两个序列的最小误差值。
输入 |
---|
2 0 0 1 2 2 3 |
输出 |
2 |
提示 |
我们无法对两个序列做任何操作,因此 。 |
输入 |
---|
2 1 0 1 2 2 2 |
输出 |
0 |
提示 |
将 序列的第一个元素 ,就可以使两个序列的最小误差为 。 |
输入 |
---|
2 5 7 3 4 14 4 |
输出 |
1 |
提示 |
可以将 序列的第一个元素 得到 ,第二个序列的第一个元素 得到 , 序列仍然剩下一次操作,因此将第二个序列的任意一个元素 或者 ,得到两个序列的误差为 。 |
由于对其中一个序列的元素 或 等价于对另一个序列相同位置上的数字 或 ,因此相当于直接对其中一个序列做 次操作,每次贪心地对两个序列对应位置上绝对值最大的数字进行一次操作,往减小它们绝对值的方向操作,若序列中对应位置的最大绝对值为 ,则只能将绝对值 ,否则 。将对应位置的绝对值放入一个大顶堆中可以维护以上操作。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <algorithm>
#include <functional>
#include <iomanip>
using namespace std;
#define LL long long
const int maxn = 1000 + 100;
int n, k1, k2;
int a[maxn], b[maxn];
priority_queue<int> que;
int main() {
#ifdef LOCAL
freopen("test.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif // LOCAL
ios::sync_with_stdio(false);
while(scanf("%d%d%d", &n, &k1, &k2) != EOF) {
while(!que.empty()) {
que.pop();
}
for(int i = 0; i < n; ++i) {
scanf("%d", &a[i]);
}
for(int i = 0; i < n; ++i) {
scanf("%d", &b[i]);
que.push(abs(a[i] - b[i]));
}
k1 += k2;
for(int i = 0; i < k1; ++i) {
int tmp = que.top();
que.pop();
if(tmp != 0) {
--tmp;
} else {
++tmp;
}
que.push(tmp);
}
LL ans = 0;
while(!que.empty()) {
LL tmp = que.top();
que.pop();
ans += tmp * tmp;
}
printf("%I64d\n", ans);
}
return 0;
}
给定整数 和 ,构造一个长度为 的序列,这个序列总共有 个非空子序列,要求将所有非空子序列中的子序列最大值减最小值大于等于 的所有子序列删去后,剩下 个子序列。
输入包含两个整数 。
第一行输出一个整数 ,表示构造出来的序列长度,第二行为 个整数 ,如果无法构造出满足条件的序列,输出 。
输入 |
---|
10 5 |
输出 |
6 5 50 7 15 6 100 |
提示 |
将所有最大值减最小值大于等于 的子序列删除后,剩下的序列为:,还剩下 个子序列。 |
输入 |
---|
4 2 |
输出 |
4 10 100 1000 10000 |
提示 |
将所有最大值减最小值大于等于 的子序列删去后,就是每个数字独立成为一个子序列,个数为 。 |
将 分解成 ,其中 , 个相同的数字就可以得到 个非空子序列,对于每个 输出 个相同的数字,让任意两个不同的数字间隔为 ,就可以构造出合法的序列,不存在无法构造数列的情况。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <algorithm>
#include <functional>
#include <iomanip>
using namespace std;
#define LL long long
const int maxn = 70;
int cnt;
LL x, d;
LL two[maxn];
LL *it;
LL ans[maxn];
int main() {
#ifdef LOCAL
freopen("test.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif // LOCAL
ios::sync_with_stdio(false);
two[0] = 1;
for(int i = 1; i < 63; ++i) {
two[i] = two[i - 1] * 2;
}
for(int i = 0; i < 63; ++i) {
--two[i];
}
while(scanf("%I64d%I64d", &x, &d) != EOF) {
bool flag = false;
cnt = 0;
LL n = 0;
while(x != 0) {
it = upper_bound(two, two + 63, x);
--it;
x -= *it;
ans[cnt++] = it - two;
n += ans[cnt - 1];
}
printf("%I64d\n", n);
for(int i = 0; i < cnt; ++i) {
for(int j = 0; j < ans[i]; ++j) {
if(flag) {
printf(" ");
}
printf("%I64d", i * d + 1);
flag = true;
}
}
printf("\n");
}
return 0;
}