一直wa,搜索真不愧是我的最大弱点。
剪枝判断没做好,加入队列条件也没有控制好
1.广搜省时间。。大神XX当时集训用深搜一次搞定了。。差距啊。。
2.每次搜都直接搜到底。
3.先标记一下今天惨烈错误的地方,有空将错误过程写上去
贴一下
#include <stdio.h> #include <queue> using namespace std; #define maxn 101 int x1,x2,y1,y2,n,m,K; int vis[maxn][maxn] , stp[maxn][maxn] , dir[maxn][maxn]; int tn , tx , ty , nx , ny , ts; const int dx[] = {0,1,0,-1}; const int dy[] = {1,0,-1,0}; int maz[maxn+10][maxn+10]; bool is_ok(int x,int y){ return x>=0&&x<n&&y<m&&y>=0&&maz[x][y]=='.'; } bool bfs(){ memset(vis, 0 , sizeof(vis)); queue<int> q;stp[x1][y1] = 0; K++; q.push(x1*m+y1); vis[x1][y1] = 1; dir[x1][y1]=-1; while(!q.empty()){ tn = q.front(); q.pop(); tx = tn / m , ty = tn % m; if(stp[tx][ty] > K) continue; if(stp[tx][ty] <= K && tx==x2&&ty==y2) return true; for(int i=0;i<4;i++){ nx = tx + dx[i] , ny = ty + dy[i]; while(is_ok(nx,ny)){ if(vis[nx][ny]==0){ vis[nx][ny] = 1; dir[nx][ny] = i; if(dir[tx][ty]==i) stp[nx][ny]=stp[tx][ty]; else if(dir[tx][ty]==-1||dir[tx][ty]!=i) stp[nx][ny] = stp[tx][ty]+1; if(nx==x2&&ny==y2&&stp[nx][ny]<=K) return true; q.push(nx*m+ny); } nx += dx[i] , ny += dy[i]; } } }return false; } int main(){ int T;char ma[110]; scanf("%d",&T); while(T--){ scanf("%d %d",&n,&m); memset(maz,0,sizeof(maz)); for(int i=0;i<n;i++){ scanf("%s",ma); for(int j=0;j<m;j++) maz[i][j] = ma[j]; } scanf("%d %d %d %d %d",&K,&y1,&x1,&y2,&x2); y1--,x1--,y2--,x2--; puts(bfs() ? "yes" : "no"); } return 0; }
S点是一个相遇的点,从路径c和路径f过来都是可以到达的,这里先不考虑转折的问题。每次搜索找沿每个方向找到最底
1.每次一次搜索到尽头的方法一定使得被搜索点一定最优,转折最少(两点间直线最短)
2.像S点,假设一种情景,沿f,c路径到达S点的转折数是一样的,而且c路径先到达,那么f路径经过该点如何处理?
3.由于S被搜索过了,但是,队列中S点还没有往上下方向移动,所以,应该继续搜索下去。PS:之前在S点停止搜索了。