我先贴两张图
图片说明
这是输入为11,30,30时的边界示意图。绿色的是不能到达的方块。白色的是可以到达的方块。
图片说明
这是输入参数是15,20,20时的示意图。
通过图我们可以发现:
1.第一行和第一列的数位之和是一一对应的,都是0到9,1到10,2到11这样增长的。而算出第一行和第一列的数位之和后,其他格子的数位之和可以通过其对应的首行首列轻易算出来的。例如sum(3,4)=sum(3,0)+sum(0,4)=3+4=7。
2.因为绿***域都是楼梯形的,所以我们找到第一行的第一个绿色块后(因为第一行竖轴的数位之和是0,所以横轴能达到最远的距离),沿着它往左下方画楼梯,楼梯右下方的方块一定是机器人到不了的,只有左上方的方块是有机会到达的。
3.为什么楼梯左上方的方块是有机会到达而不是一定呢?因为除了第一行,其他行的竖轴的数位之和至少是1,所以他们能达到的最大的横轴的数位之和是一定小于第一行的,对第一行来说符合要求的横轴的数位之和,其他行没准就不符合了。
4.在楼梯的左上方区域,除边界外的不能达到的方块一定是与边界分离的。看看第9列和第10列的横轴的数位之和,9后面是1,差距这么大怎么连?
所以,只要第一行是连通的,那其他行的可到达方块就一定可达,不用担心被绿色方块包起来而到不了。
而第一行我们找的就是第一块绿色方块,所以第一行一定是连通的。
5.所以,只有第一行是需要去找第一个绿色方块的(当然,如果找到头也没找到,那第一行的可达方块数量就是横轴长度),其他行只要数可达方块的数量就可以了。
思路就是这样的,如果有考虑不全的地方,欢迎指正。
看别的题解提到什么BFS,百度下是什么“宽度优先搜索算法”,因为没听说过,所以先去学习啦,代码凑活看吧
最后,贴上代码:

public class Solution {
    public int movingCount(int threshold, int rows, int cols)
    {
        if(rows==0||cols==0){
            return 0;
        }
        if(threshold<0){
            return 0;
        }
        int edge=0;
        int max=rows;
        if(cols>rows){
            max=cols;
        }
        int[] base=new int[max];
        //找到第一行第一个禁区方块,同时初始化第一行和第一列
        do{
            int sum=0;
            int buf=edge;
            while(buf!=0){
                sum+=buf%10;
                buf/=10;
            }
            if(edge<max){
                base[edge]=sum;
            }
            if(sum==(threshold+1)){
                break;
            }
            edge++;
        }while(true);

        int amount=0;     //累计器,用来统计能达到的方块个数
        if(edge==0)
            return 0;
        if(edge>=cols){
            amount=cols;
        }else{
            amount=edge;
        }
        edge--;
        for(int i=1;i<rows;i++){
            int limit=cols;
            if(edge==0){
                break;
            }
            if(edge<cols){
                limit=edge;
            }
            for(int j=0;j<limit;j++){
                if((base[i]+base[j])<=threshold){
                    amount++;
                }
            }
            edge--;
        }
        return amount;
    }
}