#Codeforces Round #632 (Div. 2)C. D.F题解 #
比赛链接
C - Eugene and an array
题意:
求一个array的有多少subarray是good的,subarray定义为子串,必须怜恤。一个array是good的条件是其全部subarray的和不为0。
题解:
求一个前缀和,使用map保存每一个前缀和的下标,一旦出现相同的前缀和,就是出现和为0的串,所以全部串都不应该包括它。
代码:
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <map>
using namespace std;
const int N=2e5+10;
#define ll long long
int a[N];
map<ll,int>pos;
int main() {
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
ll sum =0;
int p=-1;
ll ans = 0;
pos[0]=0; //important
for(int i=1;i<=n;i++) {
sum += a[i];
if (pos.count(sum))p = max(p, pos[sum]);
ans += i - (p + 1);
pos[sum] = i;
}
printf("%lld\n",ans);
return 0;
}
D - Challenges in school №41
题意:
变形的等价问题为,输入0,1串,每次可以交换任意组(最少一组)的连续的两个0,1的位置,最后使得全部1在左边,全部0在右边。求构造一个恰好交换k次的方案。输出每次交换的每组中1的位置
题解:
有点类似冒泡排序,把1全部冒到左边即可。
最小的min_k:每次交换全部的全部相邻的0,1对。
最大的max_k:每次交换一组0,1队。
输入的k必须位于二者之间。
用最小的min_k转换到任意一个满足条件的k(代码细节学dls写的。
代码:
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <map>
#include <algorithm>
#include <math.h>
#include <vector>
using namespace std;
const int N=3005;
char arr[N];
int main() {
int n,k;
scanf("%d%d",&n,&k);
scanf("%s",arr);
vector<vector<int> > ps = vector<vector<int>>(k,vector<int>());
int tol = 0;
int m=0;
while (1) {
vector<int> step;
for (int i = 0; i < n - 1; i++) {
if (arr[i] == 'R' && arr[i + 1] == 'L')step.push_back(i), tol++;
}
if (step.empty())break;
if (m >= k) {
puts("-1");
return 0;
}
ps[m++] = step;
for (auto x:step)swap(arr[x], arr[x + 1]);
}
if(k>tol){
puts("-1");
return 0;
}
int fs = m-1;//最少的
for(int i=k-1;i>=0;i--){
if(ps[fs].empty())fs--;
if(!ps[i].empty())break;
ps[i] = vector<int>{ps[fs].back()};
ps[fs].pop_back();
}
for(int i=0;i<k;i++){
printf("%d ",ps[i].size());
for(auto x:ps[i])printf("%d ",x+1);
puts("");
}
return 0;
}
F. Kate and imperfection
题意:
在1~n的n个数中,对于k∈[2,n],在n个数中取k个数,选出k的数,使得他们最大gcd最小。
题解:
素数筛类似。
因为求的是最大gcd的最小,所以我们先尽可能的拿素数,素数拿完以后,再拿一个数,必然有一对不互质,所以我们要尽量使答案变小,即因子小的先拿,最后就可以得到从小到大输出的结论。
这样逻辑似乎还是有点问题,依然不能证明这就是最优方案。
代码:
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <map>
#include <algorithm>
#include <math.h>
using namespace std;
const int N=5e5+10;
#define ll long long
int a[N];
int pr[N];
map<ll,int>pos;
void solve(int n){
for(int i=1;i<=n;i++)pr[i]=1;
for(int i=2;i<=n;i++){
for(int j=2*i;j<=n;j+=i){
pr[j] = i;//目前的最大因子
}
}
}
int main() {
int n;
scanf("%d",&n);
solve(n);
sort(pr+1,pr+n+1);
for(int i=2;i<=n;i++){
printf("%d ",pr[i]);
}
return 0;
}