手搓哈希表、列表、队列,只为了用C语言快速求解华容道游戏,我不是大佬,只是一个游戏算法爱好者

背景

多年前曾经写过C语言求解华容道,当时没有用到哈希表,导致整个查重搜索数组过大,每次求解都得花上数分钟的时间,如今时过境迁,对数据结构和算法有了更深的理解,所以得把这一块补上了。(其实就是最近想换工作,发现都喜欢算法大佬,所以写一个来敲一敲面试官的脑壳)

游戏

华容道挑战 7724游戏

方案

 把曹操格子用1表示,横将用2表示,竖将用3表示,小兵用4表示,空地用0表示,上图可以转化了代号

2244
3110
3110
3433
3433

把上术内容保存到文本文件problem.txt当中

编写源文件main.c,内容为

/*==============依赖库导入 start================*/
#include<stdio.h>				/* 标准输入输出库 */
#include<string.h>				/* 字符串处理库 */
#include<malloc.h>				/* 动态内存管理库 */
/*==============依赖库导入 end==================*//*================宏定义 start==================*/
/* 格子宏 */
#define SPACE '0'				/* 空格 */
#define BIG '1'					/* 大格 */
#define HORIZONTAL '2'			/* 横格 */
#define VERTICAL '3'			/* 竖格 */
#define SMALL '4'				/* 小格 */
/* 方向宏 */
#define UP 1					/* 上 */
#define DOWN 2					/* 下 */
#define LEFT 3					/* 左 */
#define RIGHT 4					/* 右 */
/* 哈希宏 */
#define PRIMER 31				/* 素数系数 */
#define MOD 10007				/* 素数哈希 */
/*================宏定义 end====================*//*===============数据结构 start=================*/
typedef struct LinkList { 		/* 链表 */char *str;					/* 字符串 */struct LinkList *next;		/* 下一个节点指针 */
} LinkList;typedef struct HashSet {		/* 哈希集合 */LinkList *linkList[MOD];	/* 链表数组 */
} HashSet;typedef struct Block {			/* 方块 */char type;					/* 类型 */int x;						/* 左上角横坐标 */int y;						/* 左上角纵坐标 */int w,h;					/* 格子宽高 */struct Block *next;			/* 下一个节点 */
} Block;typedef struct Operation {		/* 操作 */int x,y;					/* 格子位置 */int direction;				/* 移动类型 */
} Operation;typedef struct Node {			/* 节点 */char **arr;					/* 字符数组 */Operation *operation;		/* 上一步操作 */struct Node *previous;		/* 上一个节点 */struct Node *next;			/* 下一个节点 */
} Node;typedef struct Queue {			/* 队列 */Node *head;					/* 队头 */Node *tail;					/* 队尾 */int count;					/* 数量 */
} Queue;
/*===============数据结构 end===================*//* 从文件读取题目 */
void readProblemFile(char **arr,char *filepath) {freopen(filepath,"r",stdin);int i,j;for(i=0; i<5; i++) {scanf("%s",arr[i]);printf("%s\n",arr[i]);}printf("\n");
}/* 获取字符数组哈希码 */
int hashCode(char **arr,char value[]) {int res=0;int i,j,k=0;for(i=0; i<5; i++) {for(j=0; j<4; j++) {value[k]=arr[i][j];k++;res=res*PRIMER+arr[i][j]-'0';res%=MOD;}}return res;
}/* 往哈希表中添加对象 */
int addObjectToHashSet(char **arr,HashSet *hashSet) {char value[21]= {'\0'};int code=hashCode(arr,value);LinkList *linkList=hashSet->linkList[code];while(linkList!=NULL) {if(strcmp(linkList->str,value)==0) {return 0;} else {linkList=linkList->next;}}LinkList *listHead=(LinkList*)malloc(sizeof(LinkList));listHead->str=(char*)malloc(sizeof(char)*21);strcpy(listHead->str,value);listHead->next=hashSet->linkList[code];hashSet->linkList[code]=listHead;return 1;
}/* 释放哈希表 */
void freeHashSet(HashSet *hashSet) {int i;for(i=0; i<MOD; i++) {while(hashSet->linkList[i]!=NULL) {LinkList *linkList=hashSet->linkList[i];hashSet->linkList[i]=hashSet->linkList[i]->next;free(linkList);}}free(hashSet);
}/* 入队 */
void enQueue(char **arr,int x,int y,int direction,Queue *queue) {int i;Node *node=(Node*)malloc(sizeof(Node));node->arr=(char**)malloc(sizeof(char*)*5);for(i=0; i<5; i++) {node->arr[i]=(char*)malloc(sizeof(char)*5);strcpy(node->arr[i],arr[i]);}if(x==-1||y==-1||direction==-1) {node->operation=NULL;} else {node->operation=(Operation*)malloc(sizeof(Operation));node->operation->x=x;node->operation->y=y;node->operation->direction=direction;}node->previous=NULL;node->next=NULL;if(queue->head==NULL) {queue->head=node;queue->tail=node;queue->count=0;} else {queue->tail->next=node;node->previous=queue->head;queue->tail=node;}queue->count++;
}/* 出队 */
void deQueue(Queue *queue) {queue->head=queue->head->next;queue->count--;
}/* 释放队列 */
void freeQueue(Queue *queue) {while(queue->head!=NULL) {Node* node=queue->head;queue->head=queue->head->next;if(node->operation!=NULL) {free(node->operation);}if(node->arr!=NULL) {int i;for(i=0; i<5; i++) {free(node->arr[i]);}free(node->arr);}}free(queue);
}/* 生成格子链表 */
Block* getBlocks(char **arr) {int i,j,u,v;Block* blocks=NULL;char temp[5][4]= {0};for(i=0; i<5; i++) {strcpy(temp[i],arr[i]);}for(i=0; i<5; i++) {for(j=0; j<4; j++) {if(temp[i][j]==SPACE) {continue;}Block *block=(Block*)malloc(sizeof(Block));block->next=blocks;blocks=block;block->type=temp[i][j];block->x=i;block->y=j;switch(temp[i][j]) {case BIG:block->w=2;block->h=2;break;case HORIZONTAL:block->w=2;block->h=1;break;case VERTICAL:block->w=1;block->h=2;break;case SMALL:block->w=1;block->h=1;break;}for(u=i; u<i+block->h; u++) {for(v=j; v<j+block->w; v++) {temp[u][v]=SPACE;}}}}return blocks;
}/* 释放格子链表 */
void freeBlocks(Block *blocks) {while(blocks->next!=NULL) {Block *block=blocks;blocks=blocks->next;free(block);}
}/* 创建字符数组 */ 
char** createArray() {int i,j;char** res=(char**)malloc(sizeof(char*)*5);for(i=0; i<5; i++) {res[i]=(char*)malloc(sizeof(char)*5);for(j=0; j<4; j++) {res[i][j]='0';}res[i][4]='\0';}return res;
}/* 释放字符数组 */
void freeArray(char **arr) {int i;for(i=0; i<5; i++) {free(arr[i]);}free(arr);
}/* 方块转字符数组 */
void blocksToArray(Block *blocks,char **arr) {int i,j;while(blocks!=NULL) {Block *block=blocks;blocks=blocks->next;for(i=block->x; i<block->x+block->h; i++) {for(j=block->y; j<block->y+block->w; j++) {arr[i][j]=block->type;}}}
}/* 打印所求结果 */
void displaySolution(Node *node) {if(node->operation==NULL) {return;} else {displaySolution(node->previous);int i;char directionName[][10]= {"","↑","↓","←","→"};printf("[%d,%d] %s\n",node->operation->x,node->operation->y,directionName[node->operation->direction]);}
}/* 主函数 */
int main(int argc,char *argv[]) {char **array=(char**)malloc(sizeof(char*)*5);int i,j;for(i=0; i<5; i++) {array[i]=(char*)malloc(sizeof(char)*5);array[i][4]='\0';}if(argc==2) {readProblemFile(array,argv[1]);} else {strcpy(array[0],"3113\0");strcpy(array[1],"3113\0");strcpy(array[2],"3223\0");strcpy(array[3],"3443\0");strcpy(array[4],"4004\0");}HashSet hashSet;for(i=0; i<MOD; i++) {hashSet.linkList[i]=NULL;}Queue queue;queue.head=NULL;queue.tail=NULL;Node *result=NULL;addObjectToHashSet(array,&hashSet);enQueue(array,-1,-1,-1,&queue);free(array);while(queue.head!=NULL) {Node *node=queue.head;if(node->arr[3][1]==BIG && node->arr[4][2]==BIG) {result=node;break;}Block *blocks=getBlocks(node->arr);Block *blocksHead=blocks;while(blocksHead!=NULL) {Block *block=blocksHead;blocksHead=blocksHead->next;char **arr=NULL;switch(block->type) {case BIG:if(block->x>0 && node->arr[block->x-1][block->y]==SPACE && node->arr[block->x-1][block->y+1]==SPACE) {arr=createArray();block->x--;blocksToArray(blocks,arr);block->x++;if(addObjectToHashSet(arr,&hashSet)) {enQueue(arr,block->x,block->y,UP,&queue);}}if(block->x+block->h<5 && node->arr[block->x+block->h][block->y]==SPACE && node->arr[block->x+block->h][block->y+1]==SPACE) {arr=createArray();block->x++;blocksToArray(blocks,arr);block->x--;if(addObjectToHashSet(arr,&hashSet)) {enQueue(arr,block->x,block->y,DOWN,&queue);}}if(block->y>0 && node->arr[block->x][block->y-1]==SPACE && node->arr[block->x+1][block->y-1]==SPACE) {arr=createArray();block->y--;blocksToArray(blocks,arr);block->y++;if(addObjectToHashSet(arr,&hashSet)) {enQueue(arr,block->x,block->y,LEFT,&queue);}}if(block->y+block->w<4 && node->arr[block->x][block->y+block->w]==SPACE && node->arr[block->x+1][block->y+block->w]==SPACE) {arr=createArray();block->y++;blocksToArray(blocks,arr);block->y--;if(addObjectToHashSet(arr,&hashSet)) {enQueue(arr,block->x,block->y,RIGHT,&queue);}}break;case HORIZONTAL:if(block->x>0 && node->arr[block->x-1][block->y]==SPACE && node->arr[block->x-1][block->y+1]==SPACE) {arr=createArray();block->x--;blocksToArray(blocks,arr);block->x++;if(addObjectToHashSet(arr,&hashSet)) {enQueue(arr,block->x,block->y,UP,&queue);}}if(block->x+block->h<5 && node->arr[block->x+block->h][block->y]==SPACE && node->arr[block->x+block->h][block->y+1]==SPACE) {arr=createArray();block->x++;blocksToArray(blocks,arr);block->x--;if(addObjectToHashSet(arr,&hashSet)) {enQueue(arr,block->x,block->y,DOWN,&queue);}}if(block->y>0 && node->arr[block->x][block->y-1]==SPACE) {arr=createArray();block->y--;blocksToArray(blocks,arr);block->y++;if(addObjectToHashSet(arr,&hashSet)) {enQueue(arr,block->x,block->y,LEFT,&queue);}}if(block->y+block->w<4 && node->arr[block->x][block->y+block->w]==SPACE) {arr=createArray();block->y++;blocksToArray(blocks,arr);block->y--;if(addObjectToHashSet(arr,&hashSet)) {enQueue(arr,block->x,block->y,RIGHT,&queue);}}break;case VERTICAL:if(block->x>0 && node->arr[block->x-1][block->y]==SPACE) {arr=createArray();block->x--;blocksToArray(blocks,arr);block->x++;if(addObjectToHashSet(arr,&hashSet)) {enQueue(arr,block->x,block->y,UP,&queue);}}if(block->x+block->h<5 && node->arr[block->x+block->h][block->y]==SPACE) {arr=createArray();block->x++;blocksToArray(blocks,arr);block->x--;if(addObjectToHashSet(arr,&hashSet)) {enQueue(arr,block->x,block->y,DOWN,&queue);}}if(block->y>0 && node->arr[block->x][block->y-1]==SPACE && node->arr[block->x+1][block->y-1]==SPACE) {arr=createArray();block->y--;blocksToArray(blocks,arr);block->y++;if(addObjectToHashSet(arr,&hashSet)) {enQueue(arr,block->x,block->y,LEFT,&queue);}}if(block->y+block->w<4 && node->arr[block->x][block->y+block->w]==SPACE && node->arr[block->x+1][block->y+block->w]==SPACE) {arr=createArray();block->y++;blocksToArray(blocks,arr);block->y--;if(addObjectToHashSet(arr,&hashSet)) {enQueue(arr,block->x,block->y,RIGHT,&queue);}}break;case SMALL:if(block->x>0 && node->arr[block->x-1][block->y]==SPACE) {arr=createArray();block->x--;blocksToArray(blocks,arr);block->x++;if(addObjectToHashSet(arr,&hashSet)) {enQueue(arr,block->x,block->y,UP,&queue);}}if(block->x+block->h<5 && node->arr[block->x+block->h][block->y]==SPACE) {arr=createArray();block->x++;blocksToArray(blocks,arr);block->x--;if(addObjectToHashSet(arr,&hashSet)) {enQueue(arr,block->x,block->y,DOWN,&queue);}}if(block->y>0 && node->arr[block->x][block->y-1]==SPACE) {arr=createArray();block->y--;blocksToArray(blocks,arr);block->y++;if(addObjectToHashSet(arr,&hashSet)) {enQueue(arr,block->x,block->y,LEFT,&queue);}}if(block->y+block->w<4 && node->arr[block->x][block->y+block->w]==SPACE) {arr=createArray();block->y++;blocksToArray(blocks,arr);block->y--;if(addObjectToHashSet(arr,&hashSet)) {enQueue(arr,block->x,block->y,RIGHT,&queue);}}break;}}while(blocks!=NULL) {blocksHead=blocks;blocks=blocks->next;free(blocksHead);}deQueue(&queue);}if(result!=NULL) {printf("求解完成\n");displaySolution(result);} else {printf("此题无解\n");}freeHashSet(&hashSet);freeQueue(&queue); return 0;
}

