題目就簡單的貼上以下:
題目描述 description
有兩個長度為 n 的序列 a 和 b,在 a 和 b 中各任取乙個數可以得到 n^2 個和,求這n^2 個和中最小的 n個。
輸入描述 input description
第一行輸入乙個正整數n;第二行n個整數ai 且ai≤10^9;第三行n個整數bi,
且bi≤10^9
輸出描述
output description
輸出僅一行,包含 n 個整數,從小到大輸出這 n個最小的和,相鄰數字之間用
空格隔開。
樣例輸入
sample input
5 1 3 2 4 5
6 3 4 1 7
樣例輸出 sample output
2 3 4 4 5
此題需要注意的是必須先對兩個輸入陣列進行排序,亂序的資料量n^2太大,陣列存不下。然後就是時間複雜度的問題,必須過濾掉一部分資料。對於有序陣列a[i],b[j].i*j-1>n的資料是無效的資料。因為已經存在了n個更小的資料。例如當n = 100的時候,i=5,j=20時,(i=1,2,3,4且j<=20) 和( i=5且j<20)的資料一定比a[5]+b[20]小,所以已經存在了100個很小的資料了就不需要比較後續的資料了。完全可以忽略。至於i*j-1的-1是因為i,j這組資料並沒有算進去。
因為需要聯絡堆排序,就使用了堆排序做題:
#include#include#include
using
namespace
std;
#define max_num 100005
int heaparr[max_num*100
];int heapcount = 1
;int
a[max_num];
intb[max_num];
void insert(int
a);int
pop();
intmain()
for (int i = 0; i < n; i++)
sort(a, a +n);
sort(b, b +n);
for (int i = 0; i < n; i++)
}for (int i = 0; i < n; i++)
cout
}void insert(int
a)
else
}//if (heapcount//
想當然的進行了資料忽略,然後發現忽略是錯誤的,對於堆排序本身,葉子節點的數並不代表是很大的數,可能葉子節點的數小於根節點的另乙個孩子(次節點的祖先的兄弟節點)。
heapcount++;
}int
pop()
else
break
; }
else
else
break
; }
}else
else}}
return
ans;
}
犯了乙個錯誤,記錄一下:
//if (heapcount//想當然的進行了資料忽略,然後發現忽略是錯誤的,對於堆排序本身,葉子節點的數並不代表是很大的數,可能葉子節點的數小於根節點的另乙個孩子(次節點的祖先的兄弟節點)。
Wiki OI 1245 最小的N個和
演算法與思路 k路歸併 堆 優先佇列 k路歸併具體請參考劉汝佳 演算法競賽入門經典訓練指南 p189 題目要求從兩個長度為n的數列中各取出一數相加,可得到n n個和,輸出這些和公升序的前n項 由於資料太大,不能通過先求和再排序的方式來求解,這個時候就要用到堆了 首先將a,b兩陣列排序,然後將a i ...
codevs1245 最小的N個和
題目描述 description 有兩個長度為 n 的序列 a 和 b,在 a 和 b 中各任取乙個數可以得到 n 2 個和,求這n 2 個和中最小的 n個。輸入描述 input description 第一行輸入乙個正整數n 第二行n個整數ai 且ai 10 9 第三行n個整數bi,且bi 10 ...
codevs 1245 最小的N個和
題目描述 description 有兩個長度為 n 的序列 a 和 b,在 a 和 b 中各任取乙個數可以得到 n 2 個和,求這n 2 個和中最小的 n個。輸入描述 input description 第一行輸入乙個正整數n 第二行n個整數ai 且ai 10 9 第三行n個整數bi,且bi 10 ...