链接:https://codeforces.com/problemset/problem/1512/E
题意:
给你一个1~n的序列,重新排列,使得L~R范围内的数字的和为S;
题解:
一开始写了个dfs,没过;看了下数据范围才500,那就直接暴力构造;先判断是否有满足条件的序列,有的话取1~len(len=r-l+1)进行处理;具体操作看代码(纯暴力,注意取值范围)
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<int>b;
int a[505] = { 0 };
void chuli(int l, int r, int s,int n)
{
ll sum = 0;
for (int i = 1; i <= r - l + 1; i++)
{
a[i] = i;
sum += i;
}
s -= sum;//取s与最小序列的差值
int num = n;
int cnt = r - l + 1;
while (true)
{
if(s==0)
{
for (int i = 1; i <= r - l + 1; i++)
{
b.push_back(a[i]);
}
break;
}
if (a[cnt] == num)//如果达到当前数的最大值,构造前一个
{
cnt--;
num--;
}
else
{
a[cnt]++;
s--;
}
}
}
int main()
{
int t;
cin >> t;
while (t--)
{
int n, l, r, s;
cin >> n >> l >> r >> s;
memset(a, 0, sizeof(a));
b.clear();
int len = r - l + 1;
int minn = 0, maxn = 0;
for (int i = 1; i <= len; i++)
minn += i;
for (int i = n; i > n - len; i--)
maxn += i;
if (s<minn||s>maxn)//判断条件
{
cout << -1 << endl;
}
else
{
chuli(l, r, s, n);//构造序列
int cn1 = 1;
while (l != 1)
{
if (find(b.begin(), b.end(), cn1) == b.end())
{
cout << cn1 << " ";
l--;
}
cn1++;
}
for (int i = 0; i <b.size(); i++)
{
cout << b[i] << " ";
}
while (r != n)
{
if (find(b.begin(), b.end(), cn1) == b.end())
{
cout << cn1 << " ";
n--;
}
cn1++;
}
cout << endl;
}
}
}