P1605 迷宫
题目描述
给定一个 N*M 方格的迷宫,迷宫里有T处障碍,障碍处不可通过。
在迷宫中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍。
给定起点坐标和终点坐标,每个方格最多经过一次,问有多少种从起点坐标到终点坐标的方案。
输入格式
第一行为三个正整数 N,M,T,分别表示迷宫的长宽和障碍总数。
第二行为四个正整数 SX,SY,FX,FY,SX,SYSX,SY 代表起点坐标,FX,FYFX,FY 代表终点坐标。
接下来 T 行,每行两个正整数,表示障碍点的坐标。
输出格式
输出从起点坐标到终点坐标的方案总数。
#include<iostream>
using namespace std;
int mx[4]={1,-1,0,0};
int my[4]={0,0,1,-1};
//一个是x轴横向移动,一个是y轴纵向移动
int N,M,T;
//迷宫的长宽及障碍的个数
int mg[6][6];
//迷宫的大小
bool vis[6][6];
//是否经过
int sx,sy,fx,fy;
//起点位置及终点位置
int temp;
//记录方案个数
void search(int x,int y){
//总方针
//不出圈
//不进障
if(fx==x&&fy==y){
temp+=1;
return;
}
else
for(int i=0;i<=3;i++){
if(0==vis[x+mx[i]][y+my[i]]&&mg[x+mx[i]][y+my[i]]==1){
//迷宫可走的点一开始全部已赋值为1
//然后障碍的点全部赋值为0
vis[x][y]=1;
search(x+mx[i],y+my[i]);
//回溯一步
vis[x][y]=0;
}
}
}
int main(){
cin>>N>>M>>T;
int p,q;
cin>>sx>>sy>>fx>>fy;
for(int i=1;i<=N;i++){
for(int j=1;j<=M;j++){
mg[i][j]=1;
}
}
for(int l=1;l<=T;l++){
cin>>p>>q;
mg[p][q]=0;
}
search(sx,sy);
cout<<temp;
return 0;
}
思路已嵌在代码中。。
P1443 马的遍历
题目描述
有一个n×m的棋盘,在某个点 (x, y)上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步。
输入格式
输入只有一行四个整数,分别为 n, m, x, y。
输出格式
一个 n×m 的矩阵,代表马到达某个点最少要走几步(不能到达则输出 −1)。
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int mx[8]={1,2,2,1,-1,-2,-2,-1};
int my[8]={2,1,-1,-2,2,1,-1,-2};
//马的跳法
int N,M,sx,sy,h[500000][3];
int vis[401][401];
//疑问:h空间的大小需要开多大?
int jump(int sx,int sy){
memset(vis,-1,sizeof(vis));
//赋一个初值用来判断是否被走过
vis[sx][sy]=0;
int t=0,w=1;
h[1][0]=sx,h[1][1]=sy,h[1][2]=0;
// x y step
do{
t++;//指针指向头
int x=h[t][0],y=h[t][1];//初始位置
for(int i=0;i<=7;i++){
int X=x+mx[i],Y=y+my[i];
//跳一步的位置
if(X>0&&X<=N&&Y>0&&Y<=M&&vis[X][Y]==-1){
//如果在范围内且这一步没有经过
w++;
//队伍加长
//(其实也没有用到队列的操作,只是单纯储存数据)
h[w][0]=X;
h[w][1]=Y;
//入队
h[w][2]=h[t][2]+1;
//此步的步数
vis[X][Y]=h[w][2];
//直接把走到的这一步的步数填入已走过的数组内
}
}
} while(t<w);
}
//目的是让马把所有位置跳一遍,根据广搜的原理,结点总是以最小的路径被遍历
int main(){
scanf("%d%d%d%d",&N,&M,&sx,&sy);
jump(sx,sy);
for(int i=1;i<=N;i++){
for(int j=1;j<=M;j++){
printf("%-5d ",vis[i][j]);
}
printf("\n");
}
return 0;
}
所有遍历到的结点都会被最小步数赋值,其余范围内的结点都是-1。