• poj1101 The Game


    题目:

    一个游戏,给一块板子,有空白处和不能走的格子,每一块板子给出几组起点和终点,判断这两块能不能连在一起。空白处和外围可以走。如果能连接,求最小拐弯数。


    此题坑点很多

    • 每块板子的长度、宽度是反的
    • 起点,终点的横纵坐标是反的
    • 每块板子输出后要换行

    思路

    • BFS(优先队列)
    • 输入极坑,详见代码
    • sum数组记录每一种状态的拐弯数
    • 枚举4个方向,可以走外围,所以要注意边界,因为是求拐弯数,所以要记录上一次的方向判断

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    using namespace std;
    int n,m,sx,sy,ex,ey;
    bool map[80][80];
    int sum[4][160][160],T1,T2,ans;
    int dir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};
     struct ss
    {
    	int x,y,d,num;
    	friend bool operator < (ss a,ss b)
    	{
    		return a.num>b.num;
    	}
    };
    priority_queue<ss>q;
    
     void bfs()
    {
    	memset(sum,0xf,sizeof(sum));
    	while (!q.empty()) q.pop();
    	ss res,tmp;
    	res.x=sx; res.y=sy; res.num=1; res.d=0; q.push(res);
    	res.d=1; q.push(res);
    	res.d=2; q.push(res);
    	res.d=3; q.push(res);
    	sum[0][sx][sy]=sum[1][sx][sy]=sum[2][sx][sy]=sum[3][sx][sy]=1;
    	while (!q.empty())
    	{
    		res=q.top(); q.pop();
    		if (res.x==ex&&res.y==ey)
    		{
    			ans=res.num;
    			return;
    		}
    		if (res.num>sum[res.d][res.x][res.y]) continue;
    		int num1,x,y;
    		for (int i=0; i<4; i++)
    		{
    			if (i==res.d) num1=res.num;
    			else num1=res.num+1;
    			x=res.x+dir[i][0]; y=res.y+dir[i][1];
    			while (x>=0&&x<=n+1&&y>=0&&y<=m+1&&!map[x][y])
    			{
    				if (num1<sum[i][x][y])
    				{
    					sum[i][x][y]=num1;
    					tmp.x=x; tmp.y=y; tmp.num=num1; tmp.d=i;
    					q.push(tmp);
    				}
    				x=x+dir[i][0]; y=y+dir[i][1];
    				if (map[x][y]) break;
    			}
    			if (x==ex&&y==ey)
    				if (num1<sum[i][x][y])
    				{
    					sum[i][x][y]=num1;
    					tmp.x=x; tmp.y=y; tmp.num=num1; tmp.d=i;
    					q.push(tmp);
    				}
    		}
    	}
    }
     void init()
    {
    	memset(map,0,sizeof(map));
    	char c;
    	int j,T2=0;
    	while(scanf("%c",&c)==1)
    	{
    		if(c=='\n')break;
    	}
    	for(int i=1;i<=n;i++)
    	{
    		j=0;
    		while(scanf("%c",&c)==1)
    		{
    			j++;
    			if(c=='X') map[i][j]=1;
    			if(c=='\n') break;
    		}
    	}
    	printf("Board #%d:\n",++T1);
    	while(scanf("%d%d%d%d",&sy,&sx,&ey,&ex)==4&&sx)//横纵坐标是反的
    	{
    		printf("Pair %d:",++T2);
    		ans=0;
    		bfs();
    		if(ans) printf(" %d segments.\n",ans);
    		else printf(" impossible.\n");
    	}
    }
    
     int main()
    {
    	while (scanf("%d%d",&m,&n))
    	{
    		if (!m&&!n) break;
    		init(); printf("\n");//坑点,千万注意
    	}
    	return 0;
    }
    
  • 相关阅读:
    Linux环境下安装JDK
    CentOS 7 更改主机名
    Find Pivot Index之Python实现
    MySQL基本操作之数据库基本操作
    Linux环境下安装单实例MySQL 5.7
    基于时间的ACL配置
    动态ACL的配置
    自反ACL
    OSFPv3的配置
    RIPng 配置
  • 原文地址:https://www.cnblogs.com/lyxzhz/p/11407121.html
Copyright © 2020-2023  润新知