题目链接
求一个长度n的序列,从L到R的元素总和为s。(序列中元素在1-n之间)
首先判断s是否合法。
如果合法,假装这个序列从L到R是1 2 3 … R-L+1,再计算s和sum[l…r]的差值。每相差(r-l+1)就把l到r集体往后移动1,相差不到r-l+1的就把后几个移动1.
比如n=5 , l=3, r=5, and s=8,
第三个元素到第五个初始设为:
1 2 3 差值为8-6=2,不足3,所以后两个都后移1
1 3 4
所以整个序列为 2 5 1 3 4
时间复杂度为O(n).
#include <bits/stdc++.h>
using namespace std;
const int N=510;
int n,l,r,s;
int a[N],f[N];
int main(){
int t;cin>>t;
while(t--){
memset(a,0,sizeof a);
memset(f,0,sizeof f);
cin>>n>>l>>r>>s;
int len=r-l+1;
if(s<(1+len)*len/2||s>(2*n-len+1)*len/2){
puts("-1");
continue;
}
int start=(1+len)*len/2;
int cnt=(s-start)/len,num=(s-start)%len;
for(int i=l;i<=r;i++){
a[i]=i-l+1+cnt;
if(r-i<num) a[i]++;
f[a[i]]=1;
}
int j=1;
for(int i=1;i<=n;i++){
if(a[i]) continue;
while(f[j]){
j++;
}
a[i]=j;
f[j]=1;
}
for(int i=1;i<=n;i++) cout<<a[i]<<' ';
cout<<endl;
}
return 0;
}