zoukankan      html  css  js  c++  java
  • UVA 825 Walkiing on the safe side

    根据地图,要求固定两点间最短路径的条数 。

    这题的输入数据就是个坑,题目有没有说明数据之间有多个空格,结尾换行符之前也不止一个空格,WA了好几遍,以后这种情况看来都要默认按照多空格的情况处理了。

    可以先利用bfs求出起点到各点的最短距离,然后dfs统计 num[x][y]表示起点到x,y的最短路径数,转移方程为 num[x][y] += num[nx][ny], nx = x +dx[k],ny = y + dy[k],

    map[nx][ny] != 0.

    代码:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <climits>
      4 #include <cstring>
      5 #include <cstdlib>
      6 #include <cmath>
      7 #include <vector>
      8 #include <queue>
      9 #include <algorithm>
     10 #define esp 1e-6
     11 #define pb push_back
     12 #define in  freopen("in.txt", "r", stdin);
     13 #define out freopen("out.txt", "w", stdout);
     14 #define print(a) printf("%d
    ",(a));
     15 #define bug puts("********))))))");
     16 #define Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++)
     17 #define inf 0x0f0f0f0f
     18 using namespace std;
     19 typedef long long  LL;
     20 typedef vector<int> VI;
     21 typedef pair<int, int> pii;
     22 typedef vector<pii,int> VII;
     23 typedef vector<int>:: iterator IT;
     24 #define N 200
     25 int map[N][N], vis[N][N], num[N][N];
     26 int dis[N][N];
     27 int n, m;
     28 int dx[] = {-1, 0, 1, 0};
     29 int dy[] = {0, 1, 0, -1};
     30 void init(void)
     31 {
     32     memset(map, -1, sizeof(map));
     33     memset(vis, 0, sizeof(vis));
     34     memset(num, 0, sizeof(num));
     35     memset(dis, 0, sizeof(dis));
     36 }
     37 void bfs(int x, int y)
     38 {
     39     int u = x*m+y;
     40     queue<int> q;
     41     q.push(u);
     42     vis[x][y] = 1;
     43     while(!q.empty())
     44     {
     45         int u = q.front();
     46         int x = u/m, y = u%m;
     47         q.pop();
     48 //        print(vis[0][1]) print(vis[1][0])
     49         for(int k = 0; k < 4; k++)
     50         {
     51             int nx = x + dx[k], ny = y + dy[k];
     52             if(nx >= 0 && nx < n && ny >= 0 && ny < m && !vis[nx][ny] && map[nx][ny])
     53             {
     54                 dis[nx][ny] = dis[x][y] + 1;
     55                 q.push(nx*m+ny);
     56                 vis[nx][ny] = 1;
     57             }
     58         }
     59     }
     60 }
     61 int dfs(int x, int y)
     62 {
     63     int ans = num[x][y];
     64         if(x == 0 && y == 0 && map[x][y])
     65         return num[x][y] = 1;
     66   if(ans > 0)
     67         return ans ;
     68     for(int k = 0; k < 4; k++)
     69     {
     70         int nx = x+dx[k], ny = y+dy[k];
     71         if(nx >= 0 && nx < n && ny >= 0 && ny < m && dis[nx][ny]+1 == dis[x][y] && map[nx][ny])
     72             ans += dfs(nx, ny);
     73     }
     74     return num[x][y] =  ans;
     75 }
     76 int main(void)
     77 {
     78     int T;
     79     for(int t = scanf("%d", &T); t <= T; t++)
     80     {
     81         if(t - 1)
     82             puts("");
     83         init();
     84         scanf("%d%d", &n, &m);
     85         char ch;
     86         for(int i = 0; i < n; i++)
     87         {
     88             int j;
     89             scanf("%*d");
     90             while((ch = getchar())== ' ') ;
     91             while(ch != '
    ')
     92             {
     93                 ungetc(ch, stdin);
     94                 scanf("%d", &j);
     95                 while((ch = getchar()) == ' ');
     96                 map[i][j-1] = 0;
     97             }
     98         }
     99         bfs(0, 0);
    100         printf("%d
    ", dfs(n-1,m-1));
    101     }
    102     return 0;
    103 }
    View Code

    其实可以直接用dp的这样似乎思路简单不少,不知道为什么我总是没想到这种简便方法,=、=

    dp[i][j] = dp[i-1][j] + dp[i][j-1];

  • 相关阅读:
    单链表反转
    C++面试题
    堆排序
    1链表:回文链表(leetcode 234)
    深信服社招linux岗面试记录
    腾讯后台开发社招记录(电话面试)
    小米社招ATE岗位记录
    诺基亚社招C++面试记录
    腾讯后台开发社招面试记录
    makefile笔记
  • 原文地址:https://www.cnblogs.com/rootial/p/3327827.html
Copyright © 2011-2022 走看看