【第05题】骑士走棋盘

简介: 【第05题】骑士走棋盘

说明

骑士旅游(Knight tour)在十八世纪初倍受数学家与拼图迷的注意,它什么时候被提出已不可考,骑士的走法为西洋棋的走法,骑士可以由任一个位置出发,它要如何走完[所有的位置?

解法

骑士的走法,基本上可以使用递回来解决,但是纯綷的递回在维度大时相当没有效率,一个聪明的解法由J.C.  Warnsdorff在1823年提出,简单的说,先将最难的位置走完,接下来的路就宽广了,骑士所要走的下一步,「为下一步再选择时,所能走的步数最少的一步。」,使用这个方法,在不使用递回的情况下,可以有较高的机率找出走法(找不到走法的机会也是有的)。

#include <stdio.h> 
int board[8][8] = {0}; 
int main(void) {
    int startx, starty;
    int i, j;
    printf("输入起始点:");
    scanf("%d %d", &startx, &starty);
    if(travel(startx, starty)) {
        printf("游历完成!\n");
    }
    else {
        printf("游历失败!\n");
    }
    for(i = 0; i < 8; i++) {
        for(j = 0; j < 8; j++) {
            printf("%2d ", board[i][j]);
        }
        putchar('\n');
    }
    return 0;
} 
int travel(int x, int y) {
    // 对应骑士可走的八个方向
    int ktmove1[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
    int ktmove2[8] = {1, 2, 2, 1, -1, -2, -2, -1};
    // 测试下一步的出路
    int nexti[8] = {0};
    int nextj[8] = {0};
    // 记录出路的个数
    int exists[8] = {0};
    int i, j, k, m, l;
    int tmpi, tmpj;
    int count, min, tmp;
    i = x;
    j = y;
    board[i][j] = 1;
    for(m = 2; m <= 64; m++) {
        for(l = 0; l < 8; l++) 
            exists[l] = 0;
        l = 0;
        // 试探八个方向
        for(k = 0; k < 8; k++) {
            tmpi = i + ktmove1[k];
            tmpj = j + ktmove2[k];
            // 如果是边界了,不可走
            if(tmpi < 0 || tmpj < 0 || tmpi > 7 || tmpj > 7)
                continue;
            // 如果这个方向可走,记录下来
            if(board[tmpi][tmpj] == 0) {
                nexti[l] = tmpi;
                nextj[l] = tmpj;
                // 可走的方向加一个
                l++;
            }
        }
        count = l;
        // 如果可走的方向为0个,返回
        if(count == 0) {
            return 0;
        }
        else if(count == 1) {
            // 只有一个可走的方向
            // 所以直接是最少出路的方向
            min = 0;
        }
        else {
            // 找出下一个位置的出路数
            for(l = 0; l < count; l++) {
                for(k = 0; k < 8; k++) {
                    tmpi = nexti[l] + ktmove1[k];
                    tmpj = nextj[l] + ktmove2[k];
                    if(tmpi < 0 || tmpj < 0 || 
                       tmpi > 7 || tmpj > 7) {
                        continue;
                    }
                    if(board[tmpi][tmpj] == 0)
                        exists[l]++;
                }
            }
            tmp = exists[0];
            min = 0;
            // 从可走的方向中寻找最少出路的方向
            for(l = 1; l < count; l++) {
                if(exists[l] < tmp) {
                    tmp = exists[l];
                    min = l;
                }
            }
        }
        // 走最少出路的方向
        i = nexti[min];
        j = nextj[min];
        board[i][j] = m;
    }
    return 1;
} 


相关文章
|
3月前
|
存储 人工智能 容灾
阿里云服务器2核8G、4核16G、8核32G配置热门实例性能对比与场景化选型指南
2核8G/4核16G/8核32G配置的阿里云服务器在阿里云活动中目前有经济型e、通用算力型u1、通用型g7、通用型g8y和通用型g9i五种实例可选,目前2核8G配置选择u1实例活动价格652.32元1年起,4核16G月付选择经济型e实例最低89元1个月,8核32G配置160元1个月起,本文将为大家解析经济型e、通用算力型u1、通用型g7及通用型g8y实例,帮助用户根据自身需求合理选择最适合的实例规格和配置。
|
SQL 前端开发 安全
Gin-Vue-Admin 使用 gin+vue 进行极速开发的全栈开发基础平台【gva 第一节】
功能: 1.增加了 pgsql 数据库初始化,用户可选用 pgsql 进行开发。 2.增加了业务数据库功能,用户可通过 yaml 中配置自己的业务数据库,根据 name 获取业务库进行业务操作,实现框架和业务的数据库分离。 3.oss 集成了华为云 oss。 4.前端打包增加了提示内存不足时的一键 node 内存扩容 build 命令。 5.调整了获取用户信息的方法,增加了不鉴权模式下的用户信息获取方式。 6.配置页面调整。 7.取消了自动化代码中数据库类型和 size 的选择模块,防止自动化代码报错。
742 0
|
Web App开发 Linux iOS开发
Chrome浏览器如何导出所有书签并导入书签
【11月更文挑战第4天】本文介绍了如何在 Chrome 浏览器中导出和导入书签。导出时,打开书签管理器,点击“整理”按钮选择“导出书签”,保存为 HTML 文件。导入时,同样打开书签管理器,点击“整理”按钮选择“导入书签”,选择之前导出的 HTML 文件即可。其他主流浏览器也支持导入这种格式的书签文件。
10203 2
|
JSON 前端开发 决策智能
Multi-Agent实践第6期:面向智能体编程:狼人杀在AgentScope
本期文章,我们会介绍一下AgentScope的一个设计哲学(Agent-oriented programming)
|
JavaScript 前端开发 Java
淘宝/天猫获取sku详细信息 API接口(如何抓取别人的sku图淘宝)
淘宝/天猫平台提供了获取商品SKU(Stock Keeping Unit,库存量单位)详细信息的API接口。SKU通常代表一种具有独特属性的商品变体,如颜色、尺寸等。为了获取淘宝/天猫商品的SKU详细信息,您可以遵循以下步骤:
|
Web App开发 安全 IDE
软件测试 测试自动化习题及答案
软件测试 测试自动化习题及答案
719 0
|
负载均衡 前端开发 Java
SpringBoot如何使用Feign实现远程接口调用
SpringBoot如何使用Feign实现远程接口调用
1311 0
SpringBoot如何使用Feign实现远程接口调用
|
传感器 机器学习/深度学习 数据采集
多模态最新Benchmark!aiMotive DataSet:远距离感知数据集(上)
本文引入了一个多模态数据集,用于具有远程感知的鲁棒自动驾驶。该数据集由176个场景组成,具有同步和校准的激光雷达(Lidar)、相机和毫米波雷达(Radar),覆盖360度视场。所收集的数据是在白天、夜间和下雨时在高速公路、城市和郊区捕获的,并使用具有跨帧一致标识符的3D边界框进行标注。此外,本文训练了用于三维目标检测的单模态和多模态基线模型。
多模态最新Benchmark!aiMotive DataSet:远距离感知数据集(上)
|
程序员 图形学
1.使用Blender制作第一个模型
1.使用Blender制作第一个模型
813 0