题意:
给出n, l, r, s, 要求构造一个序列,要求满足l, r区间的和是s, 存在就是输出序列,否则就-1
思路:
首先判断是否-1,很简单,就是一个区间里面的最大值和最小值,s必须在这其中,然后就是如果在这其中如何去构造,刚开始想的是没什么思路,但后面看了别人的,才悟了,就是可以先填最小的,然后不够从后往前加,因为最后肯定能够保证填满足条件,因为每次加的是1
总结:
构造一段区间,区间里面的数都不相等,然后和为s, 先排最小的,然后不断的从后往前添加,保证不重复了就
点击查看代码
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);
#define endl '\n'
using namespace std;
typedef long long ll;
int T, n, l, r, s;
int main()
{
IOS; cin.tie(0), cout.tie(0);
cin >> T;
while (T--)
{
cin >> n >> l >> r >> s;
int mn = (1 + r - l + 1) * (r - l + 1) / 2;
int mx = (n - (r - l + 1) + 1 + n) * (r - l + 1) / 2;
if (mn > s || s > mx)
{
cout << "-1" << endl;
continue;
}
int left = s - mn, count = left / (r - l + 1), cha = left - count * (r - l + 1);
vector<int> ans, other;
for (int i = 1; i <= r - l + 1; ++i)
ans.push_back(i + count);
for (int i = ans.size() - 1; i >= ans.size() - 1 - cha + 1; --i)
++ans[i];
set<int> st;
for (int i = 0; i < ans.size(); ++i)
st.insert(ans[i]);
for (int i = 1; i <= n; ++i)
if (!st.count(i))
other.push_back(i);
int pos = 0;
for (int i = 1; i < l; ++i)
cout << other[pos++] << " ";
for (int i = 0; i < ans.size(); ++i)
cout << ans[i] << " ";
for (int i = r + 1; i <= n; ++i)
cout << other[pos++] << " ";
cout << endl;
}
return 0;
}
/*
1
3 1 2 4
*/