牛客#机器人的运动范围

14 篇文章 0 订阅
2 篇文章 0 订阅

Description

地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?

Code

一开始没注意到机器人一次只移动一格,所以写的代码是计算所有格内满足行列坐标数位之和小于等于k的格子数,算是更厉害一些吧,哈哈!

# -*- coding:utf-8 -*-
class Solution:
    def movingCount(self, threshold, rows, cols):
        # write code here
        if threshold == 0:
            return 0
        index = {}
        for i in range(rows):
            cnt = self.cnt(i)
            if cnt <= threshold:
                if cnt in index:
                    index[cnt] += 1
                else:
                    index[cnt] = 1
            else:#去掉就是算除去一次一步条件下机器人可达的格子数
                break#去掉就是算除去一次一步条件下机器人可达的格子数
        res = 0
        for i in range(cols):
            cnt = self.cnt(i)
            if threshold - cnt >= 0:
                for j in index:
                    if j + cnt <= threshold:
                        res += index[j]
            else:#去掉就是算除去一次一步条件下机器人可达的格子数
                break;#去掉就是算除去一次一步条件下机器人可达的格子数
        return res

    def cnt(self, num):
        res = num % 10
        num /= 10
        while num:
            res += num % 10
            num /= 10
        return res

该算法的设计思路恰巧就是因为我没注意到一次只能走一步的条件,所以想到了这样的用例:
k = 7, row = 15, col = 13,当col = 0时,row允许的值是0-710-14。注意到了吗,中间是会断开的!10-14区间段也被允许是因为它们位数和加起来后相当于1-5!这样的话,其实可以在算到1-5时就每格多算一格,因为10-14这里也会重复。所以我就想到了将index当成系数表示该行可以算作几格,这样就不用把所有的行都算一遍了。
事实上,col也可以进行相同的处理,我去更改下代码好了。

Code 改进版

# -*- coding:utf-8 -*-
class Solution:
    def movingCount(self, threshold, rows, cols):
        # write code here
        if threshold == 0:
            return 0
        row = self.calIndex(rows, threshold)
        col = self.calIndex(cols, threshold)
        res = 0
        for i in range(len(col)):
            minus = threshold - i
            if minus >= 0:
                for j in row[:minus + 1]:
                    res += j * col[i]
        return res

    def calIndex(self, line, threshold):
        index = [0] * line
        for i in range(line):
            cnt = self.cnt(i)
            if cnt <= threshold:
                index[cnt] += 1
            else:#去掉就是算除去一次一步条件下机器人可达的格子数
                break#去掉就是算除去一次一步条件下机器人可达的格子数
        return index

    def cnt(self, num):
        res = num % 10
        num /= 10
        while num:
            res += num % 10
            num /= 10
        return res

这下就更加精简了,总的思想就是行列都算出来每一格等同于多少格,然后相乘即可,好好体会下吧,自己画个图应该就明白了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值