编译源文件main.c得到可执行程序main.exe,把main.exe和problem.txt放在同一个文件夹下。

使用cmd打开此目录,执行命令

main.exe problem.txt > 1.txt

稍后便可在目录下生成1.txt文件,里边保存的就是游戏的通关参考答案。

2244
3110
3110
3433
3433求解完成
[3,3] ↑
[2,3] ↑
[3,2] →
[4,1] →
[3,1] ↓
[1,1] ↓
[0,2] ↓
[1,2] ←
[0,3] ←
[1,3] ↑
[3,3] ↑
[4,2] →
[0,2] ↓
[0,0] →
[1,0] ↑
[3,0] ↑
[4,1] ←
[2,1] ↓

思路

之前已经有博文进行了详细介绍,此处不再赘述。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/147833.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis面经

Redis使用场景 1、缓存&#xff1a; 缓存三兄弟(穿透、击穿、雪崩) 、双写一致、持久化、数据过期策略&#xff0c;数据淘汰策略 2、分布式锁 setnx、redisson 3、消息队列 4、延迟队列 何种数据类型&#xff08;list、zset&#xff09; 缓存三兄弟 缓存穿透 缓存穿透…

Python 如何实现职责链设计模式?什么是职责链设计模式?Python 职责链设计模式示例代码

