广搜(综合问题)

首先感谢一下关注Me的朋友~

话不多说,开始~

最少步数

题目描述

在各种棋中,棋子的走法总是一定的,如中国象棋中马走“日”。有一位小学生就想如果马能有两种走法将增加其趣味性,因此,他规定马既能按“日”走,也能如象一样走“田”字。他的同桌平时喜欢下围棋,知道这件事后觉得很有趣,就想试一试,在一个(100×100)的围棋盘上任选两点A、B,A点放上黑子,B点放上白子,代表两匹马。棋子可以按“日”字走,也可以按“田”字走,俩人一个走黑马,一个走白马。谁用最少的步数走到左上角坐标为(1,1)的点时,谁获胜。现在他请你帮忙,给你A、B两点的坐标,想知道两个位置到(1,1)点可能的最少步数。

提示:棋盘左上角坐标为(1,1),右下角坐标为(100,100)

输入描述

A、B两点的坐标。

输出描述

最少步数。

样例输入
12 16
18 10
样例输出
8
9
代码

需要用12方向数组

#include<iostream>
#include<string> 
#include<cmath>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<queue>
using namespace std;
int dx[12]={-2,-2,-2,-2,-1,-1,1,1,2,2,2,2},x,y,nx,ny;
int dy[12]={-2,-1,1,2,-2,2,-2,2,-2,-1,1,2};
int step[105][105],vis[105][105];
int xa,ya,xb,yb;
void bfs(){
	queue<int>qx,qy;
	qx.push(1);
	qy.push(1);
	vis[1][1]=1;
	while(qx.empty()==0){
		x=qx.front();
		y=qy.front();
		qx.pop();
		qy.pop();
		for(int i=0;i<12;i++){
			nx=x+dx[i];
			ny=y+dy[i];
			if(nx<=100&&nx>=1&&ny<=100&&ny>=1&&vis[nx][ny]==0){
				qx.push(nx);
				qy.push(ny);
				step[nx][ny]=step[x][y]+1;
				vis[nx][ny]=1;
			}
		}
	}
	cout<<step[xa][ya]<<endl<<step[xb][yb];
}
int main(){
	cin>>xa>>ya>>xb>>yb;
	bfs();
	return 0;
}

矩阵距离

题目描述

给定一个N行M列的01矩阵A,A[i][j] 与 A[k][l] 之间的曼哈顿距离定义为:
dist(A[i][j],A[k][l])=|i-k|+|j-l|
输出一个N行M列的整数矩阵B,其中:
B[i][j]=min(1≤x≤N,1≤y≤M,A[x][y]=1)⁡{dist(A[i][j],A[x][y])}
即求与每个位置曼哈顿距离最近的1
N,M≤1000。

输入描述

第一行两个整数n,m。
接下来一个N行M列的01矩阵,数字之间没有空格。

输出描述

一个N行M列的矩阵B,相邻两个整数之间用一个空格隔开。

样例输入
3 4
0001
0011
0110
样例输出
3 2 1 0
2 1 0 0
1 0 0 1
代码 
#include<iostream>
#include<cstring> 
#include<cmath>
#include<iomanip>
#include<algorithm>
#include<cstdio>
#include<queue>
using namespace std;
char a[1005][1005];
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
int n,m,x,vis[1005][1005],step[1005][1005];
queue<int>qx,qy;
void bfs(){
	while(qx.empty()==0){
		int x=qx.front();
		int y=qy.front();
		qx.pop();
		qy.pop();
		for(int i=0;i<4;i++){
			int nx=x+dx[i];
			int ny=y+dy[i];
			if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&a[nx][ny]=='0'&&vis[nx][ny]==0){
				qx.push(nx);
				qy.push(ny);
				step[nx][ny]=step[x][y]+1;
				vis[nx][ny]=1;
			}
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>a[i][j];
			if(a[i][j]=='1'){
				qx.push(i);
				qy.push(j);
			}
		}
	}
	bfs();
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cout<<step[i][j]<<" ";
		}
		cout<<endl;
	}
	return 0;
}
  • 12
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值