【剪枝】HDU 1010——tempter of the bone
来源:点击打开链接
看上去数据规模很小,但是必须要剪枝,否则直接爆TLE。
通过这个题可以练习奇偶剪枝。
另外:还有一个优化方式,如果所有步数走完了门还没关,则直接返回结果"NO".
#include <iostream> #include <cstring> #include <cmath> #include <cstdlib> using namespace std; int n,m,tarstep; int tari,tarj; int si,sj; char map[10][10]; int dir[4][2]={0,1,0,-1,1,0,-1,0}; int ok=0; void dfs(int si,int sj,int step) { int temp; if(si>n || sj>m || si<=0 || sj<=0) return; if(step==tarstep && si==tari && sj==tarj) ok=1; if(ok==1) return; //奇偶剪枝 temp=(tarstep-step)-abs(si-tari)-abs(sj-tarj); if(temp<0 || temp&1) return; for(int i=0;i<4;i++) { if(map[si+dir[i][0]][sj+dir[i][1]]!='X') { map[si+dir[i][0]][sj+dir[i][1]]='X'; dfs(si+dir[i][0],sj+dir[i][1],step+1); map[si+dir[i][0]][sj+dir[i][1]]='.'; } } return ; } int main() { while(cin>>n>>m>>tarstep) { if(n==0 && m==0 && tarstep==0) break; int wall=0; for(int i=1;i<=n;i++) //下标从1开始 { for(int j=1;j<=m;j++) { cin>>map[i][j]; if(map[i][j]=='S') { si=i; sj=j; } else if(map[i][j]=='D') { tari=i; tarj=j; } else if(map[i][j]=='X') wall++; } } if(n*m-wall<tarstep) //剪枝,如果能走的空地走完门没开 { cout<<"NO"<<endl; continue; } ok=0; map[si][sj]='X'; //初始化破坏掉 dfs(si,sj,0); if(ok==0) { cout<<"NO"<<endl; } else { cout<<"YES"<<endl; } } return 0; }