POJ2488 骑士游历(DFS)

题目意思是在一个国际棋盘里,判断马能否不重复的走过所有格,并记录下其中按字典序排列的第一种路径。

DFS方法解决,由于是字典顺序,所以搜索方向要严格规定

本题错了几次,原因是memset没有使用正确,此函数的第三个参数是按字节的单位,所以数组长度还要乘以sizeof(type)

160K 63MS C++ 3332B 2013-11-28 10:29:22

下图是搜索的顺序:

《POJ2488 骑士游历(DFS)》

以下是代码:

#include<iostream>
#include<vector>
#include<map>
#include <string>
#include <set>
#include <stack>
#include <queue>
using namespace std;

#include <stdio.h>
#include <string.h>


#define N_P  27
#define N_Q  27 

int g_chessboard[N_P][N_Q] = {};
char g_char[27] = {};
int g_printRule[100][2] = {};

int g_varP = 0;
int g_varQ = 0;
int g_moveNum = 0;

#define rangeP(m)  (m >= 1 && m <= g_varP)
#define rangeQ(m)  (m >= 1 && m <= g_varQ)


void getPos(int iDir, int iInP, int iInQ, int& iOutP, int& iOutQ)
{
	switch(iDir)
	{
	case 1: {iOutP=iInP-1; iOutQ=iInQ-2; break;}     
	case 2: {iOutP=iInP+1; iOutQ=iInQ-2; break;}     
	case 3: {iOutP=iInP-2; iOutQ=iInQ-1; break;} 
	case 4: {iOutP=iInP+2; iOutQ=iInQ-1; break;}  
	case 5: {iOutP=iInP-2; iOutQ=iInQ+1; break;}  
	case 6: {iOutP=iInP+2; iOutQ=iInQ+1; break;}  
	case 7: {iOutP=iInP-1; iOutQ=iInQ+2; break;}  
	case 8: {iOutP=iInP+1; iOutQ=iInQ+2; break;}  
	}
}

bool dfs(int iP, int iQ)
{
	g_chessboard[iP][iQ] = ++g_moveNum;

	if(g_moveNum == g_varP * g_varQ) // 全部走完
	{
		return true;
	}

	int iTP = 0;
	int iTQ = 0;

	for(int i = 1; i <= 8; i++)
	{
		getPos(i, iP, iQ, iTP, iTQ);

		if(!rangeP(iTP) || !rangeQ(iTQ))
		{
			continue;
		}

		if(0 == g_chessboard[iTP][iTQ])
		{
			//if(!dfs(iTP, iTQ))
			//{
			//	g_chessboard[iP][iQ] = 0;
			//	g_moveNum--;
			//}

			if(dfs(iTP, iTQ))
			{
				return true;
			}
		}
	}
	
	if(g_moveNum == g_varP * g_varQ) // 全部走完
	{
		return true;
	}
	
	g_chessboard[iP][iQ] = 0;
	g_moveNum--;
	
	return false;
}

bool visits(int& iOutP, int& iOutQ)
{
	for(int i = 1; i <= g_varP; i++)
	{
		for(int j = 1; j <= g_varQ; j++)
		{
			int iSize = (sizeof(g_chessboard) / sizeof(g_chessboard[0])) * (sizeof(g_chessboard[0]) / sizeof(g_chessboard[0][0]));

			memset(g_chessboard, 0, iSize * sizeof(int));

			g_moveNum = 0;

			if(dfs(i, j))
			{
				iOutP = i;
				iOutQ = j;
				return true;
			}
		}
	}

	return false;
}

void printRule()
{
	int iSize = (sizeof(g_printRule) / sizeof(g_printRule[0])) * (sizeof(g_printRule[0]) / sizeof(g_printRule[0][0]));

	memset(g_printRule, 0, iSize * sizeof(int));

	for(int i = 1; i <= g_varP; i++)
	{
		for(int j = 1; j <= g_varQ; j++)
		{
			g_printRule[g_chessboard[i][j]][0] = i;
			g_printRule[g_chessboard[i][j]][1] = j;
		}
	}

	for(int k = 1; k <= g_moveNum; k++)
	{
		//g_printRule[k][0];
		//g_printRule[k][1]; // char
		printf("%c%d", g_char[g_printRule[k][1]], g_printRule[k][0]);
	}

	printf("\n");
}

int main()
{
	//int take = ::GetTickCount();
	
	//freopen("in47.txt", "r", stdin);
    //freopen("out47.txt", "w", stdout);

	int iLen = sizeof(g_char) / sizeof(g_char[0]);

	for(int i = 0; i < iLen; i++)
	{
		g_char[i+1] = char(int('A') + i);
	}

	int iNumTest = 0;
	int p = 0;
	int q = 0;

	scanf("%d",&iNumTest);

	for(int i = 0; i < iNumTest; i++)
	{
		scanf("%d %d", &g_varP, &g_varQ);
		
		printf("Scenario #%d:\n", i+1);
		if(visits(p, q))
		{
			//printf("Scenario #  ok %d %d\n", p, q);
			printRule();
		}
		else
		{
			printf("impossible\n");
		}

		if(i != iNumTest-1)
		printf("\n");
	}

	//cout<<::GetTickCount() - take<<endl;
	return 0;
}

    原文作者:骑士周游问题
    原文地址: https://blog.csdn.net/gucheng789/article/details/17002393
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