两道搜索的题目,难度应该还差不多。。
1254推箱子有一点很重要,如果判断cur是不是目标点的话会超时,需要判断next是不是目标点。
即:
while(!q.empty())
{
cur=q.front();
q.pop();
if(cur==目标点) return 1;
............
}
这样会超时的,需要在把next加入队列的时候就判断它是不是目标点。,这点需要注意。。
1175连连看需要用到两个visit数组, 因为访问到该节点时有可能是竖直方向过来的,也有可能是水平方向过来的,需要用两个visit数组,分别记录在两个方向上的最小值。
贴下1175代码:
# include<stdio.h> # include<math.h> # include<string.h> # include<queue> # define N 1005 using namespace std; struct node{ int x,y,step; bool operator <(const node &a)const { return a.step<step; } int cp; }; int n,m,map[N][N],xx1,yy1,xx2,yy2; int visit1[N][N];//表示竖直方向上的 int visit2[N][N];//表示水平方向上的 int dir[4][2]={1,0,-1,0,0,-1,0,1}; int is(int x,int y) { if(x>=1 && x<=n && y>=1 && y<=m ) { return 1; } return 0; } int bfs() { int i; queue<node>q; node cur,next; cur.x=xx1; cur.y=yy1; cur.step=0; cur.cp=-1; q.push(cur); visit1[cur.x][cur.y]=0; visit2[cur.x][cur.y]=0; while(!q.empty()) { cur=q.front(); q.pop(); for(i=0;i<4;i++) { next=cur; next.x+=dir[i][0]; next.y+=dir[i][1]; if(next.cp==-1) next.cp=fabs(dir[i][0]); else if(next.cp!=fabs(dir[i][0])) { next.cp=fabs(dir[i][0]); next.step++; } if(next.step>2) continue; if(is(next.x,next.y)) { if(next.x==xx2 && next.y==yy2) return 1; if(map[next.x][next.y]!=0) continue; if(fabs(next.x-xx2)!=0 && fabs(next.y -yy2)!=0 && next.step==2) continue; if(next.cp==0) { if(visit1[next.x][next.y]==-1 || next.step<visit1[next.x][next.y]) { visit1[next.x][next.y]=next.step; q.push(next); } } else { if(visit2[next.x][next.y]==-1 || next.step< visit2[next.x][next.y]) { visit2[next.x][next.y]=next.step; q.push(next); } } } } } return -1; } int main() { int i,j,q,ans; while(scanf("%d%d",&n,&m)!=EOF) { if(n==0 && m==0) break; for(i=1;i<=n;i++) for(j=1;j<=m;j++) scanf("%d",&map[i][j]); scanf("%d",&q); while(q--) { scanf("%d%d%d%d",&xx1,&yy1,&xx2,&yy2); if(map[xx1][yy1]==0 || map[xx2][yy2]==0 ||map[xx1][yy1]!=map[xx2][yy2]) {printf("NO\n");continue;} memset(visit1,-1,sizeof(visit1)); memset(visit2,-1,sizeof(visit2)); ans=bfs(); if(ans==-1) printf("NO\n"); else printf("YES\n"); } } return 0; }