zoukankan      html  css  js  c++  java
  • 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
    ");
            }
            else
            {
                printf("NO
    ");
            }
        }
    
        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;
    }
    


  • 相关阅读:
    C#和sqlserver中生成新的32位GUID
    IIS7下swfupload上传大文件出现404错误
    jQuery 判断是否为数字的方法 及 转换数字函数
    js数组与字符串的相互转换方法
    jquery 中如何将数组转化为json字符串,然后再转化回来?
    Firemonkey Android 虚拟机
    Eclipse apk 签名
    win10 修改hosts
    eclipse 预览Android界面报错
    夜神模拟器
  • 原文地址:https://www.cnblogs.com/james1207/p/3278011.html
Copyright © 2011-2022 走看看