一、第一题:火柴排队
解题思路:归并排序
重点在于想清楚是对哪个数组进行归并排序求逆序对
【Python程序代码】
from math import *
n = int(input())
a = list(map(int,input().split()))
b = list(map(int,input().split()))
na,nb = [],[]
for i in range(n):
na.append([a[i],i])
nb.append([b[i],i])
na.sort()
nb.sort()
np = [0]*(n+5)
for i in range(n):
np[na[i][1]] = nb[i][1]
tep = [0]*(100005)
def merge_sort(q, l, r):
if l >= r: return 0
mid = (l + r) >> 1
res = merge_sort(q, l, mid) + merge_sort(q, mid + 1, r)
k, i, j = 0, l, mid + 1
while i <= mid and j <= r:
if q[i] <= q[j]:
tep[k] = q[i]
k, i = k + 1, i + 1
else:
res += mid - i + 1
tep[k] = q[j]
k, j = k + 1, j + 1
while i <= mid:
tep[k] = q[i]
k, i = k + 1, i + 1
while j <= r:
tep[k] = q[j]
k, j = k + 1, j + 1
j = 0
for i in range(l, r + 1):
q[i] = tep[j]
j += 1
return res
print( (merge_sort(np,0,n-1))%99999997)
二、第二题: 归并排序
解题思路:归并排序
归并排序模板题
【Python程序代码】
n = int(input())
a = list(map(int,input().split()))
tep = [0]*(n+5)
def merge_sort(q,l,r):
if l>=r:return
mid = (l+r)>>1
merge_sort(q,l,mid);merge_sort(q,mid+1,r)
k,i,j = 0,l,mid+1
while i<=mid and j<=r:
if q[i]<=q[j]:
tep[k] = q[i]
k,i=k+1,i+1
else:
tep[k] = q[j]
k,j=k+1,j+1
while i<=mid:
tep[k]=q[i]
k,i=k+1,i+1
while j<=r:
tep[k]=q[j]
k,j=k+1,j+1
j = 0
for i in range(l,r+1):
q[i]=tep[j]
j += 1
merge_sort(a,0,n-1)
for i in range(n):
print(a[i],end=" ")
三、第三题:逆序对的数量
解题思路:归并排序
归并排序求逆序对模板题
【Python程序代码】
n = int(input())
a = list(map(int,input().split()))
tep = [0]*(n+5)
def merge_sort(q,l,r):
if l>=r:return 0
mid = (l+r)>>1
res = merge_sort(q,l,mid)+merge_sort(q,mid+1,r)
k,i,j = 0,l,mid+1
while i<=mid and j<=r:
if q[i]<=q[j]:
tep[k] = q[i]
k,i=k+1,i+1
else:
res += mid - i + 1
tep[k] = q[j]
k,j=k+1,j+1
while i<=mid:
tep[k]=q[i]
k,i=k+1,i+1
while j<=r:
tep[k]=q[j]
k,j=k+1,j+1
j = 0
for i in range(l,r+1):
q[i]=tep[j]
j += 1
return res
print(merge_sort(a,0,n-1))
四、第四题:小朋友排队
解题思路:归并排序
归并排序求出每个数与其他数组成的逆序对数,然后求和公式累加
【Python程序代码】
n = int(input())
a = list(map(int, input().split()))
q,tep = [],[[0]*2 for _ in range(n+5) ]
for i in range(n):q.append( [a[i],i] )
sum = [0]*(n+5)
def merge(q,l,r):
if l>=r:return
mid = (l+r)>>1
merge(q,l,mid);merge(q,mid+1,r)
k,i,j=0,l,mid+1
while i<=mid and j<=r:
if q[i][0]<=q[j][0]:
tep[k]=q[i]
sum[q[i][1]] += j-mid-1
k,i = k+1,i+1
else:
tep[k]=q[j]
sum[q[j][1]] += mid-i+1
k,j = k+1,j+1
while i<=mid:
tep[k] = q[i]
sum[q[i][1]] += j-mid-1
k,i = k+1,i+1
while j<=r:
tep[k] = q[j]
k,j = k+1,j+1
j = 0
for i in range(l,r+1):
q[i]=tep[j]
j += 1
merge(q,0,n-1)
res = 0
for i in range(n):
res += (sum[i])*(sum[i]+1)//2
print(res)
五、第五题:超快速排序
解题思路:归并排序
归并排序求逆序对模板题
【Python程序代码】
import sys
tep = [0] * (500005)
def merge_sort(q,l,r):
if l>=r:return 0
mid = (l+r)//2
res = merge_sort(q,l,mid) + merge_sort(q,mid+1,r)
k,i,j = 0,l,mid+1
while i<=mid and j<=r:
if q[i]<=q[j]:
tep[k]=q[i]
k,i = k+1,i+1
else:
tep[k]=q[j]
res += mid-i+1
k,j = k+1,j+1
while i<=mid:
tep[k] = q[i]
k,i = k+1,i+1
while j<=r:
tep[k] = q[j]
k,j = k+1,j+1
j = 0
for i in range(l,r+1):
q[i] = tep[j]
j += 1
return res
n = int(sys.stdin.readline())
while n!=0:
a = []
for i in range(n):
a.append(int(sys.stdin.readline()))
print(merge_sort(a,0,n-1))
n = int(sys.stdin.readline())