Codeforces Round #631 (Div. 2) - Thanks, Denis aramis Shitov!
Codeforces Round #631 (Div. 2) - Thanks, Denis aramis Shitov!
自闭了,惨案现场,比赛写不出C,st后A掉了
A. Dreamoon and Ranking Collection
题意
给出一串\(n\)个数字,可以自行加入\(m\)个数字,问可以得到的最大数字\(k\),使得数列中\([1,k]\)都存在
题解
排个序,逐个枚举就好了
ps:m=0时一定不能提前退出(惨痛教训)
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define def 110
using namespace std;
long a[def];
int main()
{ long _,n,m,i,q,now;
for(scanf("%ld",&_);_;_--){
scanf("%ld%ld",&n,&m);
for(i=1;i<=n;i++)
scanf("%ld",&a[i]);
sort(a+1,a+n+1);
a[n+1]=a[n]+1;
now=0;
for(i=1;i<=n;i++)
if(a[i]!=a[i+1]){
q=min(m,a[i]-now-1);
now+=q;
m-=q;
if(a[i]==now+1)now++;
}
printf("%ld\n",now+m);
}
return 0;
}
B. Dreamoon Likes Permutations
题意
给出一串\(n\)个数字,定义如果一个数列中\([1,k]\)都存在且只出现一次,则它为一个“长度为\(k\)排列”,问如何把给定数列划分成两段,使得两边都为一个排列
题解
简单\(dp\)一下,\(l_i\)为从1到i是否为一个排列,\(r_i\)为从i到n是否为一个排列,最后枚举中间点
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define def 200010
using namespace std;
bool l[def],r[def];
long a[def],sum[def];
int main()
{ long _,n,i,maxx,ans;
for(scanf("%ld",&_);_;_--){
scanf("%ld",&n);
for(i=1;i<=n;i++){
scanf("%ld",&a[i]);
sum[i]=0;
l[i]=r[i]=false;
}
maxx=0;
for(i=1;i<=n;i++){
if(++sum[a[i]]==2)
break;
while(sum[maxx+1])
maxx++;
if(maxx==i)
l[i]=true;
}
maxx=0;
for(i=1;i<=n;i++)
sum[i]=0;
for(i=n;i>=1;i--){
if(++sum[a[i]]==2)
break;
while(sum[maxx+1])
maxx++;
if(maxx==n-i+1)
r[i]=true;
}
ans=0;
for(i=1;i<n;i++)
if(l[i]&&r[i+1])
ans++;
printf("%ld\n",ans);
for(i=1;i<n;i++)
if(l[i]&&r[i+1])
printf("%ld %ld\n",i,n-i);
}
return 0;
}
C. Dreamoon Likes Coloring
题意
有\(n\)个格子,每次可以对其中的连续\(l_i\)个格子染色颜色\(i\),后来的颜色会覆盖原有的颜色,问如何选取每一次的染色区间,使得所有格子都被染色且所有颜色都被显现
题解
贪心,每次尽量往前染色
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define min(a,b) (((a)<(b))?(a):(b))
#define def 100010
using namespace std;
long a[def],ans[def];
int main()
{ long n,m,i,now,q;
long long sum=0;
scanf("%ld%ld",&n,&m);
for(i=1;i<=m;i++){
scanf("%ld",&a[i]);
sum+=a[i];
}
if(sum>=n){
now=1;
for(i=1;i<=m;i++){
ans[i]=now;
if(now+a[i]-1>n)//对空气染色了,不符合
break;
if(sum>n){//需要覆盖染色一部分
q=min(sum-n,a[i]-1);
now+=a[i]-q;
sum-=q;
}else if(sum==n)//不需要覆盖染色
now+=a[i];
else//不够染色
break;
}
}
if(i==m+1&&sum==n){//全部颜色和格子都染了
for(i=1;i<=m;i++)
printf("%ld ",ans[i]);
printf("\n");
}else
printf("-1\n");
return 0;
}

浙公网安备 33010602011771号