[大题解]搜索五题
QingLin001 · · 个人记录
搜索五题
\quad \color{black}\text{P1332 血色先锋队}
\quad \color{black}\text{P3395 路障}
\quad \color{black}\text{P6207 [USACO06OCT] Cows on Skates G}
\quad \color{black}\text{P1238 走迷宫}
\quad \color{black}\text{P3956 棋盘}
难度:中等
题目分析
1.血色先锋队
给定一个大小为
2.路障
给定一个大小为
3.[USACO06OCT] Cows on Skates G
给定一个大小为
4.走迷宫
给定一个大小为
5.棋盘
给定一个大小为
思路分析
1.血色先锋队
这题我们可以采用
2.路障
这题我们也可以采用
3.[USACO06OCT] Cows on Skates G
这题我使用的算法是
4.走迷宫
这题我们还是可以常规
5.棋盘
依旧是
Code Share
1.血色先锋队
#include<bits/stdc++.h>
using namespace std;
const int N=555;
int ans[N][N];
int dx[]={0,0,0,-1,1},dy[]={0,1,-1,0,0};
int n,m,a,b;
bool v[N][N];
struct node{
int x,y,t;
};
int main()
{
queue<node> q;
scanf("%d %d %d %d",&n,&m,&a,&b);
while(a--)
{
int x,y;
scanf("%d %d",&x,&y);
node p;
p.x=x,p.y=y,p.t=0;
q.push(p);
v[x][y]=1;
}
while(q.size())
{
node now=q.front();
node p;
for(int i=1;i<=4;i++)
{
now=q.front();
int x=now.x,y=now.y,t=now.t;
int xx=x+dx[i],yy=y+dy[i];
if(xx>=1 && xx<=n && yy>=1 && yy<=m && !v[xx][yy])
{
v[xx][yy]=1;
p.x=xx;
p.y=yy;
p.t=t+1;
q.push(p);
}
}
ans[now.x][now.y]=now.t;
q.pop();
}
while(b--)
{
int x,y;
scanf("%d %d",&x,&y);
printf("%d\n",ans[x][y]);
}
return 0;
}
2.路障
#include<bits/stdc++.h>
using namespace std;
const int N=1010,M=2020;
int stopx[M],stopy[M];
int dx[]={0,0,0,-1,1},dy[]={0,1,-1,0,0};
int T;
struct node{
int x,y,t;
};
bool v[N][N],v2[N][N];
int main()
{
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
for(int i=1;i<=2*n-2;i++)
scanf("%d %d",&stopx[i],&stopy[i]);
memset(v,0,sizeof(v));
memset(v2,0,sizeof(v2));
//bfs
v[1][1]=1;
bool flag=0;
queue<node> q;
node p,l;
p.x=1,p.y=1,p.t=0;
q.push(p);
while(q.size())
{
p=q.front();
q.pop();
int x=p.x;
int y=p.y;
int t=p.t;
if(x==n && y==n)
{
flag=1;
break;
}
v2[stopx[t]][stopy[t]]=1;
for(int i=1;i<=4;i++)
{
int xx=x+dx[i];
int yy=y+dy[i];
if(xx>=1 && xx<=n && yy>=1 && yy<=n && !v[xx][yy] &&!v2[xx][yy])
{
l.x=xx;
l.y=yy;
l.t=t+1;
v[xx][yy]=1;
q.push(l);
}
}
}
if(flag)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
3.[USACO06OCT] Cows on Skates G
#include<bits/stdc++.h>
using namespace std;
const int N=120,M=80;
int dx[]={0,0,0,-1,1};
int dy[]={0,-1,1,0,0};
int r,c,cnt=1,ans[100010][2];
bool v[N][M];
char a[N][M];
void dfs(int x,int y)
{
if(x==r && y==c)
{
for(int i=1;i<=cnt;i++)
printf("%d %d\n",ans[i][0],ans[i][1]);
return ;
}
for(int i=1;i<=4;i++)
{
int xx=x+dx[i],yy=y+dy[i];
if(xx>=1 && xx<=r && yy>=1 && yy<=c && !v[xx][yy] && a[xx][yy]=='.')
{
v[xx][yy]=1;
cnt++;
ans[cnt][0]=xx;
ans[cnt][1]=yy;
dfs(xx,yy);
cnt--;
}
}
}
int main()
{
scanf("%d %d",&r,&c);
for(int i=1;i<=r;i++)
{
char s[N];
scanf("%s",s+1);
for(int j=1;j<=c;j++)
a[i][j]=s[j];
}
ans[1][0]=ans[1][1]=1;
v[1][1]=1;
dfs(1,1);
return 0;
}
4.走迷宫
#include<bits/stdc++.h>
using namespace std;
const int N=16;
int a[N][N],p[50050][2];
int dx[5]={0,0,-1,0,1};
int dy[5]={0,-1,0,1,0};
int m,n,cnt;
bool v[N][N],flag;
int sx,sy,tx,ty;
void dfs(int x,int y)
{
if(x==tx && y==ty)
{
flag=1;
for(int i=1;i<=cnt;i++)
printf("(%d,%d)->",p[i][0],p[i][1]);
printf("(%d,%d)\n",tx,ty);
return ;
}
for(int i=1;i<=4;i++)
{
int xx=x+dx[i];
int yy=y+dy[i];
if(!v[xx][yy] && a[xx][yy]==1)
{
++cnt;
v[x][y]=1;
p[cnt][0]=x;
p[cnt][1]=y;
dfs(xx,yy);
v[x][y]=0;
--cnt;
}
}
}
int main()
{
scanf("%d %d",&m,&n);
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
scanf("%d",&a[i][j]);
scanf("%d %d\n%d %d",&sx,&sy,&tx,&ty);
dfs(sx,sy);
if(flag==0)
{
printf("-1");
return 0;
}
return 0;
}
5.棋盘
#include<bits/stdc++.h>
using namespace std;
const int M=101;
int a[M][M],n,m,coin=0x7f7f7f7f;
int color[M][M],d[M][M];
bool v[M][M];
int dx[]={0,1,-1,0,0},dy[]={0,0,0,1,-1};
void dfs(int x,int y,int now,bool magic)
{
if(x<1 || x>m || y<1 || y>m)
return ;
if(now>=d[x][y])
return ;
d[x][y]=now;
if(x==m && y==m) //走到终点
{
coin=min(coin,now);
return ;
}
for(int i=1;i<=4;i++)
{
int xx=x+dx[i];
int yy=y+dy[i];
//下一个格子有色
if(color[xx][yy])
{
if(color[xx][yy]!=color[x][y])
dfs(xx,yy,now+1,false);
else
dfs(xx,yy,now,false);
}
//没有用魔法
else if(!magic)
{
color[xx][yy]=color[x][y];
dfs(xx,yy,now+2,true);
color[xx][yy]=0;
}
}
}
int main()
{
memset(d,0x7f,sizeof(d));
scanf("%d %d",&m,&n);
//(1,1)->(m,m)
for(int i=1;i<=n;i++)
{
int x,y,c;
scanf("%d %d %d",&x,&y,&c);
color[x][y]=c+1;
//c==0无色,c==1为红色,c==2为黄色
//小技巧:为了区分有色和无色
}
dfs(1,1,0,false);
printf("%d",coin==0x7f7f7f7f ? -1:coin);
return 0;
}