座標[0,0]から座標[m-1、n-1]まで、地面にm行n列のグリッドがあります。ロボットは座標[0、0]のグリッドから開始し、一度に1つのグリッドを左、右、上、下に移動できます(グリッドの外に移動できません)。また、行と列の座標を入力できません。数字の合計は、 kの格子。たとえば、kが18の場合、3 + 5 + 3 + 7 = 18であるため、ロボットは正方形[35、37]に入ることができます。しかし、3 + 5 + 3 + 8 = 19であるため、正方形[35、38]に入ることができません。ロボットが到達できるグリッドはいくつですか?
例1:
入力:m = 2、n = 3、k = 1
出力:3
例2:
入力:m = 3、n = 1、k = 0
出力:1
ヒント:
1 <= n、m <= 100
0 <= k <= 20
出典:LeetCode
リンク:https ://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof
著作権は控除ネットワークに属しています。商用転載の正式な許可書に連絡し、非商用転載の出典を明記してください。
ディレクトリ
アイデア1:ディープサーチ(dfs)
開始点(0、0)から始めて、4方向に検索すると、継続できる条件は、座標の数がK以下であることです。
従来のディープサーチは4つの方向にありますが、この質問は次のように最適化できます。
class Solution:
def movingCount(self, m: int, n: int, k: int) -> int:
# 暴力
self.cnt = 0
self.n = n
self.m = m
self.k = k
self.visit = [[0]*n for _ in range(m)]
self.dx = [0, 1] # 优化为只:向右、向下
self.dy = [1, 0]
self.visit[0][0] = 1
self.dfs(0, 0)
return self.cnt
def dfs(self, x, y):
ti = x
tj = y
t = 0
while ti > 0:
t += ti % 10
ti = ti // 10
while tj > 0:
t += tj % 10
tj = tj // 10
if t <= self.k:
self.cnt += 1
else:
return
for i in range(2):
xx = x + self.dx[i]
yy = y + self.dy[i]
if 0 <= xx < self.m and 0 <= yy < self.n and self.visit[xx][yy] == 0:
self.visit[xx][yy] = 1
self.dfs(xx, yy)
アイデア2:Guangsuo(bfs)
Guangsouはキューを使用して実装されており、この質問ではsetを使用して重複排除します。
def digitsum(n):
ans = 0
while n:
ans += n % 10
n //= 10
return ans
class Solution:
def movingCount(self, m: int, n: int, k: int) -> int:
from queue import Queue
q = Queue()
q.put((0, 0))
s = set()
while not q.empty():
x, y = q.get()
if (x, y) not in s and 0 <= x < m and 0 <= y < n and digitsum(x) + digitsum(y) <= k:
s.add((x, y))
q.put((x, y + 1))
q.put((x + 1, y))
return len(s)
アイデア3:再帰
def digitsum(n):
ans = 0
while n:
ans += n % 10
n //= 10
return ans
class Solution:
def movingCount(self, m: int, n: int, k: int) -> int:
s = set([(0, 0)])
for i in range(m):
for j in range(n):
if ((i-1,j) in s or (i,j-1) in s) and digitsum(i) + digitsum(j) <= k:
s.add((i, j))
return len(s)