題目如下:
----------------------------------
time limit:
10000ms
case time limit:
1000ms
memory limit:
256mb
描述在上一回、上上回以及上上上回里我們知道nettle在玩《艦これ》。經過了一番苦戰之後,nettle又獲得了的很多很多的船。
這一天nettle在檢查自己的艦隊列表:
我們可以看到,船預設排序是以等級為引數。但實際上乙個船的火力值和等級的關係並不大,所以會存在a船比b船等級高,但是a船火力卻低於b船這樣的情況。比如上圖中77級的飛龍改二火力就小於55級的夕立改二。
現在nettle將按照等級高低的順序給出所有船的火力值,請你計算出一共有多少對船滿足上面提到的這種情況。
輸入第1行:1個整數n。n表示艦船數量, 1≤n≤100,000
第2行:n個整數,第i個數表示等級第i低的船的火力值a[i],1≤a[i]≤2^31-1。
輸出第1行:乙個整數,表示有多少對船滿足「a船比b船等級高,但是a船火力低於b船」。
sample input
10sample output1559614248 709366232 500801802 128741032 1669935692 1993231896 369000208 381379206 962247088 237855491
27--------------------------------
這題是個典型逆序排隊問題,經典解法就是用歸併排序來求解。我採用的也是歸併的方法,但是在hihocoder提交**之後,一直提示wrong answer,但是自己用了多組測試用例都沒發現有任何問題,簡直太鬱悶了。。。後來想到那要不用大資料方案測一下唄,於是設定了乙個100000大的輸入陣列,發現返回結果為負數了。。。好,問題來了,返回負值,那不就是儲存返回結果的變數不夠長嗎?真是智商捉急啊!於是將儲存返回結果的int型變數變成了long long型的,一下就ac了。回想前幾天做的乙個微軟的筆試題,當時提交答案後也是扣了一半分數,不明原因,現在回想估計有這個原因在裡面,回頭再去檢查一下。
下面簡單說一下思路:
在歸併排序的過程中,當左右兩組(分別長m, n)進行合併時,會臨時申請乙個m+n長的陣列來存兩者合併的有序陣列。那麼當掃面左邊和右邊陣列時,如果發現右邊比左邊小,那麼將右邊陣列中該元素放入臨時陣列中。如果發現左邊陣列大於或者等於右邊陣列中當前元素,那麼將左邊陣列該元素放入臨時陣列中,同時更新逆序對的數量,增加的數量等於目前臨時陣列中的右邊陣列的元素個數(為什麼這麼認為呢,因為當前放入的左邊陣列元素大於臨時陣列中的所有元素,那麼就與臨時陣列中的所有右邊陣列的元素構成了逆序對)。沒**釋可能比較繞,本部落格也只是對本人的乙個記錄,就將就這麼寫吧。
下面是實現**:
#include #include void merge(int *a, int p1, int p2, int p3, long long &sum) else if(a[leftptr] > a[midptr])} if(leftptr == p2)
} else if(midptr == p3)
} for(int p=0; p= right - left) return;
for(int i=0; i
hihocoder1693 逆序異或和
時間限制 10000ms 單點時限 1000ms 記憶體限制 256mb 給定長度為n的序列a1,a2,an,求 其中xor是按位異或運算。第一行包含乙個整數n。第二行包含n個整數a1,a2,an。對於60 的資料,1 n 5000 對於100 的資料,1 n 100000,1 ai 100000 ...
HihoCoder1366 逆序單詞(字典樹)
時間限制 10000ms 單點時限 1000ms 記憶體限制 256mb 在英文中有很多逆序的單詞,比如dog和god,evil和live等等。現在給出乙份包含n個單詞的單詞表,其中每個單詞只出現一次,請你找出其中有多少對逆序單詞。第1行 1個整數,n,表示單詞數量。2 n 50,000。第2.n ...
NOIP2013 火柴排隊(逆序對)
涵涵有兩盒火柴,每盒裝有 n 根火柴,每根火柴都有乙個高度。現在將每盒中的火柴各自排成一列,同一列火柴的高度互不相同,兩列火柴之間的距離定義為 ai bi 2 其中 ai 表示第一列火柴中第 i 個火柴的高度,bi 表示第二列火柴中第 i 個火柴的高度。每列火柴中相鄰兩根火柴的位置都可以交換,請你通...