什么是职责链&#xff08;Chain of Responsibility&#xff09;设计模式&#xff1f; 职责链&#xff08;Chain of Responsibility&#xff09;设计模式是一种行为型设计模式&#xff0c;旨在构建一个对象链&#xff0c;每个对象都有机会处理请求&#xff0c;并且可以将请求传…

动手学深度学习——循环神经网络的从零开始实现(原理解释+代码详解)

文章目录 循环神经网络的从零开始实现1. 独热编码2. 初始化模型参数3. 循环神经网络模型4. 预测5. 梯度裁剪6. 训练 循环神经网络的从零开始实现 从头开始基于循环神经网络实现字符级语言模型。 # 读取数据集 %matplotlib inline import math import torchfrom torch import …

五、hdfs常见权限问题

1、常见问题 2、案例 &#xff08;1&#xff09;问题 &#xff08;2&#xff09;hdfs的超级管理员 &#xff08;3&#xff09;原因 没有使用Hadoop用户对hdfs文件系统进行操作。 在Hadoop文件系统中&#xff0c;Hadoop用户相当于Linux系统中的root用户&#xff0c;是最高级别用…

react实现步进器

创建一个步进器组件&#xff0c;包含当前步骤&#xff08;currentStep&#xff09;的状态以及前进和后退的操作&#xff1a; import React, { useState } from react;function Stepper() {const [currentStep, setCurrentStep] useState(1);const handleNext () > {setCu…

