HDU 1175 连连看+ HDU 1728 逃离迷宫

        这段时间跟着校队在训练,由于自己实在是太水,都是从基本的开始,第一个专题是搜索,所以刷了很多搜索题了吧,但是一直没写博客,是想自己对DFS和 BFS了解的更有点感觉再发博客。

HDU 1175连连看

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1175 

       题意是中文的就不多说了刚开始拿到手,想用DFS做,可是剪枝减的不好,一直 TLE,最后就还是用BFS做了,不过说实话 ,BFS在做这种求最小值问题方面还真是很有优势的,题目中有一句说是连线不能从外围绕,这句话明显降低了边界的处理,就按照平常的宽搜来做就OK。可能对于大家来说这道题超级水吧,不过我是第一次做转弯题目,所以就发下博客纪念下。

代码:

#include<stdio.h>
#include<string.h>
#include<queue>
#define maxn 1001

using namespace std;

int n,m;
int mapn[maxn][maxn];
struct point
{
   int x,y,turn;
}start;
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int visit[maxn][maxn];
int dx,dy;

void BFS(int a,int b)
{
    queue<point> q;
    point cur,next;
    start.x=a;
    start.y=b;
    start.turn=-1;
    q.push(start);
    while(!q.empty())
    {
        cur=q.front();
        q.pop();
        if(cur.x==dx&&cur.y==dy)
        {
            if(cur.turn<=2)
            {
                printf("YES\n");
                return ;
            }
            break;
        }
        for(int i=0;i<4;i++)
        {
            next.x=cur.x+dir[i][0];
            next.y=cur.y+dir[i][1];
            next.turn=cur.turn+1;
            if(next.x==dx&&next.y==dy&&next.turn<=2)
            {

                printf("YES\n");
                return ;
            }
            while(next.x>=0&&next.x<n&&next.y>=0&&next.y<m&&mapn[next.x][next.y]==0)
            {
               if(!visit[next.x][next.y])
               {
                   visit[next.x][next.y]=1;
                   q.push(next);

               }
               next.x+=dir[i][0];
               next.y+=dir[i][1];
               if(next.x==dx&&next.y==dy&&next.turn<=2)
               {
                   printf("YES\n");
                   return ;
               }
            }

        }

    }
    printf("NO\n");
}

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int k,sx,sy;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==0&&m==0)
            break;
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
            scanf("%d",&mapn[i][j]);

        scanf("%d",&k);
        for(int i=0;i<k;i++)
        {
            memset(visit,0,sizeof(visit));
            scanf("%d%d%d%d",&sx,&sy,&dx,&dy);
            sx--,sy--,dx--,dy--;
            if(mapn[sx][sy]!=mapn[dx][dy])
            {
                printf("NO\n");
                continue;
            }
            if(mapn[sx][sy]==0||sx==dx&&sy==dy)
            {
                printf("NO\n");
                continue;
            }
            visit[sx][sy]=1;
            BFS(sx,sy);
        }

    }
    return 0;
}


 

 HDU1782 逃离迷宫

链接: http://acm.hdu.edu.cn/showproblem.php?pid=1728

 这道题目和连连看基本差不多,不过连连看是最多转两次弯,这道的转弯次数是自己输入的,性质一样。因为做了连连看,所以又找来这道题做,算是给自己巩固下。

代码:

#include <stdio.h>
#include <queue>
#include <string.h>

using std::queue;
struct point 
{
	int x,y,step;
}start;
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int n,m,k,dx,dy;

char mapn[110][110];
int visit[110][110];

void BFS(int a,int b)
{
	queue<point> q;
	point cur,next;
	start.x=a;
	start.y=b;
	start.step=-1;//刚开始选方向不算转弯

	q.push(start);

	while(!q.empty())
	{
		cur=q.front();
		q.pop();
		if(cur.x==dx&&cur.y==dy)
		{
			if(cur.step<=k)
			{
				printf("yes\n");
				return ;
			}
			break;
		}

		for(int i=0;i<4;i++)
		{
			next.x=cur.x+dir[i][0];
			next.y=cur.y+dir[i][1];
			next.step=cur.step+1;

			if(next.x==dx&&next.y==dy&&next.step<=k)
			{
				printf("yes\n");
				return ;
			}
			while(next.x>=0&&next.x<n&&next.y>=0&&next.y<m&&mapn[next.x][next.y]=='.')
			{

				if(!visit[next.x][next.y])
				{
					visit[next.x][next.y]=1;
					q.push(next);
				}
				next.x+=dir[i][0];
				next.y+=dir[i][1];
				if(next.x==dx&&next.y==dy&&next.step<=k)
				{
					printf("yes\n");
					return ;
				}
			}
		}
	}
	printf("no\n");
}

int main()
{
	//freopen("in.txt","r",stdin);
	int sx,sy,t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&n,&m);
		for(int i=0;i<n;i++)
			scanf("%s",mapn[i]);
		scanf("%d%d%d%d%d",&k,&sy,&sx,&dy,&dx);
		sx--,sy--,dx--,dy--;
		if(mapn[dx][dy]=='*')
		{
			printf("no\n");
			continue;
		}

		memset(visit,0,sizeof(visit));
		visit[sx][sy]=1;
		BFS(sx,sy);
	}
	return 0;
}










 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值