poj-2049 dfs
来源:互联网 发布:类似淘宝的app 编辑:程序博客网 时间:2024/05/05 07:47
//7148K 94MS G++
#include <stdio.h>
#include <string.h>
struct WallCell {
char upWall; // 0, no wall. 1, has door. 2, has wall
char rightWall;
};
typedef struct WallCell WallCell;
// seaMap[i][j] indicates the wall info from (i, j) to (i+1, j)<upWall> and (i, j) to (i, j+1)<rightWall>
WallCell seaMap[1000][1000];
int seaMapFlag[1000][1000];
#define INF 100000
//return -1 if can not go on, else the door num
char dfs(int x, int y, int minX, int minY, int maxX, int maxY) {
// printf("dfs %d %d\n", x, y);
char leftWall = seaMap[x][y].upWall;
char downWall = seaMap[x][y].rightWall;
char rightWall = seaMap[x+1][y].upWall;
char upWall = seaMap[x][y+1].rightWall;
if (leftWall < 2 && (seaMapFlag[x-1][y] > seaMapFlag[x][y] + leftWall)) { // try to enter left cell x->x-1
seaMapFlag[x-1][y] = seaMapFlag[x][y] + leftWall;
dfs(x-1, y, minX, minY, maxX, maxY);
}
if (downWall < 2 && (seaMapFlag[x][y-1] > seaMapFlag[x][y] + downWall)) { // try to enter down cell y->y-1
seaMapFlag[x][y-1] = seaMapFlag[x][y] + downWall;
dfs(x, y-1, minX, minY, maxX, maxY);
}
if (rightWall < 2 && (seaMapFlag[x+1][y] > seaMapFlag[x][y] + rightWall)) { // try to enter right cell x->x+1
seaMapFlag[x+1][y] = seaMapFlag[x][y] + rightWall;
dfs(x+1, y, minX, minY, maxX, maxY);
}
if (upWall < 2 && (seaMapFlag[x][y+1] > seaMapFlag[x][y] + upWall)) { // try to enter up cell y->y+1
seaMapFlag[x][y+1] = seaMapFlag[x][y] + upWall;
dfs(x, y+1, minX, minY, maxX, maxY);
}
return -1;
}
void hardEnEdge(int maxX, int maxY) {
// printf("hardEnEdge %d %d\n", maxX, maxY);
for (int i = 0; i <= maxX-1; i++) {
seaMap[i][0].rightWall = 2;
seaMap[i][maxY].rightWall = 2;
}
// printf("hardEnEdge 1\n");
for (int i = 0; i <= maxY-1; i++) {
seaMap[0][i].upWall = 2;
seaMap[maxX][i].upWall = 2;
}
// printf("hardEnEdge 2\n");
}
void getMinDoor(float beginX, float beginY, int minX, int minY, int maxX, int maxY) {
// printf("%f %f %d %d %d %d\n", beginX, beginY, minX, minY, maxX, maxY);
for (int i = 0; i <= maxX; i++) {
for (int j = 0; j <= maxY; j++) {
seaMapFlag[i][j] = INF;
}
}
seaMapFlag[(int)beginX][(int)beginY] = 0;
dfs((int)beginX, (int)beginY, minX, minY, maxX, maxY);
printf("%d\n", seaMapFlag[0][0] == INF ? -1 : seaMapFlag[0][0]);
}
int main() {
int M;
int N;
while(1) {
int minX = 9999, minY = 9999, maxX = -9999, maxY = -9999;
memset(seaMap, 0, sizeof(seaMap));
memset(seaMapFlag, 0, sizeof(seaMapFlag));
scanf("%d %d", &M, &N);
if (-1 == M && -1 == N) {
return 0;
}
for (int i = 0; i < M ; i++) {
int x, y, direction, length;
scanf("%d %d %d %d", &x, &y, &direction, &length);
minX = x < minX ? x : minX;
minY = y < minY ? y : minY;
if (!direction) { //paralell to X-axis
maxX = x + length > maxX ? x + length : maxX;
maxY = y + 0 > maxY ? y + 0 : maxY;
} else { //paralell to Y-axis
maxY = y + length > maxY ? y + length : maxY;
maxX = x + 0 > maxX ? x + 0 : maxX;
}
for (int i = 0; i < length; i++) {
direction == 0 ? seaMap[x+i][y].rightWall = 2 : seaMap[x][y+i].upWall = 2;
}
}
for (int j = 0; j < N; j++) {
int x, y, direction;
scanf("%d %d %d", &x, &y, &direction);
direction == 0 ? seaMap[x][y].rightWall = 1 : seaMap[x][y].upWall = 1;
if (!direction) { //paralell to X-axis
maxX = x + 1 > maxX ? x + 1 : maxX;
maxY = y + 0 > maxY ? y + 0 : maxY;
} else { //paralell to Y-axis
maxY = y + 1 > maxY ? y + 1 : maxY;
maxX = x + 0 > maxX ? x + 0 : maxX;
}
}
float sbX, sbY;
scanf("%f %f", &sbX, &sbY);
if (!M & !N) {
printf("0\n");
continue;
}
if (sbX < 0 || sbY < 0 || sbX > 199 || sbY > 199) {
printf("0\n");
continue;
}
maxX = maxX > (int)sbX ? maxX : (int)sbX;
maxY = maxY > (int)sbY ? maxY : (int)sbY;
hardEnEdge(maxX + 1, maxY + 1);
getMinDoor(sbX, sbY, minX, minY, maxX, maxY);
}
#include <stdio.h>
#include <string.h>
struct WallCell {
char upWall; // 0, no wall. 1, has door. 2, has wall
char rightWall;
};
typedef struct WallCell WallCell;
// seaMap[i][j] indicates the wall info from (i, j) to (i+1, j)<upWall> and (i, j) to (i, j+1)<rightWall>
WallCell seaMap[1000][1000];
int seaMapFlag[1000][1000];
#define INF 100000
//return -1 if can not go on, else the door num
char dfs(int x, int y, int minX, int minY, int maxX, int maxY) {
// printf("dfs %d %d\n", x, y);
char leftWall = seaMap[x][y].upWall;
char downWall = seaMap[x][y].rightWall;
char rightWall = seaMap[x+1][y].upWall;
char upWall = seaMap[x][y+1].rightWall;
if (leftWall < 2 && (seaMapFlag[x-1][y] > seaMapFlag[x][y] + leftWall)) { // try to enter left cell x->x-1
seaMapFlag[x-1][y] = seaMapFlag[x][y] + leftWall;
dfs(x-1, y, minX, minY, maxX, maxY);
}
if (downWall < 2 && (seaMapFlag[x][y-1] > seaMapFlag[x][y] + downWall)) { // try to enter down cell y->y-1
seaMapFlag[x][y-1] = seaMapFlag[x][y] + downWall;
dfs(x, y-1, minX, minY, maxX, maxY);
}
if (rightWall < 2 && (seaMapFlag[x+1][y] > seaMapFlag[x][y] + rightWall)) { // try to enter right cell x->x+1
seaMapFlag[x+1][y] = seaMapFlag[x][y] + rightWall;
dfs(x+1, y, minX, minY, maxX, maxY);
}
if (upWall < 2 && (seaMapFlag[x][y+1] > seaMapFlag[x][y] + upWall)) { // try to enter up cell y->y+1
seaMapFlag[x][y+1] = seaMapFlag[x][y] + upWall;
dfs(x, y+1, minX, minY, maxX, maxY);
}
return -1;
}
void hardEnEdge(int maxX, int maxY) {
// printf("hardEnEdge %d %d\n", maxX, maxY);
for (int i = 0; i <= maxX-1; i++) {
seaMap[i][0].rightWall = 2;
seaMap[i][maxY].rightWall = 2;
}
// printf("hardEnEdge 1\n");
for (int i = 0; i <= maxY-1; i++) {
seaMap[0][i].upWall = 2;
seaMap[maxX][i].upWall = 2;
}
// printf("hardEnEdge 2\n");
}
void getMinDoor(float beginX, float beginY, int minX, int minY, int maxX, int maxY) {
// printf("%f %f %d %d %d %d\n", beginX, beginY, minX, minY, maxX, maxY);
for (int i = 0; i <= maxX; i++) {
for (int j = 0; j <= maxY; j++) {
seaMapFlag[i][j] = INF;
}
}
seaMapFlag[(int)beginX][(int)beginY] = 0;
dfs((int)beginX, (int)beginY, minX, minY, maxX, maxY);
printf("%d\n", seaMapFlag[0][0] == INF ? -1 : seaMapFlag[0][0]);
}
int main() {
int M;
int N;
while(1) {
int minX = 9999, minY = 9999, maxX = -9999, maxY = -9999;
memset(seaMap, 0, sizeof(seaMap));
memset(seaMapFlag, 0, sizeof(seaMapFlag));
scanf("%d %d", &M, &N);
if (-1 == M && -1 == N) {
return 0;
}
for (int i = 0; i < M ; i++) {
int x, y, direction, length;
scanf("%d %d %d %d", &x, &y, &direction, &length);
minX = x < minX ? x : minX;
minY = y < minY ? y : minY;
if (!direction) { //paralell to X-axis
maxX = x + length > maxX ? x + length : maxX;
maxY = y + 0 > maxY ? y + 0 : maxY;
} else { //paralell to Y-axis
maxY = y + length > maxY ? y + length : maxY;
maxX = x + 0 > maxX ? x + 0 : maxX;
}
for (int i = 0; i < length; i++) {
direction == 0 ? seaMap[x+i][y].rightWall = 2 : seaMap[x][y+i].upWall = 2;
}
}
for (int j = 0; j < N; j++) {
int x, y, direction;
scanf("%d %d %d", &x, &y, &direction);
direction == 0 ? seaMap[x][y].rightWall = 1 : seaMap[x][y].upWall = 1;
if (!direction) { //paralell to X-axis
maxX = x + 1 > maxX ? x + 1 : maxX;
maxY = y + 0 > maxY ? y + 0 : maxY;
} else { //paralell to Y-axis
maxY = y + 1 > maxY ? y + 1 : maxY;
maxX = x + 0 > maxX ? x + 0 : maxX;
}
}
float sbX, sbY;
scanf("%f %f", &sbX, &sbY);
if (!M & !N) {
printf("0\n");
continue;
}
if (sbX < 0 || sbY < 0 || sbX > 199 || sbY > 199) {
printf("0\n");
continue;
}
maxX = maxX > (int)sbX ? maxX : (int)sbX;
maxY = maxY > (int)sbY ? maxY : (int)sbY;
hardEnEdge(maxX + 1, maxY + 1);
getMinDoor(sbX, sbY, minX, minY, maxX, maxY);
}
}
2049的dfs版本,思想上其实没有变化,都是flood-fill的不断刷新每个格子到起始点的最少doorNum,只是遍历的手段从bfs换成了dfs。
这道题之所以和普通的迷宫题不一样,在于,一般迷宫要求的都是最少的移动次数,及从起始的格子节点到目的格子节点所需要的最短路径就是所求。
因此BFS就可以满足此需求,但是本题的特殊之处在于,要求的不是最少移动次数,而是通过的最少的门(有可能长的路径经过门少,短路径经过门多),
因此普通的BFS在这种情况下就不再适用了。
有点像带权重的图求解。
首先需要开一个二维数组A记录每个格子到起始格子所经过的最少door num, 注意的是这个door num都是不断在刷新的, 每次有新的路径要抵达这个点的时候,
要看从此路径到此点的doorNum是否比此格子当前存储的doornum还要小,如果小,那么更新此点,并且要重新遍历该点。
和普通的二维标记数组不一样,A在这里也是标示,但是是否需要遍历的标准从 是否遍历过 变成了新路径到该点的doornum是否更小(如果更小,那么以就要重新遍历)。
不清楚这个技法算是BFS/DFS的一部分,还是一种新的思想.
感觉好乱,无数的命运交叉口互相交织影响,最后写出大结局。
0 0
- poj-2049 dfs
- DFS POJ
- POJ DFS
- poj 3083 DFS+DFS+BFS
- POJ 1753 ID+DFS
- poj 1950 数字dfs
- poj 1816(trie+dfs)
- POJ 3107 Godfather(DFS)
- poj 3620(DFS)
- poj 1020 DFS
- poj 2362Square(DFS)
- POJ 2676 Sudoku dfs
- POJ 2357 Labyrinth [DFS]
- poj 1011 dfs
- poj 1190 dfs(生日蛋糕)
- poj 1154 dfs
- poj 2192 DFS+剪枝
- 【DFS】POJ 2044
- kvm的安装,创建和转移
- SeaJs研究 之 关键方法实现解析
- IP地址的分类
- 【Android 应用开发】Android 上实现非root的 Traceroute -- 非Root权限下移植可执行二进制文件 脚本文件
- A Knight's Journey(深搜)
- poj-2049 dfs
- PB窗口使用技巧
- 从输入 URL 到页面加载完成的过程中都发生了什么事情?
- xml/xsl(2): 将XML/XSL写到一个文件
- cocos2d-X学习之主要类介绍:节点CCNode
- 学习 "使用cocos2d-x3.0和物理引擎实现碰撞检测" 中出现的一个问题
- android 外置sdcard与内置sdcard
- java错误总结1
- Android - 小功能 利用Jsoup解析html 开发网站客户端小记。