HNUST 挑戰ACM迷宮(DFS版)
阿新 • • 發佈:2019-02-13
題目描述
如下圖所示的是一個由程式設計題目組成的ACM迷宮。迷宮的左上角是入口,右下角是出口。迷宮中每一個格子都有一個程式設計題目,挑戰者要AC該題目後才能通過,大於0的數字表示AC該題目所需的最短時間。數字如果是0表示是陷阱,進去了就出不來。現在的問題是:求挑戰者從入口到出口所需的最短時間。
輸入
有多組測試例項。
對於每組測試例項,先輸入一個數字n(1<n<=100),然後輸入n*n個數字表示迷宮中的數字。
輸出
對應輸出挑戰者從入口到出口所需的最短時間。
樣例輸入
10 1 0 2 1 2 3 4 2 2 5 2 1 0 1 3 2 5 7 2 1 1 1 1 0 1 1 1 3 2 3 1 2 1 1 0 1 1 1 2 3 1 1 2 0 2 0 2 3 2 3 2 2 2 2 3 2 0 2 3 2 3 2 2 2 1 1 1 0 1 1 0 1 1 3 0 1 1 2 3 2 2 0 1 1 2 2 2 2 2 2 3 2 3 2 3 2 3 2 3 2 5 1 2 1 2 5 1 3 2 4 5 2 1 0 2 5 2 1 1 2 1 2 4 1 1 2
樣例輸出
min=29 min=11
題意:就是從起點走到終點,求最短路
解題思路:我用的是DFS,當然也可以BFS,甚至DP。dfs有4個方向,採用記憶化搜尋,記錄每一個點的最短路路徑,當然,這樣還是會超時。再網dfs引數中加一個sum,表示當前的步數,如果大於ans就終止。最後要注意,要把迷宮中的0設為不可以走的牆壁,別設定為一個很大的數,否則dfs還是會搜尋下去。
#include <bits/stdc++.h> using namespace std; int n; int z[110][110]; int vis[110][110]; int dir[4][2]={1,0,0,1,-1,0,0,-1}; int ans; void dfs(int x,int y,int sum)//加一個sum是用來剪枝的 { if(x==n && y==n)//到達終點 { ans=sum; return ; } if(sum>ans) return ;//當前這點的和已經大於終點的了,直接剪去 for(int i=0;i<4;i++) { int xx,yy; xx=x+dir[i][0]; yy=y+dir[i][1]; if(xx>=1 && yy>=1 && x<=n && yy<=n && z[xx][yy]!=0) { if(vis[xx][yy]==-1)//該點沒被訪問過 { vis[xx][yy]=z[xx][yy]+vis[x][y]; dfs(xx,yy,vis[xx][yy]); } else if(vis[xx][yy]>z[xx][yy]+vis[x][y])//該點被訪問過了,但是不是最優 { vis[xx][yy]=z[xx][yy]+vis[x][y]; dfs(xx,yy,vis[xx][yy]); } } } } int main() { while(scanf("%d",&n)==1) { for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) { scanf("%d",&z[i][j]); vis[i][j]=-1; } vis[1][1]=z[1][1]; ans=100000; dfs(1,1,z[1][1]); printf("min=%d\n",vis[n][n]);//ans和vis[n][n]是一樣的 } return 0; }