原题目地址:附近最小
一、朴素法方法
【基本思路】
首先预处理出新数组new,它的含义是:new[i] = (a[i],i) ,并按a[i]值的大小进行排序。然后设置一个判断是否访问过的数组st[i],然后开始从小到大枚举new里面的每一个元素。在这里同爆搜无差别,小tips是当sum(st)==n时直接停止,可以省很多时间。不过蓝桥杯数据比较弱,能过,容易被一些极端数据hark掉。
【Python程序代码】
n = int(input())
a = list(map(int,input().split()))
k = int(input())
new = sorted([ (num,i) for i,num in enumerate(a) ] )
st = [0]*(n)
ans = [0]*(n)
for num,i in new:
for j in range(max(0,i-k),min(n,i+k+1)):
if st[j]==0:
st[j]=1
ans[j]=num
if sum(st)==n:break
for i in range(n):
print(ans[i],end=' ')
二、ST算法求解
【基本思路】
ST算法是求解RMQ问题的高效算法,本题刚好撞上求解静态区间的最小值。因此直接打ST算法的板子秒了。(被卡了两个点,pypy卡1个点)。。。
【Python程序代码】
from math import *
n = int(input())
a = [0] + list(map(int,input().split()))
kk = int(input())
N = n+10
dp = [[0]*(40) for _ in range(N)]
def st_init():
global dp
for i in range(1,n+1):dp[i][0]=a[i]
p = int(log2(n))
for k in range(1,p+1):
for s in range(1,n+2-(1<<k)):
dp[s][k] = min(dp[s][k-1],dp[s+(1<<(k-1))][k-1])
def st_query(L,R):
k = int(log2(R-L+1))
return min(dp[L][k],dp[R-(1<<k)+1][k])
st_init()
for i in range(1,n+1):
print( st_query(max(1,i-kk),min(n,i+kk)),end=' ')
三、单调队列求解
【基本思路】
用列表模拟栈,预处理出一个new数组,含义是new[i] = (a[i],i),由于使用单调队列,所以还需要在列表的尾部添加k个极大值元素,然后调用单调队列的板子。秒了。
【Python程序代码】
from collections import *
n = int(input())
a = [0] + list(map(int,input().split()))
k = int(input())
new = [ (num,i) for i,num in enumerate(a) ]
for i in range(n+1,n+k+1):
new.append((1000005,i))
q = []
for i in range(1,n+k+1):
while q and q[-1][0]>=new[i][0]:
q.pop()
q.append(new[i])
if q[0][1]<=i-2*k-1:q.pop(0)
if i>=k+1:print(q[0][0],end=' ')
四、线段树
【基本思路】
最基本的问题,直接套用线段树的板子就可以了。 (不过由于n是10⁶的量级卡了1个点)
【Python程序代码】
n=int(input())
def push_up(p):
tree[p]=min(tree[p<<1],tree[p<<1|1])
def query(p,pl,pr,L,R):
if pl>R or pr<L:
return 1<<64
if L<=pl and pr<=R:
return tree[p]
mid=(pl+pr)>>1
return min(query(p<<1|1,mid+1,pr,L,R),query(p<<1,pl,mid,L,R))
def build(p,pl,pr):
if pl==pr:
tree[p]=a[pl]
else:
mid=(pl+pr)>>1
build(p<<1,pl,mid)
build(p<<1|1,mid+1,pr)
push_up(p)
a=[0]+list(map(int,input().split()))
tree=[0 for _ in range(n<<2+1)]
build(1,1,n)
k=int(input())
for i in range(1,n+1):
x=max(1,i-k)
y=min(n,i+k)
print(query(1,1,n,x,y),end=' ')