hdu 3912 Turn Right

http://acm.hdu.edu.cn/showproblem.php?pid=3912


这个题我用递归深搜模拟,直接爆栈了。哭啊!为什么!

这个题最主要是能走重复格子,但是方向不一样。

我用的剪枝条件:
        1、判断有没有走出迷宫,走出迷宫了直接退出。
        2、由于题目要求只要判断有没有把所有格子走完,则可以用一个计数器统计走过格子的数量(重复走的不算)。走完了所有格子则直接退出搜索。
        3、在这个格子,当前走的方向以前走过,则重复了(判重)
别人的代码贴在最后面吧。。
我自己爆栈的代码 大哭
#include<iostream>

#include<cstdio>

#include<cstring>



using namespace std;



int r,c,enty,exitx,exity;

int yn,sum;               //yn用于标记是否走出迷宫,sum记录走过几个格子

int map[510][510][5];     //地图,最后一个代表这个格子的边缘是否有墙,map[i][j][]代表ij这个格子的上下左右是否有墙

int dis[510][510][5];     //标记



struct Node

{

    int x,y;   //当前坐标位置

    int fx;    //当前前进方向,1下,2上,3左,4右

}p;



void init()

{

    int i,j,k,q;

    for(i = 0; i < 510; i++)   //初始化全为墙

    {

        for(j = 0; j < 510; j++)

        {

            map[i][j][0]=map[i][j][1]=map[i][j][2]=map[i][j][3]=map[i][j][4] = 1;

        }

    }

    memset(dis,0,sizeof(dis));              //初始标记,均没有走过

    scanf("%d%d%d%d",&r,&c,&enty,&exity);

    exitx = r-1;

    p.x = 0;

    p.y = enty;

    p.fx = 1;     //p把入口位置和方向保存

    q = 0;

    for(i = 0; i < 2*r-1; i++)       //更新边缘是否有墙

    {

        if(i&1)

        {

            for(j = 0; j < c; j++)

            {

                scanf("%d",&k);

                map[q][j][1] = k;    //格子上边

                map[q+1][j][2] = k;  //格子下边

            }

            q++;

        }

        else

        {

            for(j = 0; j < c-1; j++)

            {

                scanf("%d",&k);

                map[q][j][4] = k;    //格子的右边

                map[q][j+1][3] = k;  //格子的左边

            }

        }

    }

    return ;

}



void right(Node now)

{

    void Dfs(Node now);

    Node next;

    switch(now.fx)

    {

    case 1:

        {

            if(map[now.x][now.y][3]==0)   //向下右转则向左,如果没有墙则能走

            {

                next.x = now.x;

                next.y = now.y-1;

                next.fx = 3;     //更改当先方向

                if(dis[next.x][next.y][0]==0)   //查看下一个格子以前走过没

                {

                    sum++;     //没走过,增加一个

                }

                Dfs(next);

            }

            break;

        }

    case 2:

        {

            if(map[now.x][now.y][4]==0)

            {

                next.x = now.x;

                next.y = now.y+1;

                next.fx = 4;

                if(dis[next.x][next.y][0]==0)

                {

                    sum++;

                }

                Dfs(next);

            }

            break;

        }

    case 3:

        {

            if(map[now.x][now.y][2]==0)

            {

                next.x = now.x-1;

                next.y = now.y;

                next.fx = 2;

                if(dis[next.x][next.y][0]==0)

                {

                    sum++;

                }

                Dfs(next);

            }

            break;

        }

    case 4:

        {

            if(map[now.x][now.y][1]==0)

            {

                next.x = now.x+1;

                next.y = now.y;

                next.fx = 1;

                if(dis[next.x][next.y][0]==0)

                {

                    sum++;

                }

                Dfs(next);

            }

            break;

        }

    }

    return ;

}



void stright(Node now)

{

    void Dfs(Node now);

    Node next;

    if(map[now.x][now.y][now.fx]==0)

    {

        switch(now.fx)

        {

        case 1:

            {

                next.x = now.x+1;

                next.y = now.y;

                next.fx = now.fx;

                if(dis[next.x][next.y][0]==0)

                {

                    sum++;

                }

                Dfs(next);

                break;

            }

        case 2:

            {

                next.x = now.x-1;

                next.y = now.y;

                next.fx = now.fx;

                if(dis[next.x][next.y][0]==0)

                {

                    sum++;

                }

                Dfs(next);

                break;

            }

        case 3:

            {

                next.x = now.x;

                next.y = now.y-1;

                next.fx = now.fx;

                if(dis[next.x][next.y][0]==0)

                {

                    sum++;

                }

                Dfs(next);

                break;

            }

        case 4:

            {

                next.x = now.x;

                next.y = now.y+1;

                next.fx = now.fx;

                if(dis[next.x][next.y][0]==0)

                {

                    sum++;

                }

                Dfs(next);

                break;

            }

        }

    }

    return ;

}



void left(Node now)

{

    void Dfs(Node now);

    Node next;

    switch(now.fx)

    {

    case 1:

        {

            if(map[now.x][now.y][4]==0)

            {

                next.x = now.x;

                next.y = now.y+1;

                next.fx = 4;

                if(dis[next.x][next.y][0]==0)

                {

                    sum++;

                }

                Dfs(next);

            }

            break;

        }

    case 2:

        {

            if(map[now.x][now.y][3]==0)

            {

                next.x = now.x;

                next.y = now.y-1;

                next.fx = 3;

                if(dis[next.x][next.y][0]==0)

                {

                    sum++;

                }

                Dfs(next);

            }

            break;

        }

    case 3:

        {

            if(map[now.x][now.y][1]==0)

            {

                next.x = now.x+1;

                next.y = now.y;

                next.fx = 1;

                if(dis[next.x][next.y][0]==0)

                {

                    sum++;

                }

                Dfs(next);

            }

            break;

        }

    case 4:

        {

            if(map[now.x][now.y][2]==0)

            {

                next.x = now.x;

                next.y = now.y-1;

                next.fx = 2;

                if(dis[next.x][next.y][0]==0)

                {

                    sum++;

                }

                Dfs(next);

            }

            break;

        }

    }

    return ;

}



