Dreamoon Likes Coloring(模拟+构造)

\(这题刚好撞到我的思路了,但是因为模拟......我看了几十遍测试数据....\)

\(首先当\sum_{i=1}^m{a_i}\)小于n时一定无解

大于呢?那我们就要浪费一些区间(覆盖一些点,也就是多出来的点)

但是又不能全部覆盖,最早应该可以从上一个区间的左端点+1位置开始覆盖

然后模拟,刚开始能覆盖多少就覆盖多少。

但是注意,当i+a[i]-1>n时输出-1,这时候不论怎么放都不行。(比较难考虑周全)

然后代码写的很丑,就这样吧....

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=100009;
ll sumn=0;
int n,m;
int a[maxn],b[maxn];
int main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		scanf("%d",&a[i]);
		sumn+=a[i];
	}
	for(int i=1;i<=m;i++)
	{
		if(a[i]+i-1>n)
		{
			cout<<-1;
			return 0;
		}
	}
	if(sumn<n)	cout<<-1;
	else if(sumn==n)
	{
		int r=1;
		for(int i=1;i<=m;i++)
		{
			cout<<r<<" ";
			r+=a[i];
		}
	}
	else
	{
		sumn-=n;//要重合这么多点
		b[1]=1;
		int flag=0,r=a[1]+1;//结束位置 
		for(int i=2;i<=m;i++)
		{
			if(flag)
			{
				b[i]=r;
				r+=a[i];
			}
			else
			{
				int L=min(a[i],r-i);//放在最左边重合的点
				if(L>=sumn)//已经够了
				{
					b[i]=r-sumn;
					r=b[i]+a[i];
					flag=1;
				}
				else//还不够 
				{
					sumn-=L;
					b[i]=i;
					r=max(r,i+a[i]);
				} 
			}
		}
		for(int i=1;i<=m;i++)	cout<<b[i]<<" "; 
	}
}

猜你喜欢

转载自www.cnblogs.com/iss-ue/p/12803295.html