⑩② 【MySQL索引】详解MySQL`索引`:结构、分类、性能分析、设计及使用规则。

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ MySQL索引 ⑩② 【MySQL索引】1. 索引2. 索引的…

搞科研、写论文,如何正确使用GPT?AIGC技术解析、提示词工程高级技巧、AI绘图、ChatGPT/GPT4应用

目录 专题一 OpenAI开发者大会最新技术发展及最新功能应用 专题二 AIGC技术解析 专题三 提示词工程高级技巧 专题四 ChatGPT/GPT4的实用案例 专题五 让ChatGPT/GPT4成为你的论文助手 专题六 让ChatGPT/GPT4成为你的编程助手 专题七 让ChatGPT/GPT4进行数据处理 专题八 …

Wordpress页面生成器:Elementor 插件制作网站页面教程(图文完整)

本文来教大家怎么使用Wordpress Elementor页面编辑器插件来自由创建我们的网页内容。很多同学在面对建站的时候,一开始都是热血沸腾信心满满的,等到实际上手的时候就会发现有很多问题都是无法解决的,希望本篇Elementor插件使用指南能够帮助到你。 Wordpress Elementor页面编…

使用VC++实现分段线性变换,直方图均衡化、锐化处理(使用拉普拉斯算子)

图像锐化1 获取源工程可访问huiningLi的gitee可在此工程的基础上进行学习。 实验要求 5.1实验目的、要求 实验目的&#xff1a; &#xff08;1&#xff09;掌握图像增强的原理与相关方法。 &#xff08;2&#xff09;能使用VC实现图像增强的一些相关功能。 实验要求&#xf…

