A. Permutation Warm-Up
翻譯:
? ? ? ? 對于長度為 n?的排列 p,我們定義函數:
????????
????????給你一個數 n。你需要計算函數 f(p) 在考慮從 1 到 n 的所有可能的數字排列時,可以取多少個不同的值。
思路:
? ? ? ? 按序排列時和為0,當有一端值+1,必有一端值-1即sum+2。由此會得到的和都為偶數。答案為sum_max/2+1。
實現:
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int MX = 2e5+10;void solve(){int n;cin>>n;int res = 0;for (int l=n,i=1;i<=n;i++){res+=abs(l-i);l--;}cout<<res/2+1<<endl;
}int main(){// 關閉輸入輸出流同步ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);// 不使用科學計數法// cout<<fixed;// 四舍五入中間填保留幾位小數,不填默認// cout.precision();int t;cin>>t;while (t--){solve();}return 0;
}
B. SUMdamental Decomposition
翻譯:
? ? ? ? 在你最近的一個生日上,你的好朋友莫里斯送給你一對數字 n
?和 x?,并要求你構造一個長度為 n 的正數數組 a ,使得。
????????這個任務對你來說似乎太簡單了,因此你決定給莫里斯一個回禮,在所有這樣的數組中構造一個元素之和最小的數組。你馬上想到了一個合適的數組;但是,由于寫下來太費時間,莫里斯只能選擇元素之和。
思路:
? ? ? ? 一個數可以被分成多個不同二的冪次相加。
? ? ? ? 要讓和足夠小,可先將 x 拆成不同的2的冪次數,再對還要填的數進行添加。設還要填 n 個數。
????????當 n 為偶數時,都為1。
? ? ? ? 帶 n 為奇數時,先摘掉一個 num,其余都為1。num 對于被拆分的2的冪次數二進制有數位0為0情況,則可將該數與num都+1,否則num為2,找個數也+2。
實現:
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int MX = 2e5+10;
void solve(){ll n,x;cin>>n>>x;if (n==1 && x==0){cout<<-1<<"\n";return;}ll res = x;ll tmp = x,cnt=0;// 有兩個及以上的1嗎while (tmp){if (tmp%2==1){cnt++;}tmp/=2;}n = max(0ll,n-cnt);if (n%2==0){res += n;}else if (n%2==1){res+=n-1;if (x==1 || x==0) res+=4;else res +=2;}cout<<res<<"\n";
}int main(){// 關閉輸入輸出流同步ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);// 不使用科學計數法// cout<<fixed;// 四舍五入中間填保留幾位小數,不填默認// cout.precision();int t;cin>>t;while (t--){solve();}return 0;
}
C. Neo's Escape
翻譯:
????????尼奧想要逃離母體。在他面前,有 n 個按鈕排成一排。每個按鈕的權重都是一個整數:
。
????????尼奧無法移動,但他可以創造和移動克隆人。這意味著他可以以任意順序執行以下兩種類型的操作,數量不限:
- 在特定按鈕前創建一個克隆體。
- 將現有克隆體向左或向右移動一個位置。
????????只要克隆體出現在另一個尚未按下的按鈕前,無論它是被創建還是被移動,它都會立即按下該按鈕。如果按鈕已經被按下,克隆人就什么也做不了--按鈕只能按一次。
????????要想讓尼奧逃脫,他需要按順序按下所有按鈕,使它們的權重序列不遞增--也就是說,如果??
?是按順序按下的按鈕的權重,那么必須成立:
。
????????你的任務是確定尼歐需要創建的最小克隆數,以便按有效順序按下所有按鈕。
思路:
? ? ? ? 不考慮有權值相同點的情況下,當一個點值為局部最大值時,它是必定要被創建的,而不是的則可通過局部最大值的左右移動被合理按下。
實現:
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int MX = 2e5+10;void solve(){int n;cin>>n;int pre = -1;vector<int> a={0};for (int num,i=0;i<n;i++){cin>>num;if (num!=pre){a.push_back(num);}pre = num;}a.push_back(0);int res = 0;for (int i=1;i<a.size()-1;i++){res+=(a[i]>a[i-1] && a[i]>a[i+1]);}cout<<res<<"\n";
}int main(){// 關閉輸入輸出流同步ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);// 不使用科學計數法// cout<<fixed;// 四舍五入中間填保留幾位小數,不填默認// cout.precision();int t;cin>>t;while (t--){solve();}return 0;
}
?
??有建議可以評論,我會積極改進qwq。