小游戏 (最少线段连线问题)
来源:互联网 发布:南木梁知小说百度云盘 编辑:程序博客网 时间:2024/05/22 01:15
游戏在一个分割成w * h个长方格子的矩形板上进行。如图所示,每个长方格子上可以有一张游戏卡片,也可以没有。当下面的情况满足时,我们认为两个游戏卡片之间有一条路径相连:
路径只包含水平或者竖直的直线段。路径不能穿过别的游戏卡片。但是允许路径临时离开矩形板。
下面是一个例子: 这里在(1, 3)和(4, 4)处的游戏卡片是可以相连的。而在 (2, 3) 和 (3, 4) 处的游戏卡是不相连的,因为连接他们的每条路径都必须要穿过别的游戏卡片。
路径只包含水平或者竖直的直线段。路径不能穿过别的游戏卡片。但是允许路径临时离开矩形板。
下面是一个例子:
你现在要在小游戏里面判断是否存在一条满足题意的路径能连接给定的两个游戏卡片。
这道题最早遇见是在高二的县里的模拟赛的时候,感觉是一个经典的问题。
分析,首先因为要求是最少的线段,实际就是用最少的转弯,那就每个方向光搜出去应该是能到的最远处内的所有点都是应该在该层中被加入队列的。
于是按照线段的转折次数为层数进行光搜即可。其中要注意一些细节。
该题出现在P大的编程网格上,岁月匆匆感慨万千,因为细节没有处理好,导致大数据上WA了若干次。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cstring>#include <queue>using namespace std;const int maxN = 100+10;const int dir[4][2]= {0,1,0,-1,-1,0,1,0};char s[maxN], map[maxN][maxN];int sx,sy,tx,ty,n,m,ans;int f[maxN][maxN][4],arrive[maxN][maxN][4];struct Node{ int x,y,Dir; }node,newNode;queue<Node> q;bool inside(int x,int y){ return (x>=0 && x<=n+1 && y>=0 && y<=m+1); }bool ok(){ memset(arrive,0,sizeof(arrive)); memset(f,127,sizeof(f)); bool canArrive = false; while (!q.empty()) q.pop(); for (int k = 0; k < 4;++k) { node.x = sx; node.y = sy; node.Dir = k; q.push(node); f[sx][sy][k]=1; arrive[sx][sy][k]=true; } while (!q.empty()) { Node now = q.front(); q.pop(); arrive[now.x][now.y][now.Dir] == false; for (int k = 0; k < 4; ++k) for (int step = 1; step <= maxN ; ++step) { int x=now.x+dir[k][0]*step; int y=now.y+dir[k][1]*step; if ( !inside(x,y)) break; if (tx == x && ty == y) { f[x][y][k]=min(f[x][y][k], f[now.x][now.y][now.Dir]+(now.Dir != k)); canArrive = true; } if (map[x][y] == 'X' ) break; if (f[now.x][now.y][now.Dir]+(now.Dir != k)< f[x][y][k]) { f[x][y][k]=f[now.x][now.y][now.Dir]+(now.Dir != k); if (!arrive[x][y][k]) { arrive[x][y][k]=true; newNode.x = x; newNode.y = y; newNode.Dir = k; q.push(newNode); } } } } return canArrive;}int main(){ int Test = 0; while (scanf("%d%d",&m,&n)==2) { if (m==0 && n==0) break; getchar(); printf("Board #%d:\n",++Test); for (int i = 0; i <= n+1; ++i) for (int j = 0; j <= m+1; ++j) map[i][j]='S'; for (int i = 1;i <= n; ++i) { gets(s); for (int j = 1; j <= m ;++j) map[i][j] = s[j-1]; } int Pair = 0; while(scanf("%d%d%d%d",&sy,&sx,&ty,&tx)) { if (sx+sy+tx+ty == 0) break; if (!ok()) printf("Pair %d: impossible.\n",++Pair); else { int ans = maxN * maxN; for (int k = 0 ; k < 4; ++k) ans=min(ans,f[tx][ty][k]); printf("Pair %d: %d segments.\n",++Pair,ans); } } } return 0; }
- 小游戏 (最少线段连线问题)
- Canvas线段终点和连线
- IOS连线问题
- xib连线问题
- 最少硬币问题(多重背包问题)
- StoryBoard使用push跳转不连线。(解决黑屏问题)
- PADS布线问题(【同网络不能够连线】)
- 最少硬币问题(动态规划解决)
- 最少步数(迷宫问题类型)
- 设计模式(连线)
- 最少零钱问题 最少硬币问题
- 最少零钱问题 最少硬币问题
- 最少硬币问题
- 最少硬币问题
- 最少硬币问题
- 【dp】最少硬币问题
- 最少硬币问题
- 最少硬币找零问题
- CSS控制所有浏览器水平居中和控制链接不换行的效果
- 老外最常说的二十个钻石级句子
- Asp.net web Api源码分析-Action的执行
- 有关L6236E,L6406E错误的总结
- Jquery queue源码分析
- 小游戏 (最少线段连线问题)
- Android之Bitmap大图加载处理
- 4.1 内存的分配与释放
- HDU 1232 & 1213并查集应用 练习
- 宁坐在切糕车上哭 也不坐在宝马车里笑
- 软件项目管理系统-项目管理-模块一览
- 放大效应
- VS2008提示无法打开包括文件:“afxcontrolbars.h”解决办法
- sql server 首字母大写