【python】均值、中值和高斯滤波详解和示例

本文对均值、中值和高斯滤波进行详解&#xff0c;以帮助大家理解和使用。 这里写目录标题 均值滤波中值滤波高斯滤波核大小为&#xff08;9,9&#xff09;核大小为&#xff08;51,51&#xff09; 小结 下面是示例中使用的原图。 均值滤波 均值滤波是一种简单的平滑滤波器&…

PyTorch微调权威指南3:使用数据增强

如果你曾经参与过 PyTorch 模型的微调&#xff0c;可能会遇到 PyTorch 的内置变换函数&#xff0c;这使得数据增强变得轻而易举。 即使你之前没有使用过这些功能&#xff0c;也不必担心。 在本文中&#xff0c;我们将深入研究 PyTorch 变换换函数的世界。 我们将探索你可以使用…

CTFhub-RCE-过滤目录分隔符 /

根据源代码信息可知&#xff0c;过滤掉了/ <?php $res FALSE; if (isset($_GET[ip]) && $_GET[ip]) { $ip $_GET[ip]; $m []; if (!preg_match_all("/\//", $ip, $m)) { $cmd "ping -c 4 {$ip}"; exec($cmd,…

【开源】基于Vue.js的高校实验室管理系统的设计和实现

项目编号&#xff1a; S 015 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S015&#xff0c;文末获取源码。} 项目编号&#xff1a;S015&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 实验室类型模块2.2 实验室模块2.3 实…

数据结构与集合源码

我是南城余&#xff01;阿里云开发者平台专家博士证书获得者&#xff01; 欢迎关注我的博客&#xff01;一同成长&#xff01; 一名从事运维开发的worker&#xff0c;记录分享学习。 专注于AI&#xff0c;运维开发&#xff0c;windows Linux 系统领域的分享&#xff01; 本…

【数据结构与算法】线性表 - 顺序表

目录 1. 线性表2.顺序表3.顺序表的优缺点4.实现&#xff08;C语言&#xff09;4.1 头文件 seqList.h4.2 实现 seqList.c 1. 线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构&#xff0c;常见…

音视频转换软件Permute mac中文板特点介绍

Permute mac是一款Mac平台上的媒体格式转换软件&#xff0c;由Chaotic Software开发。它可以帮助用户快速地将各种音频、视频和图像文件转换成所需格式&#xff0c;并提供了一些常用工具以便于用户进行编辑和处理。 Permute mac软件特点 - 支持大量格式&#xff1a;支持几乎所…

汇编-指针

一个变量如果包含的是另一个变量的地址&#xff0c; 则该变量就称为指针(pointer) 。指针是操作数组和数据结构的极好工具&#xff0c;因为它包含的地址在运行时是可以修改的。 .data arrayB byte 10h, 20h, 30h, 40h ptrB dword arrayB ptrB1 dword OFFSET arrayBarray…

Linux:权限篇 (彻底理清权限逻辑!)

shell命令以及运行原理&#xff1a; Linux严格意义上说的是一个操作系统&#xff0c;我们称之为“核心&#xff08;kernel&#xff09;“ &#xff0c;但我们一般用户&#xff0c;不能直接使用kernel。而是通过kernel的“外壳”程序&#xff0c;也就是所谓的shell&#xff0c;来…

YOLOV5部署Android Studio安卓平台NCNN

坑非常多&#xff0c;兄弟们&#xff0c;我已经踩了三天的坑了&#xff0c;我这里部署了官方的yolov5s和我自己训练的yolov5n的模型 下载Android Studio&#xff0c;配置安卓开发环境&#xff0c;这个过程比较漫长。 安装cmake&#xff0c;注意安装的是cmake3.10版本。 根据手机…

LeetCode——字符串(Java)

字符串 简介[简单] 344. 反转字符串[简单] 541. 反转字符串 II[中等] 151. 反转字符串中的单词 简介 记录一下自己刷题的历程以及代码。写题过程中参考了 代码随想录。会附上一些个人的思路&#xff0c;如果有错误&#xff0c;可以在评论区提醒一下。 [简单] 344. 反转字符串…