日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

cf 1512 E. Permutation by Sum

發布時間:2023/12/3 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 cf 1512 E. Permutation by Sum 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

cf 1512 E. Permutation by Sum

題意:

我們定義排列的概念為:從1到n的整數組成的序列,每個數字只出現一次
現在給你n,l,r,s,讓你構造一個長度為n的排列,使得其中的第l到第r項和為s
輸出任意答案

題解:

又是構造題,構造題考察經驗思維
我們想想區間[l,r]的和為s
區間長度為len = r - l+1
區間長度為len的能組成的最小和min就是1+…+len
最大和就是n+n-1…n-lenn+1
如果s不在這個范圍內,說明s無法構造,輸出-1
如果s可以構造說明最小和+?就是s
這個?怎么求
ave = (s-min)/len:區間內每個數比最小值平均大Ave
那么我們這個區間至少應該是i+ave(1<=i<=len)
這樣構造的區間一定小于等于s(我們去差為cha),且區間為從小到大順序排列
如果小于s(cha>0),我們就讓最后一位+1,cha–,如果cha還大于0,我們就讓倒數第二位+1,cha–,從后往前一次增加
為什么這樣?
為什么要+1呢?因為每位這個區間是最接近s的連續區間,所以從這個開始枚舉所需要的可能性最少
為什么要倒著循環+1呢?因為這個循環肯定是不可能全部進行完的(因為我們已經求的原本的區間是最接近s的),所以在某個時刻cha會等于0,循環中斷,如果我們正著循環,在第i個數加完后中斷,第i個數就等于第i+1個數(因為原本序列是順序排列的,而i加了1,第i+1位沒變),會出現重復數,但是如果倒著循環就不會存在,因為后一位始終大于前一位
詳細看代碼

代碼:

#include <algorithm> #include <iostream> #include <cstring> #include <string> #include <vector> #include <cstdio> #include <stack> #include <queue> #include <cmath> #include <map> #include <set> #define G 10.0 #define LNF 1e18 #define eps 1e-6 #define ll long long #define INF 0x7FFFFFFF #define PI acos(-1.0) #define pb(x) push_back(x) #define SP system("pause") #define mm(a, b) memset(a, b, sizeof(a)) #define fir(i, a, n) for (ll i = a; i <= n; i++) #define rif(i, a, n) for (ll i = a; i >= n; i--) #define each_cass(cass) for (cin >> cass; cass; cass--)using namespace std; void solve() {ll n, l, r, s;cin >> n >> l >> r >> s;ll Min = (1 + r - l + 1) * (r - l + 1) / 2;ll Max = (n + n - r + l) * (r - l + 1) / 2;if (s > Max || s < Min){cout << "-1" << endl;return;}int cha = s - Min;vector<int> zhong;vector<int> qian;vector<int> hou;int pingduo = cha / (r - l + 1);//代表[1~(r-l+r)]每個數至少要加的數int len = r - l + 1;for (int i = 1; i <= len; i++)zhong.push_back(i+pingduo),cha-=pingduo;if (cha)//如果cha不為0,就最大的幾個數+1直到cha=0{for (int i = zhong.size() - 1; cha && i >= 0; i--){zhong[i]++;cha--;}}int vis[10000] = {0};//記錄,防止重復for (int i = 0; i < zhong.size(); i++)vis[zhong[i]] = 1;for (int i = 1; i <= n; i++){if (qian.size() == l - 1)//前面的數是(l-1)個break;if (!vis[i])qian.push_back(i), vis[i] = 1;}for (int i = 1; i <= n; i++){if (hou.size() == n - r)//后面的數是(n-r)個break;if (!vis[i])hou.push_back(i), vis[i] = 1;}//輸出for (int i = 0; i < qian.size(); i++)cout << qian[i] << " ";for (int i = 0; i < zhong.size(); i++)cout << zhong[i] << " ";for (int i = 0; i < hou.size(); i++)cout << hou[i] << " ";cout << endl; } int main() {int cass;each_cass(cass){solve();}return 0; }

總結

以上是生活随笔為你收集整理的cf 1512 E. Permutation by Sum的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。