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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章