略,見鏈結
略,見鏈結
略,見鏈結
1 08
10^8
108級
首先看到題幹就知道要用貪心+排序。
迴圈模擬比賽,一次迴圈算一場比賽,那麼就要每次迴圈之後排個序。
看到資料範圍是一億級的,發現用o(
n2
)\operatorname(n^2)
o(n2
)的冒泡選擇什麼的會tle。就想到用o(
nlogn
)\operatorname(n\operatornamen)
o(nlog
n)的歸併/快排。在這裡我決定用std::sort()
[滑稽](然鵝sort會爆時間,於是我用歸併)。
關於歸併排序
歸併排序的思想就是合併兩個同序陣列的線性方式——每次比較兩個有序陣列指標指向的值,誰更小(大)則放到temp陣列裡,然後刪掉進入temp的元素,指標++。
於是**就不難理解。
偽**如下
function merge(arr, l, r)
'歸併排序, arr為待排序陣列,l、r為陣列左右指標。
if l = r
exit
m =(l + r)/2
'----分解----
call merge(arr, l, m)
'遞迴呼叫,分解
call merge(arr, m +
1, r)
'同上'----合併----
i = l, j = m +
1, p = l
while i <= m and j <= r
if a[i] > a[j] then
p = p +
1 i = i +
1 temp[p] = a[i]
endifelse
p = p +
1 j = j +
1 temp[p] = a[j]
endelse
endwhile
while i <= m
p = p +
1 i = i +
1 temp[p] = a[i]
endwhile
while j <= r
p = p +
1 j = j +
1 temp[p] = a[j]
endwhile
'----轉移----
for k = l to r step
1'k從l
a[i] = temp[i]
endforend
function
那麼整理整理,就成了這次題解**。
c ++
c++c+
+:
#include
using
namespace std;
int n, r, q;
int a[
200100
], win[
200100
], lose[
200100];
int s[
200100
], w[
200100];
bool
cmp(
int x,
int y)
void
merge()
intmain()
else
merge()
;}cout << a[q]
;return0;
}
2023年noip普及組第3題 ↩︎ 題解 P1309 瑞士輪
一開始只因為是結構體快排,不幸tle了 仔細一想,將sort換成了stable sort居然過了。原來每次改變的只是相鄰的,所以sort會浪費大量時間。之後跑來看題解,發現是清一色的歸併 獻上又醜又短的 1 include2 namespace zdy6 namespace fast,f b nam...
洛谷1309 瑞士輪 題解
我覺得我大概已經是個zz了,普及題都不會做還得看題解,難受。o rnlogn 肯定過不了 過了也沒意義 複雜度能降下來肯定序列是有規律可循的。於是可以發現,勝者組和敗者組他們的s永遠都是單調減的。然後就把兩個有序的勝者組和敗者組合並就行了,和歸併排序差不多。我的智商已如風中殘燭。include in...
瑞士輪(歸併)
2 n名編號為1 2n的選手共進行r輪比賽。每輪比賽開始前,以及所有比賽結束後,都會對選手進行一次排名。排名的依據是選手的總分。選手的總分為第一輪開始前的初始分數加上已參加過的所有比賽的得分和。總分相同的,約定編號較小的選手排名靠前。每輪比賽的對陣安排與該輪比賽開始前的排名有關 第1名和第2名 第3...