Codeforces Round #631 (Div. 2)(A-C)

A 统计之后补x个空就可以了,最大应该是max(ai)+x<=200;

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>  PII;
#define IOS ios::sync_with_stdio(0); 
const int N=1000010;
int n,x,a[N],t,num[N];
 
int main()
{
	cin>>t;
	while(t--)
	{
		memset(num,0,sizeof num);
		cin>>n>>x;
		for(int i=0;i<n;i++) cin>>a[i],num[a[i]]++;
		int cnt=0;
		for(int i=1;i<=220;i++)
			if(!num[i])
			{
				cnt++;
				if(cnt>x)
				{
					cout<<i-1<<endl;
					break;
				}
			}
	}
	return 0;
}

B 将一个数组分成两部分,两部分都是从1开始的全排列,一组数是全排列的话和就等于(1+l)*l/2(l是长度),而且还要不重复。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>  PII;
#define IOS ios::sync_with_stdio(0); 
const int N=200010;
int n,x,a[N],t,num[N];
ll sum[N];
bool stl[N],str[N];//stl左半部分是否有重复元素,str右半部分是否有重复元素
int main()
{
	cin>>t;
	while(t--)
	{
		vector<PII> ve;
		cin>>n;
		stl[0]=1;
		for(int i=1;i<=n;i++) num[i]=0;//清零,用memset应该会超时
		for(int i=1;i<=n;i++) 
		{
			cin>>a[i];
			sum[i]=sum[i-1]+a[i];
			if(stl[i-1]==1)
			{
				if(num[a[i]]) stl[i]=0;
				else num[a[i]]++,stl[i]=1;
			}
			else stl[i]=0;
		}
		for(int i=1;i<=n;i++) num[i]=0;
		for(int i=n;i;i--)
		{
			if(i==n||str[i+1]==1)
			{
				if(num[a[i]]) str[i]=0;
				else num[a[i]]++,str[i]=1;
			}
			else str[i]=0;
		}
		for(int i=1;i<n;i++)
		{
			int l=n-i;
			if(sum[i]==1ll*(i+1)*i/2&&(sum[n]-sum[i])==1ll*(l+1)*l/2&&stl[i]&&str[i+1])
				ve.push_back({i,l});
		}
		cout<<ve.size()<<endl;
		for(int i=0;i<ve.size();i++)
			cout<<ve[i].first<<' '<<ve[i].second<<endl;
	}
	return 0;
}

补题:
C 每个li可以选择区间[1,n-li+1]内的一个数为起点给长度为li的区间染色,每次颜色各不相同,问是否可以染色m次后区间[1,n]全被染色而且有m种不同颜色,就是每种颜色都没有被完全覆盖。
n-li+1+li-1==n,就是说每种颜色都是可以染到n的,那么考虑将后面的颜色首尾相连去染色,求一个sumi,就是后i中颜色最多可以染多少格,然后先将前面的颜色每次染色后只剩下一个格子,直到后面的不足以把剩下的全覆盖就跳出,后面的就尽量多的染色,但是不能将前面的格子覆盖就要大于前一个染色的点,最后判断染色后能不能将n个格子全部染上色,就是相邻的染色区有没有交集,还有每次染色的点(染色区间左端点就是输出的那个值)不能大于n-li+1;

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>  PII;
#define IOS ios::sync_with_stdio(0); 
const int N=200010;
int n,m,a[N],t;
ll b[N],num[N];
ll sum[N];
bool stl[N],str[N];
int main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++) 
		cin>>a[i];
	for(int i=m;i;i--) sum[i]=sum[i+1]+a[i]; 
	int l=m+1;
	for(int i=1;i<=m;i++)//先每次只染一个格子
	{
		if(sum[i+1]+i>=n) b[i]=i;
		else //剩下的不能全部染上色就跳出
		{
			l=i;
			break;
		}
	}
	for(int i=l;i<=m;i++)//剩下的尽量多的格子
		b[i]=max(b[i-1]+1,n-sum[i+1]-a[i]+1);
	bool flag=1;
	b[0]=1;
	for(int i=1;i<=m;i++)
		if(b[i-1]+a[i-1]<b[i]||b[i]>n-a[i]+1) flag=0;
	if(flag)
		for(int i=1;i<=m;i++) cout<<b[i]<<' ';
	else cout<<-1;
	return 0;
}
原文地址:https://www.cnblogs.com/neflibata/p/12871762.html