POJ 3083--Children of the Candy Corn
来源:互联网 发布:网易云课堂网络 编辑:程序博客网 时间:2024/06/07 01:56
题目:这是题目
题意:一个迷宫,从S点走到E点,求一直靠墙向左走和靠墙向右走以及随便走的最短路, 保证数据的合法性,一定会有路。
定义的方向:
int x[4] = {0, -1, 0, 1};//左 上 右 下int y[4] = {-1, 0, 1, 0};
思路:要求靠墙向左走和靠墙向右走,用DFS,求随便走最短路用BFS。该题的比较难的地方是处理方向。
对于一直靠墙向左走,如下图,假设你到达红色的点,方向是turn,此时首先判断左边是否有路,判断方向为(turn + 3)% 4,如果左边没路,则判断前面(turn),如果前面没路,则判断右边,否则判断下面(当然这个方向是相对方向) 。
对于一直靠墙向右走,同如下图,假设你到达红色的点,先判断右边是否有路(turn + 1)% 4, 如果没有路,再判断前面(turn),再判断左边(turn + 3)% 4, 否则判断下面(turn + 2)% 4。
好了方向问题搞清楚了, 那么靠墙向左走,循环的方向依次为 (turn + 3)% 4, turn ,(turn + 1)% 4,(turn + 2)% 4,那么循环可以有个规律,
for (int i = 3, k = 0; k < 4; i = (i + 1) % 4, k++)
turn = (turn + i)% 4;
靠墙向右走的循环方向依次为(turn + 1)% 4, turn ,(turn + 3)% 4,(turn + 2)% 4,循环为:for (int i = 1, k = 0; k < 4; i = (i + 3) % 4, k++)
turn = (turn + i)% 4;
实现如下:
#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <queue>#include <math.h>using namespace std;const int MAX = 45;char _map[MAX][MAX];bool visit[MAX][MAX];int w, h;int sx1, sy1, sx2, sy2, ex, ey;int sum1, sum2;int x[4] = {0, -1, 0, 1};//左 上 右 下int y[4] = {-1, 0, 1, 0};bool judge(int x, int y) { if (x >= 0 && x < h && y >= 0 && y < w && (_map[x][y] == '.' || _map[x][y] == 'E') ) return true; return false;}//判断是否能走struct node { int xxx, yyy; char key; int step;};void dfs_right(int xx, int yy, int turn) { if (xx == ex && yy == ey) return; else { for (int i = 1, k = 0; k < 4; i = (i + 3) % 4, k++) { if (judge(xx + x[(turn + i) % 4], yy + y[(turn + i) % 4])) { sum2++; dfs_right(xx + x[(turn + i) % 4], yy + y[(turn + i) % 4], (turn + i) % 4); break; } } }}void dfs_left(int xx, int yy, int turn) { if (xx == ex && yy == ey) return; else { for (int i = 3, k = 0; k < 4; i = (i + 1) % 4, k++) { if (judge(xx + x[(turn + i) % 4],yy + y[(turn + i) % 4])) { sum1++; dfs_left(xx + x[(turn + i) % 4], yy + y[(turn + i) % 4], (turn + i) % 4); break; } } }}void turn_left() { if (judge(sx1, sy1 - 1)) { dfs_left(sx1, sy1 - 1, 0); } else if (judge(sx1 - 1, sy1)) { dfs_left(sx1 - 1, sy1, 1); } else if (judge(sx1, sy1 + 1)) { dfs_left(sx1, sy1 + 1, 2); } else { dfs_left(sx1 + 1, sy1, 3); }}void turn_right() { if (judge(sx2, sy2 + 1)) { dfs_right(sx2, sy2 + 1, 2); } else if (judge(sx2 + 1, sy2)) { dfs_right(sx2 + 1, sy2, 3); } else if (judge(sx2, sy2 - 1)) { dfs_right(sx2, sy2 - 1, 0); } else { dfs_right(sx2 - 1, sy2, 1); }}int bfs() { queue <node>q; node start; start.xxx = sx1; start.yyy = sy1; start.key = 'S'; start.step = 1; q.push(start); while (!q.empty()) { node head, tail; head = q.front(); q.pop(); if (head.xxx == ex && head.yyy == ey) return head.step; for (int i = 0; i < 4; i++) { int xi = head.xxx + x[i]; int yi = head.yyy + y[i]; if (xi >= 0 && xi < h && yi >= 0 && yi < w && !visit[xi][yi]) { tail.xxx = xi; tail.yyy = yi; tail.key = _map[xi][yi]; tail.step = head.step + 1; visit[xi][yi] = true; q.push(tail); } } } return -1;}int main() { int t; scanf("%d", &t); while(t--) { memset(visit, false, sizeof(visit)); scanf("%d%d", &w, &h); getchar(); for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { scanf("%c", &_map[i][j]); if (_map[i][j] == '#') visit[i][j] = true; else if (_map[i][j] == 'S') { sx1 = i; sx2 = i; sy1 = j; sy2 = j; } else if (_map[i][j] == 'E') { ex = i; ey = j; } } getchar(); } sum1 = 1; sum2 = 1; turn_left(); turn_right(); cout << sum1 + 1 << " " << sum2 + 1 << " " << bfs() << endl; }}
0 0
- poj 3083 Children of the Candy Corn
- poj 3083Children of the Candy Corn
- poj 3083 Children of the Candy Corn
- poj 3083 Children of the Candy Corn
- POJ 3083 Children of the Candy Corn
- POJ 3083 Children of the Candy Corn
- POJ 3083 Children of the Candy Corn
- POJ 3083 Children of the Candy Corn
- POJ 3083 Children of the Candy Corn
- poj 3083 Children of the Candy Corn
- POJ 3083 Children of the Candy Corn
- poj 3083 Children of the Candy Corn
- POJ 3083 - Children of the Candy Corn
- POJ 3083 Children of the Candy Corn
- poj 3083 Children of the Candy Corn
- POJ 3083 Children of the Candy Corn
- POJ 3083 Children of the Candy Corn
- poj 3083 Children of the Candy Corn
- 有用的在线工具地址整理
- JSTL 核心标签库 使用
- 原码、反码、补码
- 每天一个linux命令(7):mv命令
- 拆解Clucene 系列(1)---Clucene的特点和难点
- POJ 3083--Children of the Candy Corn
- 每天一个linux命令(8):cp 命令
- 结构体字节对齐问题
- Android Robotium测试框架
- 安装libsvm工具包
- chrome跨域访问
- 每天一个linux命令(9):touch 命令
- linux简介
- java输出执行开始时间,结束时间和运行时间