codeforces #634(div3) A-E题解
Posted honey-cat
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces #634(div3) A-E题解相关的知识,希望对你有一定的参考价值。
A. Candies and Two Sisters
-
将糖果分为a,b两份,且a < b,a + b = n
-
根据题中条件分析得出糖果数n <= 2 无解
-
n为偶数 res = n / 2 - 1;奇数 res = n / 2
-
res = (n - 1)/2
cin >> t;
while(t--){
cin >> n;
cout << (n - 1) / 2;
}
B. Construct the String
- 构造一个长为n,且满足所有长为a的子串中只有b个不同的字母
- 先输出有b个不同的字母的b串,n字符串即为n // b 倍的b串
cin >> t;
while(t--){
cin >> n >> a >> b;
for(int i = 0; i < n; i++) cout << char(‘a‘ + i % b);
cout << endl;
}
C. Two Teams Composing
-
有一批学生,每个学生只拥有一个技能,现将学生分为人数相等的两组,一组中的学生只拥有同种技能,另外一组中的学生只拥有不同的技能,问每组的最大人数。
-
最大可能的结果为总人数的一半
-
使用book数组记录使用i技能的人数,idx记录技能的数量
-
寻找使用相同技能最多的人数mx,结果 <= mx
-
分情况讨论 1. n == 1,n == idx特殊情况优先讨论 2.mx 与 idx 相等时存在一个元素的交集 res = mx - 1;
mx与idx不等时,res = min(mx,idx);
#define endl ‘-n‘
using namespace std;
const int kN = 2 * 1e5 + 5;
int t,n,x,idx,arr[kN],mx,res;
//int book[kN];//map要比直接开数组快,但更耗内存
map<int,int> book;
int main(void){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin >> t;
while(t--){
idx = mx = 0;
book.clear();
cin >> n;
//memset(book,0,sizeof(book));
for(int i = 0; i < n; i++){
cin >> x;
if(!book[x]) book[x] = 1,arr[idx++] = x;
else ++book[x];
}
//idx 不同技能数 寻找最大相同技能数
for(int i = 0; i < idx; i++){
if(book[arr[i]] > mx) mx = book[arr[i]];
}
if(mx == idx) cout << mx - 1 << endl;//存在一个元素的交集
else cout << (mx > idx ? idx : mx)<< endl;
}
return 0;
}
D. Anti-Sudoku
- 每组测试样例为9x9的矩阵
- 输出结果满足每行,每列都有两个相同的数字
- 每一行,每一列的数字均值只出现一次,将所有的2换为1...等等
cin >> t;
while(t--){
for(int i = 0; i < 9; i++){
cin >> s;
for(auto x : s){
if(x == ‘2‘) cout << ‘1‘;
else cout << x;
}
cout << endl;
}
}
E1. Three Blocks Palindrome (easy version)
- three blocks palindrome(a,a,…,a,b,b,…,b,a,a,…,a) a,b数量可为0,前后a数量相等x个,b个
- 输入一个序列,找到最长的合法子序列,在序列中可不连续
- pre(i,j)为前i个数中j的个数
- 暴力:枚举a,b
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#define endl ‘
‘
using namespace std;
const int kN = 2010, kM = 30;
int t,n,ans,a[kN],pre[kN][kM];
int main(void){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin >> t;
while(t--){
ans = 0;
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= n; i++){//前缀和...
for(int j = 1; j <= 26; j++) pre[i][j] = pre[i - 1][j] + (a[i] == j);
}
for(int l = 1; l <= n; l++){//x从0开始枚举
for(int r = l; r <= n; r++){//枚举r
int x = 0, y = 0;
for(int k = 1; k <= 26; k++){//l ~ r 中间范围
x = max(x,min(pre[l - 1][k],pre[n][k] - pre[r][k]));//左右两端k的个数可以为0
y = max(y,pre[r][k] - pre[l - 1][k]);//中间k的个数,可以为0
}
ans = max(ans, x * 2 + y);//维护最大子序列长度
}
}
cout << ans << endl;
}
return 0;
}
E2. Three Blocks Palindrome (hard version)
- 与E1相比较,有了更大的数据范围
- 枚举左侧a的结束位置,计算b右侧结束位置
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#define endl ‘
‘
using namespace std;
const int kN = 2e5 + 5, kM = 205;
int t,n,ans,a[kN],pre[kN][kM];
int main(void){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin >> t;
while(t--){
ans = 0;
cin >> n;
vector<vector<int>> at(kM);
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= n; i++){//前缀和...
at[a[i]].push_back(i);//记录每个数的位置
for(int j = 1; j <= 200; j++){
pre[i][j] = pre[i - 1][j] + (a[i] == j);
}
}
//a所在位置,枚举l左端a的个数x,尾部倒数第x个a为r+1
for(int i = 1; i <= 200; i++){//枚举a
int sz = (int)at[i].size();
for(int l = 0; l <= sz/2; l++){//左侧a的个数
int r = sz - l - 1;//b区间的右侧第一个i的
if(l > r) break;
else if(l == r) ans = max(ans,sz);//全a
else{
int mx = 0;
for(int j = 1; j <= 200; j++){//枚举b
mx = max(mx,pre[at[i][r] - 1][j] - pre[at[i][l]][j]);
}
ans = max(ans,2 * (l + 1) + mx);
}
}
}
cout << ans << endl;
}
return 0;
}
以上是关于codeforces #634(div3) A-E题解的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #617(div3) A-E2题解
Codeforces Round #634 (Div. 3)
Codeforces Round #634 (Div. 3) 补题