目录
Codeforces Round #713 (Div. 3)-E. Permutation by Sum
传送门
Time Limit: 2 seconds
Memory Limit: 256 megabytes
Problem Description
A permutation is a sequence of n n n integers from 1 1 1 to n n n, in which all the numbers occur exactly once. For example, [ 1 ] [1] [1], [ 3 , 5 , 2 , 1 , 4 ] [3, 5, 2, 1, 4] [3,5,2,1,4], [ 1 , 3 , 2 ] [1, 3, 2] [1,3,2] are permutations, and [ 2 , 3 , 2 ] [2, 3, 2] [2,3,2], [ 4 , 3 , 1 ] [4, 3, 1] [4,3,1], [ 0 ] [0] [0] are not.
Polycarp was given four integers n n n, l l l, r r r ( 1 ≤ l ≤ r ≤ n ) 1 \le l \le r \le n) 1≤l≤r≤n) and s s s ( 1 ≤ s ≤ n ( n + 1 ) 2 1 \le s \le \frac{n (n+1)}{2} 1≤s≤2n(n+1)) and asked to find a permutation p p p of numbers from 1 1 1 to n n n that satisfies the following condition:
For example, for n = 5 n=5 n=5, l = 3 l=3 l=3, r = 5 r=5 r=5, and s = 8 s=8 s=8, the following permutations are suitable (not all options are listed):
Help Polycarp, for the given n n n, l l l, r r r, and s s s, find a permutation of numbers from 1 1 1 to n n n that fits the condition above. If there are several suitable permutations, print any of them.
Input
The first line contains a single integer t t t ( 1 ≤ t ≤ 500 1 \le t \le 500 1≤t≤500). Then t t t test cases follow.
Each test case consist of one line with four integers n n n ( 1 ≤ n ≤ 500 1 \le n \le 500 1≤n≤500), l l l ( 1 ≤ l ≤ n 1 \le l \le n 1≤l≤n), r r r ( l ≤ r ≤ n l \le r \le n l≤r≤n), s s s ( 1 ≤ s ≤ n ( n + 1 ) 2 1 \le s \le \frac{n (n+1)}{2} 1≤s≤2n(n+1)).
It is guaranteed that the sum of n n n for all input data sets does not exceed 500 500 500.
Output
For each test case, output on a separate line:
If there are several suitable permutations, print any of them.
Sample Input
5
5 2 3 5
5 3 4 1
3 1 2 4
2 2 2 2
2 1 1 3
Sample Onput
1 2 3 4 5
-1
1 3 2
1 2
-1
题目大意
给你 4 4 4个数 n 、 l 、 r 、 s n、l、r、s n、l、r、s,让你找到一个 n n n的全排列,它满足从第 l l l个数累加到第 r r r个数的和等于 s s s。
解题思路
n n n的全排列中,最大的数是 n n n,最小的数是 1 1 1,且各个数各不相同。
所以 l l l到 r r r这 r − l + 1 r-l+1 r−l+1个数(记为 n u m num num)中,和的最小值是 m = 1 + 2 + ⋯ + n u m = ( 1 + n u m ) ∗ n u m / 2 m=1+2+\cdots+num=(1+num)*num/2 m=1+2+⋯+num=(1+num)∗num/2,和的最大值是 M = ( n − n u m + 1 ) + ( n − n u m + 2 ) + ⋯ + n = ( n − n u m + 1 + n ) ∗ n u m / 2 M=(n-num+1)+(n-num+2)+\cdots+n=(n-num+1+n)*num/2 M=(n−num+1)+(n−num+2)+⋯+n=(n−num+1+n)∗num/2。
如果 s s s界于这两个数之间,就能找到符合条件的全排列,否则就不行。
如果可以找到,就把 l l l到 r r r中的数先初始值为最小的 1 1 1到 n u m num num,再不断将这些数变大(变得尽量大),知道他们的和等于 s s s。
变大过程是从最后一个数( n u m num num)开始变到尽可能大(不超过 n n n且和不超过 s s s),然后倒数第二个数( n u m − 1 num-1 num−1)开始变到尽可能大(不超过 n − 1 n-1 n−1且和不超过 s s s) ⋯ \cdots ⋯知道和等于 s s s。
AC代码
#include <bits/stdc++.h>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define dbg(x) cout << #x << " = " << x << endl
#define fi(i, l, r) for (int i = l; i < r; i++)
#define cd(a) scanf("%d", &a)
typedef long long ll;
int a[505];
int getNext(map<int,bool>::iterator &it)//找到下一个输出的数(可以先看下面主函数)
{
while(it->second==false)it++;//这个数出现过了,继续往下找
return it->first;//找到返回
}
int main()
{
int N;
cin>>N;
while(N--)//N组测试样例
{
int n,l,r,s;
cin>>n>>l>>r>>s;
int num=r-l+1;//从l到r共有r-l+1个数
int m=(1+num)*num/2;//和最小为m
int M=(n-num+1+n)*num/2;//和最大为M
if(s<m||s>M)//如果s不介于他们之间
{
puts("-1");//不行
continue;
}
for(int i=0;i<num;i++)//l到r初始值从1到num
{
a[i]=i+1;
}
int diff=s-m;//s比现在的这num个数大diff,还需要再加上diff
int toM=n;//一个数最大变到n
int loc=num-1;//目前处理的数的下标(从第r个数开始处理)
while(diff)//差值不为0
{
int thisMaxDiff=toM-a[loc];//这个数改变所能引起的最大的差值
int thisRealDiff=min(thisMaxDiff, diff);//真正变大的量(不能超过diff)
diff-=thisRealDiff;//差距减小了thisRealDiff
a[loc]+=thisRealDiff;//这个数变大了thisRealDiff
toM=a[loc]-1;//一个数最大变到的数-1
loc--;//下次处理前面一个数
}
map<int,bool>ma;//map储存一个数是否还能使用
for(int i=1;i<=n;i++)
{
ma[i]=1;//初始值还可以使用
}
for(int i=0;i<num;i++)
{
ma[a[i]]=0;//从l到r中要出现的数不能再使用
}
map<int,bool>::iterator it=ma.begin();//从头开始找
// for(map<int,bool>::iterator temp=ma.begin();temp!=ma.end();temp++)
// {
// printf("%d %d\n",temp->first, temp->second);
// }
loc=0;
for(int i=1;i<=n;i++)
{
if(i>=l&&i<=r)//是l到r中的一个数
{
printf("%d ",a[loc++]);//以及计算出,直接输出
}
else//否则
{
printf("%d ",getNext(it));//没出现过的数中找到下一个
it++;
}
}
puts("");//换行
}
return 0;
}
原创不易,转载请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/115599358