UVA 810 筛子难题(BFS)

The three-by-three array in Figure 1 is a maze. A standard six-sided die is needed to traverse the maze (the layout of a standard six--sided die is shown in Figure 2). Each maze has an initial position and an initial
die configuration. In Figure 1, the starting position is row 1, column 2--the ``2‘‘ in the top row of the maze--and the initial die configuration has the ``5‘‘ on top of the die and the ``1‘‘ facing the player (assume the player is viewing the maze from the
bottom edge of the figure).

To move through the maze you must tip the die over on an edge to land on an adjacent square, effecting horizontal or vertical movement from one square to another. However, you can only move onto a square that contains the same number as the number displayed
on the top of the die before the move, or onto a ``wild‘‘ square which contains a star. Movement onto a wild square is always allowed regardless of the number currently displayed on the top of the die. The goal of the maze is to move the die off the starting
square and to then find a way back to that same square.

For example, at the beginning of the maze there are two possible moves. Since the 5 is on top of the die, it is possible to move down one square, and since the square to the left of the starting position is wild it is also possible to move left. If the first
move chosen is to move down, this brings the 6 to the top of the die and moves are now possible both to the right and down. If the first move chosen is instead to the left, this brings the 3 to the top of the die and no further moves are possible.

If we consider maze locations as ordered pairs of row and column numbers ( rowcolumn) with row indexes starting at 1 for the top row and increasing
toward the bottom, and column indexes starting at 1 for the left column and increasing to the right, the solution to this simple example maze can be specified as: (1,2), (2,2), (2,3), (3,3), (3,2), (3,1), (2,1), (1,1), (1,2). A bit more challenging example
maze is shown in Figure 3.

The goal of this problem is to write a program to solve dice mazes. The input file will contain several mazes for which the program should search for solutions. Each maze will have either a unique solution or no solution at all. That is, each maze in the input
may or may not have a solution. For each input maze, either a solution or a message indicating no solution is possible will be sent to the output.

Input

The input file begins with a line containing a string of no more than 20 non-blank characters that names the first maze. The next line contains six integers delimited by single spaces. These integers are, in
order, the number of rows in the maze (an integer from 1 to 10, call this value R), the number
of columns in the maze (an integer from 1 to 10, call this value C), the starting row, the starting
column, the number that should be on top of the die at the starting position, and finally the number that should be facing you on the die at the starting position. The next R lines
contain C integers each, again delimited by single spaces. This R×C array
of integers defines the maze. A value of zero indicates an empty location in the maze (such as the two empty squares in the center column of the maze in Figure 3), and a value of `-1‘ indicates
a wild square. This input sequence is repeated for each maze in the input. An input line containing only the word `END‘ (without the quotes) as the name of the maze marks the end of the input.

Output

