【搜索算法】练习一:poj1321 棋盘问题、poj2251 Dungeon Master

文章目录

      • poj1321 棋盘问题
        • 1.题目描述
        • 2.输入要求
        • 3.输出要求
        • 4.测试样例
        • 5.代码
      • poj2251 Dungeon Master
        • 1.题目描述
        • 2.输入要求
        • 3.输出要求
        • 4.题目解释
        • 5.测试样例
        • 6.代码

poj1321 棋盘问题

题目链接:https://vjudge.net/problem/POJ-1321

1.题目描述

  在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。

2.输入要求

  输入含有多组测试数据。
  每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n
  当为-1 -1时表示输入结束。
  随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。

3.输出要求

  对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。

4.测试样例
Sample Input
2 1
#.
.#
4 4
...#
..#.
.#..
#...
-1 -1

Sample Output
2
1
5.代码
#include
using namespace std;

int n,k,ans;

//构建结构体
struct qipan{
    char s[10][10]; //存储当前状态下的棋盘
    int before_low; //存储当前状态的上一行
};

//dfs深度优先遍历
void dfs(qipan q,int k)
{
    //这里的k代表剩余的可放置的棋子数
    //如果k为0说明此种方法可行,ans++
    if(k==0)
    {
        ans++;
        return;
    }
    else
    {
        for(int i=q.before_low+1;i<=n-k;i++)
        {
            for(int j=0;j<n;j++)
            {
                //找到可以放置棋子的位置
                if(q.s[i][j]=='#')
                {
                    qipan q1;
                    q1 = q;
                    q1.before_low = i;
                    //把棋子所在这一列清空
                    for(int m=i;m<n;m++)
                    {
                        q1.s[m][j] = '.';
                    }
                    //下一个棋盘状态
                    dfs(q1,k-1);
                }
            }
        }
    }
}

int main()
{
    while(cin>>n>>k)
    {
        if(n==-1 && k==-1) break;
        else
        {
            //初始化
            ans = 0;
            qipan q;
            q.before_low = -1;
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<n;j++)
                {
                    cin>>q.s[i][j];
                }
            }
            dfs(q,k);
            cout<<ans<<endl;
        }
    }
    return 0;
}

poj2251 Dungeon Master

题目链接:https://vjudge.net/problem/POJ-2251

1.题目描述

  You are trapped in a 3D dungeon and need to find the quickest way out! The dungeon is composed of unit cubes which may or may not be filled with rock. It takes one minute to move one unit north, south, east, west, up or down. You cannot move diagonally and the maze is surrounded by solid rock on all sides.

  Is an escape possible? If yes, how long will it take?

2.输入要求

  The input consists of a number of dungeons. Each dungeon description starts with a line containing three integers L, R and C (all limited to 30 in size).
  L is the number of levels making up the dungeon.
  R and C are the number of rows and columns making up the plan of each level.
  Then there will follow L blocks of R lines each containing C characters. Each character describes one cell of the dungeon. A cell full of rock is indicated by a ‘#’ and empty cells are represented by a ‘.’. Your starting position is indicated by ‘S’ and the exit by the letter ‘E’. There’s a single blank line after each level. Input is terminated by three zeroes for L, R and C.

3.输出要求

  Each maze generates one line of output. If it is possible to reach the exit, print a line of the form

Escaped in x minute(s).

  where x is replaced by the shortest time it takes to escape.
If it is not possible to escape, print the line

Trapped!

4.题目解释

  题目的大致意思如下,现在有一个三维的迷宫,起点为S,终点为E,可以上下左右前后6个方向行走,每走一步耗时一分钟,其中#代表障碍,.代表空白(可以走),问有没有一条从S到E的路,以及最短需要多长时间。

5.测试样例
Sample Input
3 4 5
S....
.###.
.##..
###.#

#####
#####
##.##
##...

#####
#####
#.###
####E

1 3 3
S##
#E#
###

0 0 0

Sample Output
Escaped in 11 minute(s).
Trapped!
6.代码
#include
#include
#include
using namespace std;

int L,R,C;
char mg[30][30][30]; //存储迷宫
int step[30][30][30]; //存储到达每一个点的步数
int sz,sx,sy; //起点坐标
int ez,ex,ey; //终点坐标

int dir_z[6] = {-1,1,0,0,0,0};
int dir_x[6] = {0,0,-1,1,0,0};
int dir_y[6] = {0,0,0,0,-1,1};

struct node{
    int z,x,y;
    node(int zz,int xx,int yy) //结构体构造函数
    {
        z = zz;
        x = xx;
        y = yy;
    }
};

//bfs广度优先遍历
void bfs()
{
    queue<node> q;
    q.push(node(sz,sx,sy));
    while(!q.empty())
    {
        node fq = q.front();
        q.pop();
        //判断是不是到达终点
        if(fq.z==ez && fq.x==ex && fq.y==ey) break;
        else
        {
            int nz,nx,ny;
            //上下左右前后6个方向
            for(int i=0;i<6;i++)
            {
                nz = fq.z + dir_z[i];
                nx = fq.x + dir_x[i];
                ny = fq.y + dir_y[i];
                if(nz>=0 && nz<L && nx>=0 && nx<R && ny>=0 && ny<C)
                {
                    if(mg[nz][nx][ny]!='#' && step[nz][nx][ny]==-1)
                    {
                        q.push(node(nz,nx,ny));
                        step[nz][nx][ny] = step[fq.z][fq.x][fq.y] + 1;
                    }
                }
            }
        }
    }
}

int main()
{
    while(cin>>L>>R>>C)
    {
        if(L==0 && R==0 && C==0) break;
        else
        {
            //初始化
            memset(step,-1,sizeof(step));
            for(int i=0;i<L;i++)
            {
                for(int j=0;j<R;j++)
                {
                    for(int k=0;k<C;k++)
                    {
                        cin>>mg[i][j][k];
                        if(mg[i][j][k]=='S')
                        {
                            sz = i;
                            sx = j;
                            sy = k;
                            //起点的step为0
                            step[i][j][k] = 0;
                        }
                        else if(mg[i][j][k]=='E')
                        {
                            ez = i;
                            ex = j;
                            ey = k;
                        }
                    }
                }
            }
            bfs();
            if(step[ez][ex][ey]==-1) cout<<"Trapped!"<<endl;
            else cout<<"Escaped in "<<step[ez][ex][ey]<<" minute(s)."<<endl;
        }
    }
    return 0;
}

你可能感兴趣的:(算法笔记,bfs,dfs)