题解 Codeforces Round #806 (Div. 4)
Solved | Time | Penalty |
---|---|---|
7/7 | 83min | 224 |
太菜了。
A. YES or YES?
//A
#include <cstdio>
char s[10];
int t;
int main(){
scanf("%d", &t);
while(t--){
scanf("%s", s);
if((s[0] == 'Y' || s[0] == 'y') && (s[1] == 'E' || s[1] == 'e')
&& (s[2] == 'S' || s[2] == 's')){
puts("YES");
} else puts("NO");
}
return 0;
}
B. ICPC Balloons
开 c n t cnt cnt 数组记录每个字母是否为第一次出现。
//B
#include <cstdio>
#include <cstring>
int t, n;
char s[60], cnt[30];
int main(){
scanf("%d", &t);
while(t--){
memset(cnt, 0, sizeof(cnt));
scanf("%d", &n);
scanf("%s", s+1);
int ans= 0 ;
for(int i = 1; i <= n; ++ i){
if(cnt[s[i]-'A']){
ans += 1;
} else {
cnt[s[i]-'A'] = 1;
ans += 2;
}
}
printf("%d\n", ans);
}
}
C. Cypher
注意 U
和 D
反着来。
//C
#include <cstdio>
const int N = 110;
int t, n, a[N], b;
char s[N];
int main(){
scanf("%d", &t);
while(t--){
scanf("%d", &n);
for(int i = 1; i <= n; ++ i){
scanf("%d", &a[i]);
}
for(int i = 1; i <= n; ++ i){
scanf("%d", &b);
scanf("%s", s+1);
for(int j = 1; j <= b; ++ j){
if(s[j] == 'D'){
if(a[i] == 9){
a[i] = 0;
} else ++ a[i];
} else {
if(a[i] == 0){
a[i] = 9;
} else -- a[i];
}
}
}
for(int i = 1; i <= n; ++ i){
printf("%d ", a[i]);
}
puts("");
}
return 0;
}
D. Double Strings
暴力,开 map 记录每个串出没出现过。先读完然后再判断。
//D
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int t, n;
string s[N];
map<string, int> mp;
int main(){
scanf("%d", &t);
while(t--){
scanf("%d", &n);
mp.clear();
for(int i = 1; i <= n; ++ i){
cin >> s[i];
mp[s[i]] = 1;
}
for(int i = 1; i <= n; ++ i){
bool flg = false;
int k = s[i].size();
for(int j = 1; j < k; ++ j){
string a = s[i].substr(0, j);
string b = s[i].substr(j, k);
if(mp[a] && mp[b]) flg = true;
}
if(flg) putchar('1');
else putchar('0');
}
puts("");
}
}
E. Mirror Grid
四个对应点的位置分别是 ( i , j ) , ( j , n − i + 1 ) , ( n − i + 1 , n − j + 1 ) , ( n − j + 1 , i ) (i,j),(j,n-i+1),(n-i+1,n-j+1),(n-j+1,i) (i,j),(j,n−i+1),(n−i+1,n−j+1),(n−j+1,i)。
判一下里面 1
少还是 0
少就行。
我也不知道为什么我的程序里答案要 / 4 /4 /4。
//E
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 110;
int t, n;
char a[N][N];
int main(){
scanf("%d", &t);
while(t--){
scanf("%d", &n);
int ans = 0;
for(int i = 1; i <= n; ++ i){
scanf("%s", a[i] + 1);
}
for(int i = 1; i <= n; ++ i){
for(int j = 1; j <= n; ++ j){
int cnt = 0;
if(a[i][j] == '1'){
++ cnt;
a[i][j] = '1';
}
if(a[j][n-i+1] == '1'){
++ cnt;
a[j][n-i+1] = '1';
}
if(a[n-i+1][n-j+1] == '1'){
++ cnt;
a[n-i+1][n-j+1] = '1';
}
if(a[n-j+1][i] == '1'){
++ cnt;
a[n-j+1][i] = '1';
}
if(cnt){
ans += min(cnt, 4-cnt);
}
}
}
printf("%d\n", ans / 4);
}
}
F. Yet Another Problem About Pairs Satisfying an Inequality
设 f i = [ a i < i ] f_i = [a_i<i] fi=[ai<i]。
遍历数组,若发现 a i < i a_i<i ai<i,则答案累加上 ∑ j = 1 i − 1 f j \sum_{j=1}^{i-1}f_j ∑j=1i−1fj。
程序里使用树状数组维护了 f f f。
//F
#include <cstdio>
const int N = 2e5 + 10;
int t, n, a[N];
#define lb(x) (x&-x)
long long bit[N];
void add(int x, long long v){
while(x <= n){
bit[x] += v;
x += lb(x);
}
}
long long ask(int r){
long long ans = 0;
while(r){
ans += bit[r];
r -= lb(r);
}
return ans;
}
int main(){
scanf("%d", &t);
while(t--){
scanf("%d", &n);
long long ans = 0;
for(int i = 1; i <= n; ++ i){
scanf("%d", &a[i]);
if(a[i] < i){
add(i, 1);
if(a[i]) ans += ask(a[i]-1);
// printf("%d %d\n", i, ask(a[i]));
}
}
printf("%lld\n", ans);
for(int i = 1; i <= n; ++ i){
bit[i] = 0;
}
}
return 0;
}
G. Good Key, Bad Key
可以很快的写出一个 O ( n 2 ) O(n^2) O(n2) 的 dp,但是没啥用。
发现性质:最优解必定是用好钥匙开前面多少个箱,其它用坏钥匙开。即不存在一个使用好钥匙开的箱子,前面有箱子用坏钥匙开。
然后计算出一个 g g g 数组, g i g_i gi 表示第 i ∼ n i\sim n i∼n 号箱子全都用坏钥匙开能获得的金币数。答案即为:
max i = 0 n ( ∑ j = 1 i a j + g i + 1 ) \max\limits_{i=0}^n \left(\sum_{j=1}^i a_j + g_{i+1}\right) i=0maxn(j=1∑iaj+gi+1)
//G
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
int t, n;
ll k, a[N], g[N];
int main(){
scanf("%d", &t);
while(t--){
scanf("%d%lld", &n, &k);
for(int i = 1; i <= n; ++ i){
scanf("%lld", &a[i]);
ll p = a[i];
for(int j = i; j; -- j){
p >>= 1;
if(!p) break;
g[j] += p;
}
}
ll ans = g[1], sum = 0;
for(int i = 1; i <= n; ++ i){
sum += a[i] - k;
// printf("%lld %lld %lld\n", ans, sum, g[i]);
ans = max(ans, sum + g[i+1]);
}
memset(g, 0, sizeof(g));
printf("%lld\n", ans);
}
return 0;
}
后记:比赛结束后突然发现 G 用了 memset
,应该没啥问题吧。