根据地图,要求固定两点间最短路径的条数 。
这题的输入数据就是个坑,题目有没有说明数据之间有多个空格,结尾换行符之前也不止一个空格,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\n",(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 != '\n') 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\n", dfs(n-1,m-1)); 101 } 102 return 0; 103 }
其实可以直接用dp的这样似乎思路简单不少,不知道为什么我总是没想到这种简便方法,=、=
dp[i][j] = dp[i-1][j] + dp[i][j-1];