The output should contain the name of each maze followed by its solution or the string `No Solution Possible‘ (without the quotes). All lines in
the output file except for the maze names should be indented exactly two spaces. Maze names should start in the leftmost column. Solutions should be output as a comma-delimited sequence of the consecutive positions traversed in the solution, starting and ending
with the same square (the starting square as specified in the input). Positions should be specified as ordered pairs enclosed in parentheses. The solution should list 9 positions per line (with the exception of the last line of the solution for which there
may not be a full 9 positions to list), and no spaces should be present within or between positions.

Sample Input

DICEMAZE1
3 3 1 2 5 1
-1 2 4
5 5 6
6 -1 -1
DICEMAZE2
4 7 2 6 3 6
6 4 6 0 2 6 4
1 2 -1 5 3 6 1
5 3 4 5 6 4 2
4 1 2 0 3 -1 6
DICEMAZE3
3 3 1 1 2 4
2 2 3
4 5 6
-1 -1 -1
END

Sample Output

DICEMAZE1
  (1,2),(2,2),(2,3),(3,3),(3,2),(3,1),(2,1),(1,1),(1,2)
DICEMAZE2
  (2,6),(2,5),(2,4),(2,3),(2,2),(3,2),(4,2),(4,1),(3,1),
  (2,1),(2,2),(2,3),(2,4),(2,5),(1,5),(1,6),(1,7),(2,7),
  (3,7),(4,7),(4,6),(3,6),(2,6)
DICEMAZE3
  No Solution Possible

题意:给一个地图,R*C的,地图上每个点有相应的数字,如果骰子旁边的位置上的数字恰好等于当前骰子状态的上表面的点数或者旁边是空地,则骰子可以滚动到该位置。给你初始骰子的位置以及初始骰子的状态,求能否找到一条路径使骰子走一圈后又回到起点。凡神的输出方案好:点击打开链接

<pre name="code" class="cpp">#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
typedef long long LL;
using namespace std;
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a )
int mp[15][15];
int to[15][15];
int dr[][2]={-1,0,1,0,0,-1,0,1};
int vis[15][15][15][15];
int r,c,sx,sy;
int u,f;
typedef pair<int,int>pil;
vector<pil>ans;
struct node{
    int x,y,u,f;
    int pre;
}q[10005];
void solve(int &vu, int &vf, int d)
{
    int t;
    if (d == 0) {t = vf; vf = 7 - vu; vu = t;}
    if (d == 1) {t= vu; vu = 7 - vf; vf = t;}
    if (d == 2) vu = 7 - to[vu][vf];
    if (d == 3) vu = to[vu][vf];
}
void print(int x)
{
    if(x==-1)  return ;
    print(q[x].pre);
    ans.push_back(make_pair(q[x].x,q[x].y));
}
void BFS()
{
    node st,ed;
    ans.clear();
    int head=0,rear=0;
    st.x=sx;st.y=sy;st.u=u;
    st.f=f;st.pre=-1;
    CLEAR(vis,0);
    q[rear++]=st;
    while(head<rear)
    {
        st=q[head++];
        for(int i=0;i<4;i++)
        {
            int xx=st.x+dr[i][0];
            int yy=st.y+dr[i][1];
            if(xx<0||xx>r||yy<0&&yy>c)  continue;
            if(mp[xx][yy]!=-1&&st.u!=mp[xx][yy])  continue;
            if(xx==sx&&yy==sy)
            {
                print(head-1);
                ans.push_back(make_pair(sx,sy));
                int s=ans.size();
                for (int i = 0; i < s; i++)
                {
                    if (i % 9 == 0) printf("\n  ");
                    printf("(%d,%d)%c", ans[i].first, ans[i].second,
                           i == s - 1 ? '\n' : ',');
                }
                return ;
            }
            ed=st;ed.x=xx;ed.y=yy;
            solve(ed.u,ed.f,i);
            if(vis[xx][yy][ed.u][ed.f])  continue;
            vis[xx][yy][ed.u][ed.f]=1;
            ed.pre=head-1;
            q[rear++]=ed;
        }
    }
    printf("\n  No Solution Possible\n");
}
int main()
{
    char str[20];
    to[1][2] = 4; to[1][3] = 2; to[1][4] = 5; to[1][5] = 3;
    to[2][1] = 3; to[2][3] = 6; to[2][4] = 1; to[2][6] = 4;
    to[3][1] = 5; to[3][2] = 1; to[3][5] = 6; to[3][6] = 2;
    to[4][1] = 2; to[4][2] = 6; to[4][5] = 1; to[4][6] = 5;
    to[5][1] = 4; to[5][3] = 1; to[5][4] = 6; to[5][6] = 3;
    to[6][2] = 3; to[6][3] = 5; to[6][4] = 2; to[6][5] = 4;
    while(~scanf("%s",str)&&strcmp(str,"END"))
    {
         CLEAR(mp,0);
         scanf("%d%d%d%d%d%d",&r,&c,&sx,&sy,&u,&f);
         REPF(i,1,r)
         {
             REPF(j,1,c)
               scanf("%d",&mp[i][j]);
         }
         printf("%s",str);
         BFS();
    }
    return 0;
}
				
时间: 2024-10-20 05:48:57

UVA 810 筛子难题(BFS)的相关文章

UVA 810 - A Dicey Problem(BFS)

UVA 810 - A Dicey Problem 题目链接 题意:一个骰子,给你顶面和前面,在一个起点,每次能移动到周围4格,为-1,或顶面和该位置数字一样,那么问题来了,骰子能不能走一圈回到原地,输出路径,要求最短,如果有多个最短,按照上下左右输出 思路:读懂题就是水题,就记忆化搜一下即可,记录状态为位置和骰子顶面,正面(因为有两面就能确定骰子了) 代码: #include <cstdio> #include <cstring> #include <vector>

习题6-12 筛子难题 UVa810

1.题目描述:点击打开链接 2.解题思路:本题是迷宫问题,典型的BFS解法.不过首先应当确定状态是什么.根据题意描述:筛子的坐标+筛子的前面和顶面即构成了一个状态.这样以来,其实本题有点类似于隐式图的搜索.那么状态是怎么逐步扩展的呢?由于筛子每次都有四个方向可以滚动,因此通过判断滚动后的新状态是否合法即可扩展开来.不过向左,向右滚动需要提前打表,列出24种顶面是u,正面是f的右侧面值.详细部分见代码注释. 3.代码: #define _CRT_SECURE_NO_WARNINGS #includ

uva 10603 Fill (BFS)

uva 10603 Fill There are three jugs with a volume of a, b and c liters. (a, b, and c are positive integers not greater than 200). The first and the second jug are initially empty, while the third is completely filled with water. It is allowed to pour

UVA 11624 UVA 10047 两道用 BFS进行最短路搜索的题

很少用bfs进行最短路搜索,实际BFS有时候挺方便得,省去了建图以及复杂度也降低了O(N*M): UVA 11624 写的比较挫 #include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; struct node{ int ft; int sta; }flo[1010][1010]; int vis[1010][1010]; st

UVA 810 - A Dicey Problem

这道题目题意理解起来好难....以至于不想做 抄题意:! 将筛子某在某一个初始位置. 知道他的初始状态(由顶部点数 和 最前面的点数来确定) 来往四个方向进行翻转. 能够翻转的条件:当且仅当如今的顶部的点数与下一个位置的点数同样. 假设能够翻转回来. 输出路径. 难点在于,how to know the die just rely on the front and top side>.... 能够打一个大~~~~表.. . 事实上不用所有打表~由于骰子相对的两面的和 = 7: 然后是路径输出.这

UVA 11624 - Fire!(BFS)

UVA 11624 - Fire! 题目链接 题意:一个迷宫,一些格子着火了,火每秒向周围蔓延,现在J在一个位置,问他能走出迷宫的最小距离 思路:BFS2次,第一次预处理每个位置着火时间,第二次根据这个再BFS一次 代码: #include <cstdio> #include <cstring> #include <queue> using namespace std; const int d[4][2] = {0, 1, 1, 0, 0, -1, -1, 0}; co

(简单) UVA 11624 Fire! ,BFS。

Description Joe works in a maze. Unfortunately, portions of the maze have caught on fire, and the owner of the maze neglected to create a fire escape plan. Help Joe escape the maze. Given Joe's location in the maze and which squares of the maze are o

uva 10047 - The Monocycle bfs

题目链接 A monocycle is a cycle that runs on one wheel and the one we will be considering is a bit more special. It has a solid wheel colored with five different colors as shown in the figure: The colored segments make equal angles (72o) at the center. A

Uva 1600 Patrol Robot (BFS 最短路/DFS剪枝)

这道题运用的知识点是求最短路的算法.一种方法是利用BFS来求最短路. 需要注意的是,我们要用一个三维数组来表示此状态是否访问过,而不是三维数组.因为相同的坐标可以通过不同的穿墙方式到达. #include <bits/stdc++.h> using namespace std; struct Node{ int r; int c; int g; int cnt; Node(int r,int c,int g,int cnt):r(r),c(c),g(g),cnt(cnt){} }; int v