POJ3009题解

来源:互联网 发布:通信网络与信息技术 编辑:程序博客网 时间:2024/06/05 16:47
  • 《挑战》中开列的DFS习题之一;
  • 思维难度不大,读懂并直接模拟游戏规则即可;
  • 实际写起来坑不少,考验码程序的基本功;
  • 屡次WA,最后好不容易肉眼揪完错兴奋地交上去发现PE,再后来发现输出时没打‘\n’。。。
#include<cstdio>#include<algorithm>#include<vector>using namespace std;const int dy[5]={-1,1,0,0};const int dx[5]={0,0,-1,1};int N,M,brd[30][30],curstp,minstp;vector<int> anv;//多组测试时存答案用void dfs(int y,int x){    if(curstp>=10) return;//当前步数达到10时滚蛋    int ny,nx;    for(int i=0;i<4;i++)    {        if(y+dy[i]<1||y+dy[i]>N||x+dx[i]<1||x+dx[i]>M) continue;//一出门就掉出去不行(这是个容易被忽视的坑,因为下一句要使用出门第一步的坐标,所以这个出门第一步的坐标绝不能掉出去。)        if(brd[y+dy[i]][x+dx[i]]==1) continue;//一出门就撞上block也不行        ny=y;        nx=x;        for(;;)//一步一步走        {            ny+=dy[i];            nx+=dx[i];            if(ny<1||ny>N||nx<1||nx>M) break;//掉出去了不行            if(brd[ny][nx]==3)//从当前格走出去走到终点格就直接报喜,不进入终点格,这也是为什么上面步数达到10(而非超过10)时就要滚蛋。            {                minstp=min(minstp,curstp+1);                return;            }            if(ny+dy[i]<1||ny+dy[i]>N||nx+dx[i]<1||nx+dx[i]>M) break;//下一步掉出去不行(这是个容易被忽视的坑,因为下一句要使用下一步的坐标,所以这个下一步坐标绝不能掉出去。)            if(brd[ny+dy[i]][nx+dx[i]]==1)//撞到block了            {                brd[ny+dy[i]][nx+dx[i]]=0;                curstp++;                dfs(ny,nx);                curstp--;                brd[ny+dy[i]][nx+dx[i]]=1;                break;            }        }    }    return;}int main(){    int sy,sx;    for(;;)    {        scanf("%d%d",&M,&N);        if(!M) break;        curstp=0;//像这种OJ上的多组数据题,一定要注意变量的清零重置!清零重置!!清零重置!!!        minstp=0x3f3f3f3f;//同理        for(int i=1;i<=N;i++) for(int j=1;j<=M;j++)        {            scanf("%d",brd[i]+j);            if(brd[i][j]==2)//锁定起点格            {                sy=i;                sx=j;            }        }        dfs(sy,sx);//DFS        minstp>10?anv.push_back(-1):anv.push_back(minstp);    }    for(int i=0;i<anv.size();i++) printf("%d\n",anv.at(i));    return 0;}