东北大学秦皇岛分校acm俱乐部week4

p1605迷宫

题目描述

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

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

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

输入格式

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

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

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

输出格式

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

输入输出样例

输入 #1

2 2 1
1 1 2 2
1 2

输出 #1

1

题解:

本题主要考察dfs深度优先搜索,这个递归真的伤脑筋,看了好多遍大概理解什么意思,不过还是勉强会套模板,再做几道题看能不能熟练一些。这道题有几个需要注意的地方,首先在地图里有四个移动方向,需要专门定义对应数组来实现意义上的上下左右,另外,制定地图数组的同时也要制定一个对应数组来记录该地块是否经过过。

#include<iostream>
using namespace std;
int map[100][100];
bool jilu[100][100];
int dx[4] = { 0,0,1,-1 };
int dy[4] = { -1,1,0,0 };
int cishu, zhongdianx, zhongdiany,qidianx, qidiany, zhangaishu, n, m, l, r;
void check(int x, int y);
int main()
{
    cin >> n >> m >>zhangaishu >> qidianx >> qidiany >> zhongdianx >> zhongdiany;
    for (int e = 1; e <= n; e++)
        for (int ee = 1; ee <= m;ee++)
            map[e][ee] = 1;
    for (int e = 1; e <= zhangaishu; e++)
    {
        cin >> l >> r;
        map[l][r] = 0;
    }
   check(qidianx, qidiany);
    cout << cishu;
    return 0;
}
void check(int x, int y)
{
    if (x == zhongdianx && y == zhongdiany)
    {
        cishu++;
        return;
    }
    else
    {//dfs模板
        for (int i = 0; i <= 3; i++)//实现上下左右遍历
        {
            if (jilu[x + dx[i]][y + dy[i]] == 0 && map[x + dx[i]][y + dy[i]] == 1)//判断要走的点是否走过以及要走的点是否存在
            {
                jilu[x][y] = 1;//记录走过
                check(x + dx[i], y + dy[i]);
                jilu[x][y] = 0;//清除记录
            }
        }
    }
}

P1443 马的遍历

题目描述

有一个 n \times mn×m 的棋盘,在某个点 (x, y)(x,y) 上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步。

输入格式

输入只有一行四个整数,分别为 n, m, x, yn,m,x,y。

输出格式

一个 n \times mn×m 的矩阵,代表马到达某个点最少要走几步(不能到达则输出 -1−1)。

输入输出样例

输入 #1

3 3 1 1

输出 #1

0    3    2    
3    -1   1    
2    1    4    

 题解:

学习了queue,memset,和pair的用法,练习使用了bfs模板,这个题需要看到题目中如果走不到则输出-1,所以开始需要把定义的棋盘数组用memset全部赋值为负一,这样的话最后可以直接输出,没有改变到的就是走不到的;为了方便bfs,利用了列表queue先进先出的特点,而pair可以存入对应的两个数据,两者配合正好读入坐标;最后判断条件时,不但需要考虑伴随判断数组是否记录走过该点,还需要考虑该点是否出界。

#include<iostream>
#include<queue>
#include<utility>
using namespace std;
int x[8] = { 1,1,2,2,-1,-1,-2,-2,};
int y[8] = { 2,-2,1,-1,2,-2,-1,1 };//实现八个不同方向的走位
int bushu[500][500];
bool jiancha [500][500];
queue<pair<int,int>>M;
int main() {
	int a, b, c, d;
	cin >> a >> b >> c >> d;
	memset(bushu, -1, sizeof(bushu));
	memset(jiancha, 0, sizeof(jiancha));
	bushu[c][d] =0;
	jiancha[c][d] = 1;
	M.push(make_pair(c,d));
	while (!M.empty()) {
		int qian = M.front().first;
		int hou = M.front().second;
		//cout << qian << " " << hou << endl;
		M.pop();
		for (int e = 0; e < 8; e++) {
			/*cout << qian << " " << hou << endl;
			cout << qianq << " " << houh << endl;
			cout << jiancha[qianq][houh] << endl;
			system("pause");*/
			if (qian + x[e]<1 || qian + x[e] >a || hou + y[e] < 1 || hou + y[e] >b || jiancha[qian + x[e]][hou + y[e]]) {
				continue;
			}
			jiancha[qian + x[e]][hou + y[e]]=1;
			M.push(make_pair(qian + x[e], hou + y[e]));
			bushu[qian + x[e]][hou + y[e]] = bushu[qian][hou]+1;
		}
	}
	for (int e = 1; e <= a; e++) {
		for (int ee = 1; ee <= b; ee++) {
			cout << bushu[e][ee] <<" ";
		}
		cout << endl;
	}
	system("pause");
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唏嘘南溪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值