【蓝桥杯官网试题 - 历届试题】小朋友排队(逆序数,树状数组)
題干:
問題描述
n 個小朋友站成一排。現在要把他們按身高從低到高的順序排列,但是每次只能交換位置相鄰的兩個小朋友。
每個小朋友都有一個不高興的程度。開始的時候,所有小朋友的不高興程度都是0。
如果某個小朋友第一次被要求交換,則他的不高興程度增加1,如果第二次要求他交換,則他的不高興程度增加2(即不高興程度為3),依次類推。當要求某個小朋友第k次交換時,他的不高興程度增加k。
請問,要讓所有小朋友按從低到高排隊,他們的不高興程度之和最小是多少。
如果有兩個小朋友身高一樣,則他們誰站在誰前面是沒有關系的。
輸入格式
輸入的第一行包含一個整數n,表示小朋友的個數。
第二行包含 n 個整數 H1 H2 … Hn,分別表示每個小朋友的身高。
輸出格式
輸出一行,包含一個整數,表示小朋友的不高興程度和的最小值。
樣例輸入
3
3 2 1
樣例輸出
9
樣例說明
首先交換身高為3和2的小朋友,再交換身高為3和1的小朋友,再交換身高為2和1的小朋友,每個小朋友的不高興程度都是3,總和為9。
數據規模和約定
對于10%的數據, 1<=n<=10;
對于30%的數據, 1<=n<=1000;
對于50%的數據, 1<=n<=10000;
對于100%的數據,1<=n<=100000,0<=Hi<=1000000。
解題報告:
我就說嘛、、、過了70%,不可能是思路錯誤,,檢查了半天發現最后的統計答案爆了longlong、、、氣死我了。
這題的關鍵在于看到交換的條件是:只能交換相鄰的兩個元素。這就使得問題簡單了很多。考慮到x這個數,假設最后肯定要被交換到對應的位置上,那么看最少需要被交換多少次,在看這個次數能否可以實現。不難發現,最少被交換的次數,就是和前面比他大的數字,并且和后面比他小的數字。所以求該數對應的逆序數就行了。那么這個次數能否實現呢?不妨這樣想,只考慮第i個數,假設前面比他大的有x1個,后面比他小的有x2個,我們先想辦法將他前面比他大的數都交換到他后面去,這樣他移動的次數就肯定是x1,并且得到的這樣一個狀態肯定是在他本該在的位置的前面,然后我們再通過和后面的數字的交換讓他回到原來的位置就可以了,這一套操作是x2次,所以總次數可以達到x1+x2次。
AC代碼:
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define F first #define S second #define ll long long #define pb push_back #define pm make_pair using namespace std; typedef pair<int,int> PII; const int MAX = 2e6 + 5; int a[MAX]; int c[MAX]; int lowbit(int x){return x&(-x);} int query(int x) {int res = 0;while(x>0) {res += c[x];x-=lowbit(x);}return res; } void update(int x,int val) {while(x<MAX) {c[x] += val;x+=lowbit(x);} } int ans1[MAX],ans2[MAX],ans[MAX]; int main() {int n;cin>>n;for(int i = 1; i<=n; i++) {scanf("%d",a+i);a[i]++;}for(int i = n; i>=1; i--) {ans1[i] = query(a[i]-1);update(a[i],1);}memset(c,0,sizeof c);for(int i = 1; i<=n; i++) {ans2[i] = query(1000010) - query(a[i]);update(a[i],1);}for(int i = 1; i<=n; i++) ans[i] = ans1[i] + ans2[i];ll res = 0;for(int i = 1; i<=n; i++) {res += 1LL*(1+ans[i])*ans[i]/2;}printf("%lld\n",res);return 0 ; }?
總結
以上是生活随笔為你收集整理的【蓝桥杯官网试题 - 历届试题】小朋友排队(逆序数,树状数组)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: speedupmypc.exe - sp
- 下一篇: 信用卡申请后不激活多久失效 3到5年可重