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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

蓝桥杯 历届试题 小朋友排队 C++

發布時間:2023/12/14 c/c++ 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 蓝桥杯 历届试题 小朋友排队 C++ 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目閱覽
 n 個小朋友站成一排。現在要把他們按身高從低到高的順序排列,但是每次只能交換位置相鄰的兩個小朋友。
  每個小朋友都有一個不高興的程度。開始的時候,所有小朋友的不高興程度都是0。
  如果某個小朋友第一次被要求交換,則他的不高興程度增加1,如果第二次要求他交換,則他的不高興程度增加2(即不高興程度為3),依次類推。當要求某個小朋友第k次交換時,他的不高興程度增加k。
  請問,要讓所有小朋友按從低到高排隊,他們的不高興程度之和最小是多少。
  如果有兩個小朋友身高一樣,則他們誰站在誰前面是沒有關系的。
  
輸入格式
  輸入的第一行包含一個整數n,表示小朋友的個數。
  第二行包含 n 個整數 H1 H2 … Hn,分別表示每個小朋友的身高。
  
輸出格式
輸出一行,包含一個整數,表示小朋友的不高興程度和的最小值。

樣例輸入1
3
3 2 1

樣例輸出1
9

樣例說明
  首先交換身高為3和2的小朋友,再交換身高為3和1的小朋友,再交換身高為2和1的小朋友,每個小朋友的不高興程度都是3,總和為9。

思路簡介
先介紹一下第一次提交的代碼,當然因為算法復雜超時了最后三個,這里的思路是將所有小朋友的身高和所在位置存儲在數組中,并利用另外兩個數組依次根據身高大小排序,最后再次根據小朋友所在位置篩選出滿足比自身位置靠前,并且大于自身身高的人數和比自身位置靠后,但小于自己身高的人數,也就是交換的次序,再根據交換次序將小朋友不高興程度遞增,求和得出最終結果。

實現代碼

#include <iostream> #include <vector> #include <algorithm>using namespace std;struct childInfo{int location;int valueNum; };bool lowCompare(childInfo temp1,childInfo temp2){return temp1.valueNum>temp2.valueNum; }bool upCompare(childInfo temp1,childInfo temp2){return temp1.valueNum<temp2.valueNum; }int main(){int childNums;cin>>childNums;vector<childInfo> childLists;vector<childInfo> childLists1;vector<childInfo> childLists2;for(int i=0;i<childNums;i++){childInfo tempInfo;tempInfo.location=i;scanf("%d",&tempInfo.valueNum);childLists.push_back(tempInfo);childLists1.push_back(tempInfo);childLists2.push_back(tempInfo);}sort(childLists1.begin(),childLists1.end(),lowCompare);sort(childLists2.begin(),childLists2.end(),upCompare);long long int count=0;for(int m=0;m<childNums;m++){int sadNum=0;long long int count1=0,count2=0;int compareNum=childLists[m].valueNum,compareLoc=childLists[m].location;//比自身位置靠前,并且大于自身身高的人數for(int n=0;n<childNums;n++){if(compareNum<childLists1[n].valueNum){if(compareLoc>childLists1[n].location){sadNum++;count1+=sadNum;}}else{break;}}//比自身位置靠后,并且小于自身身高的人數for(int n=0;n<childNums;n++){if(compareNum>childLists2[n].valueNum){if(compareLoc<childLists2[n].location){sadNum++;count2+=sadNum;}}else{break;} }count+=count1+count2;}cout<<count<<endl;return 0; }

運行截圖

改進方法
參考這位博主:歸并排序
將每個小朋友交換次數是前面比他大的個數與后面比他小的個數之和,主要思路是對數組歸并兩次。
最終代碼

#include<iostream> #include<string> #include<vector> #include<algorithm>using namespace std;struct childInfo{int location;int valueNum; };int cnt[100005];void Merge_sort1(vector<childInfo>&tempChild,int left,int right) {if(left>=right-1)return;int mid = (left+right)/2;Merge_sort1(tempChild,left,mid);Merge_sort1(tempChild,mid,right);int i=left,j=mid,t=0;childInfo *temp = new childInfo[right-left];while(i<mid || j<right){if(j>=right || i<mid && tempChild[i].valueNum<=tempChild[j].valueNum)temp[t++] = tempChild[i++];else{cnt[tempChild[j].location] += mid-i;temp[t++] = tempChild[j++];}}t=0;for(int k = left;k<right;k++)tempChild[k] = temp[t++];delete []temp; }void Merge_sort2(vector<childInfo>&tempChild,int left,int right) {if(left>=right-1)return;int mid = (left+right)/2;Merge_sort2(tempChild,left,mid);Merge_sort2(tempChild,mid,right);childInfo *temp = new childInfo[right-left];int i=mid-1,j=right-1,t=right-left-1;while(i>=left || j>=mid){if(i<left || j>=mid && tempChild[i].valueNum <= tempChild[j].valueNum)temp[t--] = tempChild[j--];else{cnt[tempChild[i].location] += j-mid+1;temp[t--] = tempChild[i--];}}t=0;for(int i=left;i<right;i++)tempChild[i] = temp[t++];delete []temp; } int main() {int n;cin >> n;vector<childInfo> childLists;for(int i=0;i<n;i++){childInfo tempChild;tempChild.location = i;cin >> tempChild.valueNum;childLists.push_back(tempChild); }vector<childInfo> childLists1(childLists.begin(),childLists.end());Merge_sort1(childLists,0,childLists.size());Merge_sort2(childLists1,0,childLists1.size());long long sum =0;for(int i=0;i<childLists.size();i++)sum += 1ll*(1+cnt[i])*cnt[i]/2;cout << sum;return 0; }

最終結果

總結

以上是生活随笔為你收集整理的蓝桥杯 历届试题 小朋友排队 C++的全部內容,希望文章能夠幫你解決所遇到的問題。

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