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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

POJ 1804 逆序数 解题(归并排序)

發(fā)布時(shí)間:2024/7/5 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 POJ 1804 逆序数 解题(归并排序) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • 解法1:直接雙重循環(huán)求解,n*n復(fù)雜度
    • 解法2:采用歸并排序求解,復(fù)雜度nlgn

題目鏈接 http://poj.org/problem?id=1804
題目大意:
讓一串無(wú)序數(shù),在只能相鄰數(shù)字交換的前提下,最短的次數(shù)變成有序,求該最短次數(shù)。
該最短次數(shù)=該序列的逆序數(shù)

解法1:直接雙重循環(huán)求解,n*n復(fù)雜度

#include<iostream> #include<cstring> using namespace std; int main() {const int N = 1001;int cyctime,len,len1,sum=0;int arr[N];int i=0,j=0,k=0,temp;memset(arr,0,sizeof(int)*N);cin >> cyctime;for(i = 0; i < cyctime; ++i){//cin.clear();cin >> len;len1=len;j=0;while(len1--) //先輸入數(shù)組{cin >> temp;arr[j++] = temp;}for(j = 0; j < len; ++j) //從前往后依次比較{for(k = j+1; k < len; ++k){if(arr[j]>arr[k]){sum++;}}}cout << "Scenario #" << i+1 << ":" << endl;cout << sum << endl << endl;sum = 0;}return 0; }

解法2:采用歸并排序求解,復(fù)雜度nlgn

#include<iostream> #include<cstring> using namespace std; int sum=0; void merge(int *arr,size_t left,size_t mid,size_t right) {int len = right - left + 1;int *temp = new int [len]; //數(shù)組較長(zhǎng)時(shí)請(qǐng)用new,不然棧空間容易溢出size_t index = 0;size_t i = left, j = mid + 1;while(i <= mid && j <= right){if(arr[i]<=arr[j]){temp[index++] = arr[i++];}else{temp[index++] = arr[j++];sum += mid - i + 1; //左邊數(shù)比右邊大,那么左邊剩余的也比其大!!!!!!!!!!}//對(duì)兩邊的數(shù)組從小到大放入臨時(shí)空間}while(i <= mid) //比較完后,左半邊有沒放進(jìn)去的,直接寫入{temp[index++]= arr[i++];}while(j <= right) //比較完后,右半邊有沒有放進(jìn)去的,直接寫入{temp[index++]= arr[j++];}for(int k = 0;k< len;++k){arr[left++ ]= temp[k]; //把有序的臨時(shí)數(shù)組寫入原來(lái)數(shù)組的起始位置}delete [] temp; //釋放空間temp = NULL; //指針置空 } void divide(int *arr,size_t left,size_t right) {if(left == right){ return;}size_t mid = (left+right)/2; //找出區(qū)間中部的數(shù),將數(shù)組分段divide(arr,left,mid); //遞歸調(diào)用,對(duì)左邊繼續(xù)分段;divide(arr,mid+1,right); //遞歸調(diào)用,對(duì)右邊繼續(xù)分段;merge(arr,left,mid,right); //對(duì)左右兩半進(jìn)行排序合并成一小段有序的數(shù)組 } void mergesort(size_t dsize, int *arr) {if(dsize <= 1) //預(yù)防特殊情況下后面代碼失效{return;}size_t left = 0, right = dsize-1;divide(arr,left,right); }int main() {const int N = 1001;int cyctime,len,len1;int arr[N];int i=0,j=0,temp;memset(arr,0,sizeof(int)*N);cin >> cyctime;for(i = 0; i < cyctime; ++i){//cin.clear();cin >> len;len1=len;j=0;while(len1--) //先輸入數(shù)組{cin >> temp;arr[j++] = temp;}mergesort(len,arr);cout << "Scenario #" << i+1 << ":" << endl;cout << sum << endl << endl;sum = 0;}return 0; }

由上可看出歸并排序求解時(shí)間效率更高。

總結(jié)

以上是生活随笔為你收集整理的POJ 1804 逆序数 解题(归并排序)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。