今天,我来讲解对于下题,我的理解
题目:https://www.luogu.com.cn/problem/P1002
题目就是洛谷的1002题
当然,我还是没有过啊,RE与TLE
但是在这里,我还是想写出我的思想,做法,尽管不怎么优秀
分析:利用马的坐标,把马可以拦住的点都举出,并把这些点和马的拦点的坐标代表数组元素a[x][y]设置为1,然后dfs,我们需要当前点的坐标,因此设置两个形参,x,y,后面dfs的出口——a[x][y]的值为终点的值(此前我们把终点值变为6),接下来开始一般的搜索,先向下,再向右,一般套路,我们设一个标记数组f[i],i表示第i步,f[i]初始为0,f[i]为0,进行向下,再调用自己,f[i]为1,如果f[i]为1,进行向右,再调用自己,f[i]变为2,一旦为2,退出循环,这样是不够,因为不能一直向下,因此还需要判断,到终点的横坐标,纵坐标就停,在这里需要设置变量来保存f[i],如果向下走,就把f变为1,再dfs,再变回中间变量,向右同理。
#include<stdio.h>
long long a[21][21]={0},f[100]={0};
int sum=0;
int *xx,*yy;
int dfs(int i,int x,int y)
{
//printf("i=%d x=%d y=%d a[x][y]=%d f[i-1]=%d f[i]=%d f[i+1]=%d\n",i,x,y,a[x][y],f[i-1],f[i],f[i+1]);
//看看具体情况
if(a[x][y]==6){
sum++;
return 0;//出口,并且加和,统计,
}
if(a[x][y]==1) return 0;//
//返回的情况差不多完了,接着要搜索了,先向下搜索,再向右搜索,具体我肯定要标记,
while(f[i]!=2)
{
if(x==*xx)//到边界
{
int t=f[i];//这里设置中间变量t,保存之前的信息
f[i]=1;
dfs(i+1,x,y+1);
f[i]=t;
return 0;
}
if(y==*yy)//到边界
{
int t=f[i];
f[i]=2;
dfs(i+1,x+1,y);
f[i]=t;
return 0;
}
if(f[i]==0)//向下
{
f[i]=1;
dfs(i+1,x+1,y);
}
if(f[i]==1)//向右
{
dfs(i+1,x,y+1);
f[i]=2;
}
}
f[i]=0;
}
//这次开头比抓牛好,有极大的进步
int main()
{
int x1,y1,x2,y2;
scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
xx=&x1,yy=&y1;
a[x1][y1]=6;
a[x2][y2]=1;
if(x2+2<=x1)
{
a[x2+2][y2-1]=1;
if(y2+1<=y1)
a[x2+2][y2+1]=1;
}
if(x2+1<=x1)
{
a[x2+1][y2-2]=1;
if(y2+2<=y1)
a[x2+1][y2+2]=1;
}
if(y2+2<=y1)
{
a[x2-1][y2+2]=1;
}
if(y2+1<=y1)
{
a[x2-2][y2+1]=1;
}
a[x2-2][y2-1]=1;
a[x2-1][y2-2]=1;
int i,j;
/* for(i=0;i<x1+1;i++)
{
for(j=0;j<y1+1;j++) printf("%3d",a[i][j]);
printf("\n");
}*/
dfs(0,0,0);
printf("%d",sum);
return 0;
}