一月二十五日总结

文章讲述了作者在学习BFS和DFS算法后尝试解决编程题目,发现对BFS不熟悉,主要通过DFS求解迷宫路径计数问题。同时,还介绍了如何利用DFS解决国际象棋车的移动路径问题,强调了处理规则和深度优先搜索的应用。
摘要由CSDN通过智能技术生成

在经过几天对bfs和dfs的学习后,自认为把握十足的我开始了刷题。然而,现实却给了我当头一棒。我发现我做了几个题中,只有那么几个是对的,有许多并没有对。除此之外,我发现我对bfs还是及其的不熟悉,只会用dfs进行求解。(可能是dfs较bfs的代码思维较为简单些吧)所以,我就对我写对的题进行一下总结。

题目描述

给定一个 N×M 方格的迷宫,迷宫里有 T 处障碍,障碍处不可通过。

在迷宫中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍。

给定起点坐标和终点坐标,每个方格最多经过一次,问有多少种从起点坐标到终点坐标的方案。

输入格式

第一行为三个正整数 N,M,T,分别表示迷宫的长宽和障碍总数。

第二行为四个正整数 SX,SY,FX,FY,SX,SY 代表起点坐标,FX,FY 代表终点坐标。

接下来 T 行,每行两个正整数,表示障碍点的坐标。

输出格式

输出从起点坐标到终点坐标的方案总数。

输入输出样例

输入 #1复制

2 2 1
1 1 2 2
1 2

输出 #1复制

1

说明/提示

对于 100%100% 的数据,1≤N,M≤5,1≤T≤10,1≤SX,FX≤n,1≤SY,FY≤m。

代码如下:

#include<cstdio>
using namespace std;

int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, -1, 0, 1};//定义方向数组
int n = 0, p, q, t, N, M;
int v[100][100] = {0};//定义访问数组,并设为全未访问

struct point {//定义结构体,表示障碍坐标
    int x;
    int y;
};

void dfs(int x, int y, struct point s[], int t) {
    if (x == p && y == q) {//如果一条路可抵达终点,则n加1,并回溯路径
        n++;
        return;
    }
    for (int i = 0; i < 4; i++) {
        int tx = x + dx[i];
        int ty = y + dy[i];//点的移动
        if (tx >= 1 && tx <= N && ty >= 1 && ty <= M && v[tx][ty] == 0) {//判断点是否出界,是否被访问
            int flag=1;
            for (int j = 0; j < t; j++) {//通过循环遍历各障碍点,判断运动点是否为障碍点
                if (tx == s[j].x && ty == s[j].y) {//当确定点为障碍点时,循环可以停止,且将flag赋值为0,排除障碍点进行深搜的可能
                    flag=0;
                    break;
                }
            }
            if (flag==1) {//对非障碍点进行深搜
                v[tx][ty] = 1;
                dfs(tx, ty, s, t);
                v[tx][ty] = 0;
            }
        }
    }
    return;
}

int main() {
    scanf("%d %d %d", &N, &M, &t);
    struct point s[t];
    int startx, starty;
    scanf("%d %d %d %d", &startx, &starty, &p, &q);//输入起点、终点
    for (int i = 0; i < t; i++) {//输入障碍坐标
        scanf("%d %d", &s[i].x, &s[i].y);
    }
    v[startx][starty] = 1;//设置起点为访问状态
    dfs(startx, starty, s, t);
    printf("%d", n);//输出路径条数
    return 0;
}

该题的思路主要就是先定义一个结构体表示障碍坐标,然后再编写深搜函数。在每次递归前,判断点是不是障碍点,然后在一直深搜,直至终点则路径多一条,最后在进行输出。

A - Rook

 CodeForces - 1907A 

你可能知道,国际象棋是一种在一个排列成8x8网格的棋盘上进行的游戏。这个棋盘的列用从a到h的字母标记,行用从1到8的数字标记。每个方格由它所属的行和列来描述。

 

车是国际象棋中的一个棋子。在它的回合中,它可以水平或垂直地移动任意非零数量的方格。你的任务是找出车在空棋盘上所有可能的移动方式。

输入

输入的第一行包含一个整数t(1≤t≤64)— 测试用例的数量。接下来是每个测试用例的描述。

每个测试用例包含一个由两个字符组成的字符串,描述了车所在的方格。第一个字符是从a到h的字母,表示列的标记,第二个字符是从1到8的数字,表示行的标记。

相同的位置可能出现在多个测试用例中。

输出

对于每个测试用例,以与输入相同的格式输出车可以移动到的所有方格的描述。

你可以以任何顺序输出每个测试用例中的方格。

示例 1

InputcopyOutputcopy
1
d5
d1
d2
b5
g5
h5
d3
e5
f5
d8
a5
d6
d7
c5
d4

Sponsor

代码如下:

#include<bits/stdc++.h>
using namespace std;

int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, -1, 0, 1};//定义方向数组

void dfs1(int x, int y, int i) {
    if (x < 'a' || x > 'h' || y < '1' || y > '8') {//判断坐标点是否出界
        return;
    }
    printf("%c%c ", x, y);//输出结果
    int tx = x + dx[i];
    int ty = y + dy[i];
    dfs1(tx, ty, i);//从运动过后的开始进行搜索
    return;
}

void dfs(char x, char y) {
    if (x < 'a' || x > 'h' || y < '1' || y > '8') {//判断坐标点是否出界
        return;
    }
    for (int i = 0; i < 4; i++) {
        int tx = x + dx[i];
        int ty = y + dy[i];
        dfs1(tx, ty, i);
    }
    return;
}

int main() {
    int t;
    scanf("%d", &t);

    for (int i = 0; i < t; i++) {
        char x, y;
        getchar();//吸收回车
        scanf("%c%c", &x, &y);
        dfs(x, y);//从给出的点开始深搜
    }

    return 0;
}

这个题目的难点就是这个象棋只会沿直线走,所以就要求你处理好它的运动方向。所以,我们就可以先写一个函数,确定其运动方向。再写一个记录方向的深搜函数,不断沿同一方向进行深搜,最后输出结果即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值