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;
}
posted @ 2020-04-04 15:25  dreaming2019  阅读(170)  评论(0)    收藏  举报