C语言骑士游历问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言骑士游历问题相关的知识,希望对你有一定的参考价值。

#include <stdio.h>#define N 5#define NSQUARE N*Nint HorseTry(int i, int x, int y, int h[N+1][N+1]);static int a[9] = 0, 2, 1, -1, -2, -2, -1, 1, 2;static int b[9] = 0, 1, 2, 2, 1, -1, -2, -2, -1;main() int i, j, flag, x, y; static int h[N+1][N+1] =0; printf("Input the initial position x,y:"); scanf("%d,%d", &x, &y); h[x][y] = 1; flag = HorseTry(2, x, y, h); if (flag) printf("Output:\n"); for (i=1; i<=N; i++) for (j=1; j<=N; j++) printf("%5d", h[i][j]); printf("\n"); else printf("No solution!\n"); int HorseTry(int i, int x, int y, int h[N+1][N+1]) int u, v, flag, count = 0; do count++; flag = 0; u = x + a[count]; v = y + b[count]; if ((u>=1&&u<=N) && (v>=1&&v<=N) && h[u][v]==0) h[u][v] = i; if (i < NSQUARE) flag = HorseTry(i+1, u, v, h); if (!flag) h[u][v] = 0; else flag = 1; while (!flag && count<8); return flag;这个程序我看不懂啊,谁能用语言详细解释一下啊,比如各个部分之间模块的作用

这个程序很乱 还有些地方有错误 ;
本题可以使用深度搜索发求解,但是效率很低,当路径很多时,不可能在短时间内出解。可以采用动态规划的设计思想。
从(x1,y1)位置出发,按照由左到右的顺序定义阶段的方向。位于(x2,y2)的左方且可达(x2,y2)的跳马位置集合都是(x2,y2)的子问题,起点至(x2,y2)的路径数实际上等于起点至这些位置集的路径数之和。可以按照阶段的顺序依次计算每一个阶段每个点的路径数目。
阶段i:中国象棋马当前的列位置(x1≤i≤x2)
状态j:中国象棋马在i列的行位置(1≤i≤m)
每条路径走一遍,然后得出步数,比较得到最小的就行了
状态转移方程map[i,j]:起点(x1,y1)至(i,j)的路径数目
参考技术A 写规范点,不是大牛,不要把程序,搞成这样,就是别人写的,也先整好再上传嘛! Nint都没有定义

HihoCoder 1504 : 骑士游历 (矩阵乘法)

描述

在8x8的国际象棋棋盘上给定一只骑士(俗称“马”)棋子的位置(R, C),小Hi想知道从(R, C)开始移动N步一共有多少种不同的走法。  

输入

第一行包含三个整数,N,R和C。

对于40%的数据, 1 <= N <= 1000000

对于100%的数据, 1 <= N <= 1000000000 1 <= R, C <= 8

输出

从(R, C)开始走N步有多少种不同的走法。由于答案可能非常大,你只需要输出答案模1000000007的余数。

样例输入

2 1 1

样例输出

12

 

此类题在Floyd算法里用到过,即问从a出发,走x步,有多少种方法到b点。 充分利用floyd和矩阵的相似性(3个for语句),就可以求出。

很久没有写矩阵了,温故一下。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=70;
#define ll long long
const int Mod=1e9+7;
int x[8]={2,2,-2,-2,1,1,-1,-1};
int y[8]={1,-1,1,-1,2,-2,2,-2};
struct mat
{
    ll M[maxn][maxn];
    mat() { memset(M,0,sizeof(M)); }
    mat friend operator *(mat a,mat b)
    {
        mat res;
        for(int k=1;k<=64;k++)
         for(int i=1;i<=64;i++)
          for(int j=1;j<=64;j++){
                res.M[i][j]=(res.M[i][j]+a.M[i][k]*b.M[k][j])%Mod;
         } return res;
    }
    mat friend operator ^(mat a,int x)
    {
       mat res; for(int i=1;i<=64;i++) res.M[i][i]=1;
       while(x){
            if(x&1) res=a*res; a=a*a; x/=2;
       } return res;
    }
};    

mat base;
void prepare()
{
    for(int i=1;i<=8;i++)
     for(int j=1;j<=8;j++)
      for(int k=0;k<8;k++)
        if(i+x[k]>=1&&i+x[k]<=8&&j+y[k]>=1&&j+y[k]<=8)
          base.M[(i-1)*8+j][(i+x[k]-1)*8+j+y[k]]=1;
}
int main()
{
    int N,R,C,ans=0;
    scanf("%d%d%d",&N,&R,&C);
    prepare();
    base=base^N;
    for(int i=1;i<=64;i++)  ans=(ans+base.M[(R-1)*8+C][i])%Mod;
    printf("%d\n",ans);
    return 0;
}

 

以上是关于C语言骑士游历问题的主要内容,如果未能解决你的问题,请参考以下文章

HihoCoder 1504 : 骑士游历 (矩阵乘法)

骑士游历问题

骑士游历问题(马踏棋盘)解析(c++)

POJ 2488 -- A Knight's Journey(骑士游历)

你会97年的第三题骑士游历问题,跪求啊,救命用啊谢谢啊,回头给积分,要多少给多少,谢谢

codevs——T1219 骑士游历