zoukankan      html  css  js  c++  java
  • 拜访

    拜访

    题目描述

    现在有一个城市销售经理,需要从公司出发,去拜访市内的商家,已知他的位置以及商家的位置,但是由于城市道路交通的原因,他只能在左右中选择一个方向,在上下中选择一个方向,现在问他有多少种方案到达商家地址。

    给定一个地图map及它的长宽nm,其中1代表经理位置,2代表商家位置,-1代表不能经过的地区,0代表可以经过的地区,请返回方案数,保证一定存在合法路径。保证矩阵的长宽都小于等于10。

    测试样例:
    [[0,1,0],[2,0,0]],2,3
    返回:2

    牛客网题解:

    链接:https://www.nowcoder.com/questionTerminal/12cbdcdf5d1e4059b6ddd420de6342b6
    来源:牛客网

    想说的是题目描述有点模糊,通过测试才发现,“他只能在左右中选择一个方向,在上下中选择一个方向”应该理解为:左右中只能选一个方向,若选择左只能一直向左走。上下中只能选择一个方向,若选择下只能一直向下。
    解题思路:
    1.首先找到1和2的位置,这里要注意一点,从1走到2与从2走到1所得的路径数相同,即以1为起点或以2为起点是等价的。所以我做的处理是,统一从行坐标小的位置走到行坐标大的位置,即向下走。
    2.1和2的相对位置可以归纳如下:
    (1)两者位于主对角线上
    (2)两者位于副对角线上
    (3)两者位置重合或处于同一行或同一列(该特殊情形可以合并到(1)(2)中)

    3.接下来的问题就是分别对向左走和向右走的情形应用动态规划求解。
    4.代码如下,已AC。
     1 public int countPath(int[][] map, int n, int m) {
     2     // 首先找出1和2所在的位置
     3     int i,j;
     4     int x1=0,x2 = 0,y1 = 0,y2 = 0;
     5     for (i = 0; i < n; i++) {
     6         for (j = 0; j < m; j++) {
     7             if(map[i][j]==1){
     8                 x1 = i;y1=j;
     9             }else if(map[i][j]==2){
    10                 x2=i;y2=j;
    11             }
    12         }
    13     }      
    14     if(x1==x2&&y1==y2){// 两点重合
    15         return 1;
    16     }
    17     if(x1>x2){// x1,y1用于保存行下标的较小者
    18         x1 = x1^x2^(x2=x1);
    19         y1 = y1^y2^(y2=y1);
    20     }
    21     int dp[][] = new int[n][m];
    22     if(y1<y2){// 两点处在主对角线上
    23         dp[x1][y1] = 1;
    24         for (i = x1+1; i<=x2; i++) {
    25             dp[i][y1] = map[i][y1]==-1?0:dp[i-1][y1];
    26         }
    27         for (j = y1+1; j <=y2; j++) {
    28             dp[x1][j] = map[x1][j]==-1?0:dp[x1][j-1];
    29         }
    30         for (i = x1+1; i <= x2; i++) {
    31             for (j = y1+1; j <=y2; j++) {
    32                 dp[i][j] = map[i][j]==-1?0:dp[i-1][j]+dp[i][j-1];
    33             }
    34         }
    35     }else{// 两者处在副对角线上
    36         dp[x1][y1] = 1;
    37         for (i = x1+1; i<=x2; i++) {
    38             dp[i][y1] = map[i][y1]==-1?0:dp[i-1][y1];
    39         }
    40         for (j = y1-1; j >=y2; j--) {
    41             dp[x1][j] = map[x1][j]==-1?0:dp[x1][j+1];
    42         }
    43         for (i = x1+1; i <= x2; i++) {
    44             for (j = y1-1; j >=y2; j--) {
    45                 dp[i][j] = map[i][j]==-1?0:dp[i-1][j]+dp[i][j+1];
    46             }
    47         }
    48     }
    49     return dp[x2][y2];
    50 }
  • 相关阅读:
    4.angularJS-指令(directive)
    3.AngularJS-过滤器
    Codeigniter处理用户登录验证后URL跳转
    为nginx配置https并自签名证书
    使用OpenSSL自签发服务器https证书
    用tomcat配置https自签名证书,解决 ios7.1以上系统, 苹果inHouse发布
    对称加密 和 非对称加密 的区别是什么
    **CodeIgniter系列 添加filter和helper
    **CodeIgniter通过hook的方式实现简单的权限控制
    php面向对象中public与var的区别
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/7736750.html
Copyright © 2011-2022 走看看