void Dfs(Node now)

{

    Node next;

    if(yn)       //如果已经出去了,则不用搜索了

    {

        return ;

    }

    if(sum == r*c) //如果所有格子已经经过,则直接返回

    {

        return ;

    }

    if(now.x == exitx && now.y == exity && now.fx == 1)  //如果到出口且出去则标记并返回

    {

        yn = 1;    //标记已经出去了

        return ;

    }

    if(dis[now.x][now.y][now.fx]==1)  //如果这个格子的这个方向以前走过,则直接返回(判重)

    {

        return ;

    }

    if(dis[now.x])

    dis[now.x][now.y][0]++;        //标记这个格子经过的次数加一

    dis[now.x][now.y][now.fx] = 1; //标记这个格子这个方向走过

    right(now);

    stright(now);

    left(now);

}



int main()

{

    int t;

    scanf("%d",&t);

    while(t--)

    {

        init();

        yn = 0;

        sum = 1;

        Dfs(p);

        if(sum==r*c)

        {

            printf("YES\n");

        }

        else

        {

            printf("NO\n");

        }

    }



    return 0;

}


别人的代码:(来源: http://blog.csdn.net/wsniyufang/article/details/6665488
/*

开始用dfs递归,爆栈了

后来模拟又因为 出迷宫的条件一直wa,细节很重要

*/

#include <iostream>

#include<cstdio>

#include<cstring>

#include<cstdlib>

#include<cmath>

#include<algorithm>

#include<ctime>

using namespace std;

#define N 50009

int R,C,ER,EC,num;

int map1[505][505];

int map2[505][505];

int vis[505][505];

struct Point

{

	int x,y,f;

	Point(int _x,int _y,int _f){x=_x;y=_y;f=_f;}

};

void init()

{

	scanf("%d%d%d%d",&R,&C,&ER,&EC);

	memset(vis,0,sizeof(vis));

	num=0;

	for(int i=0;i<2*R-1;i++)

	{

		if(i&1)

		{

		for(int j=0;j<C;j++)

		scanf("%d",&map1[i/2][j]);

		}

		else 

		{

		for(int j=0;j<C-1;j++)

		scanf("%d",&map2[i/2][j]);

		}

	}

}



void dfs(Point s,Point ss)

{

	int ff=s.f;

	for(;;)

	{

	if(!vis[s.x][s.y])num++;

	vis[s.x][s.y]=1;

	if(s.x==ss.x&&s.y==ss.y)//注意退出的条件,这里比较复杂

	{

		if((s.f==3&&ff==0)||(s.f==1&&ff==2))

		break;

		if(s.f==ff&&ff==0&&(s.y==0||map2[s.x][s.y-1]==1))

		break;

		if(s.f==ff&&ff==2&&(s.y==C-1||map2[s.x][s.y]==1))

		break;

	}

	if(s.f==0)

	{

		if(s.y>0&&map2[s.x][s.y-1]==0)

		{

			s.y--;

			s.f=1;

		}

		else if(s.x+1<R&&map1[s.x][s.y]==0)

		{

			s.x++;

			s.f=0;

		}

		else if(s.y+1<C&&map2[s.x][s.y]==0)

		{

			s.y++;

			s.f=3;

		}

		else if(s.x>0&&map1[s.x-1][s.y]==0)

		{

			s.x--;

			s.f=2;

		}

		

	}

	else if(s.f==1)

	{

		 if(s.x>0&&map1[s.x-1][s.y]==0)

		{

			s.x--;

			s.f=2;

		}

		else if(s.y>0&&map2[s.x][s.y-1]==0)

		{

			s.y--;

			s.f=1;

		}

		else if(s.x+1<R&&map1[s.x][s.y]==0)

		{

			s.x++;

			s.f=0;

		}

		else if(s.y+1<C&&map2[s.x][s.y]==0)

		{

			s.y++;

			s.f=3;

		}

		

	}

		

	else if(s.f==2)

	{

		 if(s.y+1<C&&map2[s.x][s.y]==0)

		{

			s.y++;

			s.f=3;

		}

		else  if(s.x>0&&map1[s.x-1][s.y]==0)

		{

			s.x--;

			s.f=2;

		}

		else if(s.y>0&&map2[s.x][s.y-1]==0)

		{

			s.y--;

			s.f=1;

		}

		else if(s.x+1<R&&map1[s.x][s.y]==0)

		{

			s.x++;

			s.f=0;

		}

	}

	else if(s.f==3)

	{

		 if(s.x+1<R&&map1[s.x][s.y]==0)

		{

			s.x++;

			s.f=0;

		}

		 else if(s.y+1<C&&map2[s.x][s.y]==0)

		{

			s.y++;

			s.f=3;

		}

		else  if(s.x>0&&map1[s.x-1][s.y]==0)

		{

			s.x--;

			s.f=2;

		}

		else if(s.y>0&&map2[s.x][s.y-1]==0)

		{

			s.y--;

			s.f=1;

		}

	}

	}

}



void solve()

{

	Point s=Point(0,ER,0);	

	Point ss=Point(R-1,EC,2);

	dfs(s,ss);

	dfs(ss,s);

	if(num==R*C) puts("YES");

	else puts("NO");

}

int main()

{

    int Case;



	scanf("%d",&Case);

	while(Case--)

	{

		init();

		solve();

	}

    return 0;

}



 

你可能感兴趣的:(right)