洛谷1443 分支限界法

本人原创,转载注明出处并告知:https://blog.csdn.net/coder_what/article/details/86099579

分支限界法属于五大算法之一,关于五大算法的介绍可移步我的博客:五大算法 

刚做了一个洛谷中类似的题:https://www.luogu.org/problemnew/show/P1443

我之前提到,分支限界法是属于用队列来进行广搜以求得最小路径的常用办法,很显然,这道题是一个很典型的分支限界法的应用。套用分支限界法的公式直接可AC。

//洛谷1443马的遍历
//基于广搜的分支限界法
//2019.01.08_Stonee
#include
#include
#define N 402
using namespace std;
struct COO {
	int x,y,count;
} coo[N*N];
int main() {
	int ADJ[N][N],arrx[8]={1,1,2,2,-1,-1,-2,-2},arry[8]={2,-2,1,-1,2,-2,1,-1};
	int i,j,m,n,xo,yo,counto,front,rear;
	scanf("%d%d%d%d",&m,&n,&xo,&yo);
	memset(ADJ,-1,sizeof(ADJ));
	front=rear=0;
	coo[rear].count=ADJ[xo][yo]=0;
	coo[rear].x=xo;
	coo[rear++].y=yo;
	rear=1;//初始化
	while(front0&&(yo+arry[i])>0){
				coo[rear].count=ADJ[xo+arrx[i]][yo+arry[i]]=counto+1;
				rear++;
			}
		} 
	/*	if(ADJ[xo+1][yo+2]==-1&&(xo+1)<=m&&(yo+2)<=n) {
			coo[rear].count=ADJ[xo+1][yo+2]=counto+1;
			coo[rear].x=xo+1;
			coo[rear++].y=yo+2;
		}
		if(ADJ[xo+2][yo+1]==-1&&(xo+2)<=m&&(yo+1)<=n) {
			coo[rear].count=ADJ[xo+2][yo+1]=counto+1;
			coo[rear].x=xo+2;
			coo[rear++].y=yo+1;
		}
		if(ADJ[xo+1][yo-2]==-1&&(xo+1)<=m&&(yo-2)>0) {
			coo[rear].count=ADJ[xo+1][yo-2]=counto+1;
			coo[rear].x=xo+1;
			coo[rear++].y=yo-2;
		}
		if(ADJ[xo+2][yo-1]==-1&&(xo+2)<=m&&(yo-1)>0) {
			coo[rear].count=ADJ[xo+2][yo-1]=counto+1;
			coo[rear].x=xo+2;
			coo[rear++].y=yo-1;
		}
		if(ADJ[xo-1][yo+2]==-1&&(xo-1)>0&&(yo+2)<=n) {
			coo[rear].count=ADJ[xo-1][yo+2]=counto+1;
			coo[rear].x=xo-1;
			coo[rear++].y=yo+2;
		}
		if(ADJ[xo-1][yo-2]==-1&&(xo-1)>0&&(yo-2)>0) {
			coo[rear].count=ADJ[xo-1][yo-2]=counto+1;
			coo[rear].x=xo-1;
			coo[rear++].y=yo-2;
		}
		if(ADJ[xo-2][yo+1]==-1&&(xo-2)>0&&(yo+1)<=n) {
			coo[rear].count=ADJ[xo-2][yo+1]=counto+1;
			coo[rear].x=xo-2;
			coo[rear++].y=yo+1;
		}
		if(ADJ[xo-2][yo-1]==-1&&(xo-2)>0&&(yo-1)>0) {
			coo[rear].count=ADJ[xo-2][yo-1]=counto+1;
			coo[rear].x=xo-2;
			coo[rear++].y=yo-1;
		}*/
		//	printf("counto:%d xo:%d yo:%d rear:%d front:%d ",counto,xo,yo,rear,front);
		//	getchar();getchar();
	}
	for(i=1; i<=m; i++) {
		for(j=1; j<=n; j++)
			printf("%-5d",ADJ[i][j]);
		if(i!=m)
			printf("\n");
	}
	return 0;
}
/*思路:
	1.如何计算次数:记数组的值为循环次数,将数组初始化为-1,设为没达到,原点为0,之后数组的值再原来基础上+1即可
	2.如何停止循环,即如何找到当马遍历完全的时候:当front==rear时,
	测试数据:
	6 9 1 1
	
	0 3 2 3 2 3 4 5 4
	3 4 1 2 3 4 3 4 5
	2 1 4 3 2 3 4 5 4
	3 2 3 2 3 4 3 4 5
	2 3 2 3 4 3 4 5 4
	3 4 3 4 3 4 5 4 5
	 
*/

这道题给我的启发就是,用数组可以明显减少if语句循环的次数。设定一个arrx和arry数组分别表示8个方向,通过for循环就可以代替8个if语句了。美滋滋~~

 

你可能感兴趣的:(算法和数据结构)