这些搜索套路好深。。。
话不多说,练习搜索
其中两个题比较典型,拿出来讲讲
1.迷宫
题意较简单,n*m迷宫中,从(x,y)到(a,b)有几条路
代码奉上(这题是广搜?用的深搜):
#include<bits/stdc++.h> //这题用队列MLE,换种思路TLE,然后用了深搜 using namespace std; int n,m,t,sx,sy,fx,fy; bool ok[6][6]; int mx[4]={0,-1,0,1}; int my[4]={-1,0,1,0}; bool vis[6][6]; //储存该点在此次访问路径是否被访问过 int sum; inline bool inside(int x,int y){ //判断是否在界内,不然没有意义 return (1<=x&&x<=n&&1<=y&&y<=m); } void search(int x,int y){ if(x==fx&&y==fy){ //到达终点情况 sum++; return;//(void可以return后不加东西) } for(int i=0;i<=3;i++){ if((inside(x+mx[i],y+my[i]))&&(ok[x+mx[i]][y+my[i]])&&(!vis[x+mx[i]][y+my[i]])){ vis[x+mx[i]][y+my[i]]=1; search(x+mx[i],y+my[i]); vis[x+mx[i]][y+my[i]]=0; //返回状态 } } } int main(){ scanf("%d%d%d%d%d%d%d",&n,&m,&t,&sx,&sy,&fx,&fy); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++) ok[i][j]=1; } for(int i=1;i<=t;i++){ int zx,zy; scanf("%d%d",&zx,&zy); ok[zx][zy]=0; } vis[sx][sy]=1; //标记起点,一开始没加wa了5个点 search(sx,sy); cout<<sum; return 0; }
这题深搜易敲,思路简单
2._GC滑迷宫(跟某龚姓网友没有半点关系!(眨眼眨眼))
以下复制:
题目背景
_GC买了一双蔡徐坤一代。(重点,记笔记!)
题目描述
_GC进入了一个n*m的迷宫。
本题的特殊之处在于,_GC只能滑着走。具体来说就是,选定一个方向后,_GC会一直向该方向滑,直到撞到墙。
会给出_GC的起始位置。只需要滑出去即可。
求最小的撞墙次数。
这题求“最小次数”,要用广搜,先要精通队列
代码:
#include<bits/stdc++.h> using namespace std; int n,m,sx,sy,a[25][25]; bool vis[25][25]; int mx[4]={0,1,0,-1}; int my[4]={1,0,-1,0}; struct pos{ int x,y,sum; pos(int a,int b,int c):x(a),y(b),sum(c){}; //构造函数,在这里就是赋值 }; queue<pos> q; //队列 inline bool inside(int x,int y){ //判断界外 return (1<=x&&x<=n)&&(1<=y&&y<=m); } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++) scanf("%d",&a[i][j]); } scanf("%d%d",&sx,&sy); if(a[sx][sy]){ //出生卡墙则无解(谁出的数据?) cout<<-1; return 0; } if(sx==1||sx==n||sy==1||sy==m){ //出生在边界则0步 cout<<0; return 0; } q.push(pos(sx,sy,0)); //队列常用函数,压入 while(!q.empty()){ pos h=q.front(); //取队首元素 q.pop(); //弹出刚取的元素 if(h.x==1||h.x==n||h.y==1||h.y==m){ //到达则输出 cout<<h.sum-1; return 0; } for(int i=0;i<=3;i++){ int nowx=h.x; int nowy=h.y; while((!a[nowx+mx[i]][nowy+my[i]])&&(inside(nowx+mx[i],nowy+my[i]))){ nowx+=mx[i]; //此循环里是控制滑动 nowy+=my[i]; } if(!vis[nowx][nowy]){ vis[nowx][nowy]=1; //同上面一题,保存是否走过 q.push(pos(nowx,nowy,h.sum+1)); } } } cout<<-1; //如果以上均无路径,则无解,输出-1 return 0; }
分别是深搜和广搜,个人喜欢深搜,毕竟代码短。。。