洛谷 P1090 【合併果子】題解
阿新 • • 發佈:2019-02-06
題目傳送門
各位又是priority queue又是heap的,做了個弱點的,送上來
策略很簡單,每次拿兩個最小的和並,這個用堆來做簡直就是送分題
但是我那個時候還不會堆,所以這裡採用的方法是
1、走來做一次快排,使得這些堆升序
2、合併最前面的兩個(也就是兩個最小的)
3、冒泡,剛剛合併的冒泡到合適的位置
#include <stdio.h>
#define MAX 10000
extern int a[];
int n;
int main()
{
double sum = 0;
scanf("%d",&n);
void quickSort(int l, int r);//快排
void f5(int changeIndex);//由兩個相加所得到的堆放進去
for (int i = 1; i <= n; i++){
scanf("%d",&a[i]);
}
quickSort(1, n);//從小到大放進去
for (int i = 2; i<=n; i++){
a[i] += a[i - 1];//把小heap搬到大heap
a[i - 1] = -1;//被拿走的空地不妨置個-1
sum += a[i];//record(記錄)一下體力花費
f5(i);//由於大的heap可能不是下輪要操作的兩個heap的其中之一,所以要重新整理下這個由heap組成的list
}
printf("%.0lf",sum);
return 0;
}
int a[MAX + 1];
void quickSort(int l,int r) {//最弱的快排
if (l >= r)return;
int i = l, j = r, base = a[l];
while (i<j) {
while (i < j && a[j] >= base)j-- ;
while (i < j && a[i] <= base)i++;
if (i < j) { int t = a[i]; a[i] = a[j]; a[j] = t; }
}
int t = a[i]; a[i] = a[l]; a[l] = t;
quickSort(l, i - 1);
quickSort(i+1,r);
}
void f5(int changeIndex) {//新堆的位置
int ci = changeIndex,c=a[ci];
if (ci >= n + 1)return;
for (int i = ci;a[i] > a[i + 1] &&i+1<=n; i++){//由於新堆只可能更大,所以用冒泡把它放到次序正確的位置,請注意,這個冒泡的範圍只可能<=原list的範圍
int t = a[i]; a[i] = a[i + 1]; a[i + 1] = t;//最弱的交換法
}
}