P1443 马的遍历
本题关键字:记忆化搜索。
首先,这题为什么会想到记忆化?
在dfs每种情况是,可能这个点之前已经搜过了,没必要再去搜索了,因此不如存储记住,就没必要再去dfs了。
我们可以利用一个数组存入从起点到每一个点所需的最短路径(mapp[next.x][next.y] = mapp[now.x][now.y] + 1;),如果直接用常规的bfs会TLE。
#include<bits/stdc++.h>
using namespace std;
const int N = 400;
int n,m;
int dx[8]={-2,-2,2,2,1,-1,1,-1};
int dy[8]={-1,1,-1,1,2,-2,-2,2};
int mapp[N][N],flag[N][N];
struct node
{
int x,y;
};
int bfs(int x,int y)
{
int cnt = 0;
queue<node> q;
node now,next;
now.x = x,now.y = y;
flag[x][y] = 1;
q.push(now);
while(!q.empty())
{
now = q.front();
q.pop();
for(int i=0;i<8;i++)
{
next.x = now.x + dx[i];
next.y = now.y + dy[i];
if(next.x>=1&&next.y>=1&&next.x<=n&&next.y<=m
&&!flag[next.x][next.y])
{
mapp[next.x][next.y] = mapp[now.x][now.y] + 1;
flag[next.x][next.y] = 1;
q.push(next);
}
}
}
}
int main()
{
memset(mapp,-1,sizeof(mapp));
int x,y;
cin>>n>>m>>x>>y;
mapp[x][y] = 0;
bfs(x,y);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
printf("%-5d",mapp[i][j]);
}
cout<<endl;
}
}
滑雪
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int n,m,a[201][201],s[201][201],ans;
int dfs(int x,int y){
if(s[x][y])return s[x][y];//记忆化搜索
s[x][y]=1;
for(int i=0;i<4;i++)
{ int xx=dx[i]+x;
int yy=dy[i]+y;
if(xx>0&&yy>0&&xx<=n&&yy<=m&&a[x][y]>a[xx][yy]){
dfs(xx,yy);
s[x][y]=max(s[x][y],s[xx][yy]+1);
}
}
return s[x][y];
}
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]);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
ans=max(ans,dfs(i,j));
printf("%d",ans);
return 0;
}