深搜_尝试2

今天,我来讲解对于下题,我的理解

题目: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;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值