题目意思是在一个国际棋盘里,判断马能否不重复的走过所有格,并记录下其中按字典序排列的第一种路径。
DFS方法解决,由于是字典顺序,所以搜索方向要严格规定
本题错了几次,原因是memset没有使用正确,此函数的第三个参数是按字节的单位,所以数组长度还要乘以sizeof(type)
160K 63MS C++ 3332B 2013-11-28 10:29:22
下图是搜索的顺序:
以下是代码:
#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;
}