P1: 和至少為 K 的最短子陣列
Leetcode 862
原題一點沒改,
P2: 滑動拼圖
Leetcode 773
2
×
3
2\times3
2×3改成了
3
×
3
3\times3
3×3,
原本可以直接DFS或者A-start搜索,但是,現在會T,終止狀態也不好用了,
用優先佇列去維護, 計算和最終狀態的差值,相同step的情況下, 優先選擇差距小的,
可以在優化一些, 排除一些,
import heapq
import collections
class Solution:
"""
@param init_state: the initial state of chessboard
@param final_state: the final state of chessboard
@return: return an integer, denote the number of minimum moving
"""
def minMoveStep(self, board, target):
R, C = len(board), len(board[0])
P = [1] * (R * C)
for i in range(1, R*C):
P[i] = 10 * P[i-1]
f = lambda A: sum(A[i][j] * P[i*C + j] for i in range(R) for j in range(C))
rs, cs = -1, -1
for i in range(R):
for j in range(C):
if board[i][j] == 0:
rs, cs = i, j
def trans(r, c, state, nr, nc):
k0 = r * C + c
k1 = nr * C + nc
digit = (state // P[k1])% 10
return state - digit * P[k1] + digit * P[k0]
s_state = f(board)
f_state = f(target)
dist_to_f_state = lambda x: abs(x - f_state)
d = collections.defaultdict(int)
d[s_state] = 0
Q = [(0, dist_to_f_state(s_state), rs, cs, s_state)]
while Q and f_state not in d:
_, _, r, c, state = heapq.heappop(Q)
for dx, dy in [[1,0], [-1, 0], [0,1], [0, -1]]:
nr, nc = r + dx, c + dy
if 0<= nr < R and 0 <= nc < C:
nstate = trans(r, c, state, nr, nc)
if nstate not in d or d[nstate] > d[state] + 1:
d[nstate] = d[state] + 1
heapq.heappush(Q, (d[nstate], dist_to_f_state(nstate),nr, nc, nstate))
return -1 if f_state not in d else d[f_state]
P3. 地圖跳躍
題目
在正方形的地圖上, 從左上角(0, 0)跳到(n-1, n-1)的所需要的d的最小值,
對于d的定義是: 如果相鄰兩個格子之間的絕對值差值小于等于d,那么他們可以跳來跳去,
n
≤
1000
n\le1000
n≤1000,
0
≤
a
r
r
[
i
]
≤
1
0
5
0\le arr[i]\le 10^5
0≤arr[i]≤105
解
- d具有單調性, 如果x滿足,那么大于x的點也滿足, 而且我們知道答案在 [ 0 , 1 0 5 ] [0, 10^5] [0,105]中,
- 二分+驗證,
class Solution:
def mapJump(self, A):
n = len(A)
inf = 10 ** 5
def canReach(target):
f = lambda x: x[0] * n + x[1]
vis = {f([0, 0])}
Q = [[0,0]]
while Q:
x, y = Q[0]
del Q[0]
for dx, dy in [[0, 1], [0, -1], [1, 0], [-1, 0]]:
nx, ny = x + dx, y + dy
if 0 <= nx < n and 0 <= ny < n and f([nx, ny]) not in vis and abs(A[x][y] - A[nx][ny]) <= target:
Q.append([nx, ny])
vis.add(f([nx, ny]))
return f([n-1, n-1]) in vis
L, R = 0, inf
while L < R:
mid = (L + R) >> 1
if canReach(mid):
L, R = L, mid
else:
L, R = mid+1, R
return R
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/89317.html
標籤:其他
上一篇:紀中周末訓練 2020.09.19【NOIP提高B組】模擬 T1:音樂節拍
下一篇:410c的串口通訊
