独轮车问题(C语言程序设计)

独轮车问题(C语言程序设计),第1张

目录

问题描述

问题分析

运行程序输入的测试数据:

运行结果

代码实现

问题描述


独轮车的轮子上有5种颜色, 独轮车每走一格颜色变化一次, 并且独轮车只能往前推。

 独轮车也可以在原地旋转,每走一格需要 一个单位的时间,每转90°需要一个单位的时间, 每转180°需要两个单位的时间。

现给定一个 20x 20的迷宫,一个起点,一个终点和到达终点的颜色,问独轮车最少需要多少时间到达?

问题分析

先定义独轮车所在的行、列、当前颜色(5种)、方向(4 个),另外为了方便在结点中加上到达该点的最小步数,再用广度搜索返回目标结点的最小步数。

       本题包含一个测例。

测试数据从第一行开始的20行每行内包含20个字符,表示迷宫的状态。

其中区表示障碍物,‘.’表示空格(路);接下来的第21行输入以空格分隔的4个整数分别表示起点的坐标S(x.y)和两个整数轮子的颜色和开始的方向,第二行有以空格分隔的3个整数,表示终点的坐标T(x,y)和到达终点时轮子的颜色。

运行程序输入的测试数据:

XXXXXXXXXXXXXXXXXXXX

.....XXXX......X.XXX

X.........X.XX.....X

X.XXX.XX..X.XX.XXX.X

X.........X.XX.....X

X.XXX.XX..X.XX.XXX.X

.X.....XX.X.....X..X

X....X..X...X.X....X

...XXXX.X.XXX...XXXX

...........X.......X

XXXXXX....XXXXXX..XX

...........X.......X

.X.....XX.X.....X..X

XXXXXX....XXXXXXXX.X

X....X..X...X.X....X

...XXXX.X.XXX...XXXX

...........X.......X

XXX.X.XXXXX.XXXX.X.X

....X.XX....XXX.....

XXXX.....XX.........

运行结果 代码实现
#include

struct cnode {
	int row;  //结点所在的行坐标
	int col;  //列坐标
	int color;   //颜色
	int direction; //方向
	int num;     //从起点到本结点的最小步数
};

struct cnode s;//start记录起始点信息
struct cnode t;//tail记录目标点信息
struct cnode open[200];//创建struct cnode类型的表
int head, tail, openlen = 200;//open表数据
int direct[4][2] = { {0,-1},{1,0},{0,1},{-1,0} };//向左,下,右,上四个方向转时,行列的增加值
int a[20][20];//记录迷宫路的状态
int n = 20;//n为迷宫边长
int b[20][20][5][4] ;//表示迷宫访问状态(0:未访问,1:已访问)


int search();//用广度搜索返回目标结点的最小步数
void readdate();//读入数据
void init();//初始化
struct cnode moveahead(struct cnode u);//返回u向前走一格得到的结点
int used(struct cnode v);//判断该结点是否是到达过的结点
void addtoopen(struct cnode v);//加入open表 *** 作
int islegal(struct cnode v);//判断该结点是否是合法的结点(未越界且是空格)
int isaim(struct cnode v);//判断该结点是否是目标结点
struct cnode takeoutofopen();//从open表中取出一个结点,并将该节点在open表中删除
struct cnode turntoleft (struct cnode u);
struct cnode turntoright (struct cnode u);

int main()
{
	readdate();
	init();
	printf("独轮车最少需要%d个单位时间到达目标结点。

\n", search()); return 0; } int search()//用广度搜索返回目标结点的最小步数 { struct cnode u,v; while (head != tail) { u = takeoutofopen(); v = moveahead(u);//u向前走, 得到新结点v if (islegal(v)) { if (isaim(v)) { return (v.num); } if (!used(v)) { addtoopen(v); } } v = turntoleft(u);//u向左转,得到新结点v if (!used(v)) { addtoopen(v); } v = turntoright(u);//u向右转,得到新结点v if (!used(v)) { addtoopen(v); } } } void readdate()//读入数据 { char str[400]; printf("请输入20*20的迷宫状态:(.表示空格,X表示有障碍物)\n"); for (int i = 0; i < n; i++) { gets(str); for (int j = 0; j < n; j++) { if (str[j] == '.') { a[i][j] = 0; } else { a[i][j] = 1; } } } printf("请输入起始结点信息(行、列、颜色、方向)\n"); scanf("%d%d%d%d", &s.row, &s.col, &s.color, &s.direction); printf("请输入目标结点信息(行、列、颜色)\n"); scanf("%d%d%d", &t.row, &t.col, &t.color); } void addtoopen(struct cnode v) { open[tail++] = v;//把v放入open[tail],tail++ tail = tail % openlen;//超出表的部分,更新原来的数据 b[v.row][v.col][v.color][v.direction] = 1;//更新b数组 在v位置上的状态 为已到过 } void init() { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { for (int k = 0; k < 5; k++) { for (int l = 0; l < 4; l++) { b[i][j][k][l] = 0; } } } } head = 0; tail = 0; addtoopen(s);//把起始点放入open表 } struct cnode takeoutofopen()//从open表中取出一个结点,并将该节点在open表中删除 { struct cnode u; u = open[head++]; head = head % openlen; return u; } struct cnode moveahead(struct cnode u)//返回u向前走一格得到的结点 { struct cnode v; v.row = u.row + direct[u.direction][0];//上下 v.col = u.col + direct[u.direction][1];//左右 v.color = (u.color + 1) % 5;//变一次颜色 v.direction = u.direction;//方向不变 v.num = u.num + 1;//步数+1,走了一步 return v; } int isaim(struct cnode v)//判断该结点是否是目标结点 { if (v.row == t.row && v.col == t.col && v.color == t.color) return 1; else return 0; } int islegal(struct cnode v)//判断该结点是否是合法的结点(未越界且是空格) { if (v.row < 0 || v.row >= n || v.col < 0 || v.col >= n)//越界了 return 0; if (a[v.row][v.col] == 0)//结点未越界且是空格 return 1; return 0; } int used(struct cnode v)//判断该结点是否是到达过的结点 { if (b[v.row][v.col][v.color][v.direction] == 0) return 0; else return 1; } struct cnode turntoleft(struct cnode u) { struct cnode v = u; v.direction = (v.direction + 1) % 4; v.num = v.num + 1; return v; } struct cnode turntoright(struct cnode u) { struct cnode v = u; v.direction = (v.direction + 3) % 4; v.num = v.num + 1; return v; }

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/674909.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-19
下一篇 2022-04-19

发表评论

登录后才能评论

评论列表(0条)

保存