POJ 3669 Meteor Shower
暴力DFS。
有2个剪枝:
1.记录一下走到某一格的最小步数
2.走到安全地点马上return
WA点:安全地点坐标不一定在300以内!
#include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<algorithm> using namespace std; const int INF=0x7FFFFFFF; const int maxn=300+10; int m,ans; int f[maxn][maxn],flag[maxn][maxn]; int dir[4][2]={ {0,1}, {0,-1}, {1,0}, {-1,0} }; bool P(int a,int b,int cnt) { if(a>=0&&a<=305&&b>=0&&b<=305&&flag[a][b]>cnt+1&&cnt+1<f[a][b]) return 1; return 0; } void dfs(int a,int b,int cnt) { if(f[a][b]==INF) { ans=min(ans,cnt); return; } for(int i=0;i<4;i++) { if(P(a+dir[i][0],b+dir[i][1],cnt)) { flag[a+dir[i][0]][b+dir[i][1]]=cnt+1; dfs(a+dir[i][0],b+dir[i][1],cnt+1); } } } int main() { while(~scanf("%d",&m)) { for(int i=0;i<306;i++) for(int j=0;j<306;j++) flag[i][j]=f[i][j]=INF; for(int i=1;i<=m;i++) { int xi,yi,ti; scanf("%d%d%d",&xi,&yi,&ti); f[xi][yi]=min(f[xi][yi],ti); for(int k=0;k<4;k++) { if(xi+dir[k][0]>=0&&xi+dir[k][0]<=305) if(yi+dir[k][1]>=0&&yi+dir[k][1]<=305) f[xi+dir[k][0]][yi+dir[k][1]]=min(f[xi+dir[k][0]][yi+dir[k][1]],ti); } } ans=INF; if(f[0][0]>0) { flag[0][0]=0; dfs(0,0,0); } if(ans==INF) ans=-1; printf("%d\n",ans); } return 0; }