[回溯法] 迷宫问题

问题

思路

流程图

代码

#include "pch.h"
#include 
struct Point{
	int x;
	int y;
};

int main()
{
	int max_x = 0, max_y = 0;
	int maze_arr[100][100] = { 0 };
	scanf("%d %d", &max_x, &max_y);

	if (max_x * max_y <= 0) {
		printf("Wrong input!\n");
		return 0;
	}

	if (max_x * max_y == 1) {
		printf("No solution!\n");
		return 0;
	}

	for (int i = 0; i < max_x; i++) {
		for (int j = 0; j < max_y; j++) {
			scanf("%d", &maze_arr[i][j]);
		}
	}
	
	printf("\n");
	//第一个参数是控制行,第二个参数才是控制列
	

	int x = 0, y = 0;
	int k = 0;//步数索引
	int round = 0;

	Point path[100];//路径
	int flag[100][100];//是否走过
	int dir[100] = { 0 }; //搜索方向
	Point delta[4];//偏移量
	flag[0][0] = 1;
	while (true) {
		//0,0 第一列第0行
		//左边 0,-1 第0行第1列
		//右边 0,1 第0行第1列
		//上边 -1,0 第-1行第0列
		//下边 1,0 第1行第0列
		round = 0;//重置遍历次数
		//左方 0
		delta[0].x = x;
		delta[0].y = y - 1;
		//上方 1
		delta[1].x = x - 1;
		delta[1].y = y;
		//右方 2
		delta[2].x = x;
		delta[2].y = y + 1;
		//下方 3
		delta[3].x = x + 1;
		delta[3].y = y;
		for (int i = 0; i < 4; i++) {
			//不超出迷宫边界,即不小于0,不大于行/列
			if (delta[i].x >= 0 && delta[i].y >= 0 && delta[i].x < max_x && delta[i].y < max_y) {
				//不是墙,即所在格子值不为1
				
				if (maze_arr[delta[i].x][delta[i].y] != 1) {
					//没走过,即所在格子的flag值不为1
					if (flag[delta[i].x][delta[i].y] != 1) {
						
						//将偏移量delta加到当前坐标上
						x = delta[i].x;
						y = delta[i].y;
						path[k].x = x;
						path[k].y = y;
						//记录当前的搜索方向dir
						dir[k] = i;
						k++;
						//将当前位置的flag值标为1,表示已走
						flag[x][y] = 1;
						//是否最后一步
						if (x == max_x - 1 && y == max_y - 1) {
							//输出坐标
							printf("<0,0>\n");
							for (int j = 0; j < 100; j++) {
									if (path[j].x >= 0) {
										printf("<%d,%d>\n", path[j].x, path[j].y);
									}
							}
							return 0;
						}
						break;
					}
				}
			}
			round++;
		}
		
		if (round == 4) {
			//将当前坐标的搜索方向dir重置为0
			dir[k] = 0;
			path[k].x = 0;
			path[k].y = 0;
			//将当前坐标回退到上一步
			
			switch (dir[k-1]) {
			case 0:
				y++;
				break;
			case 1:
				x++;
				break;
			case 2:
				y--;
				break;
			case 3:
				x--;
				break;
			}
			if (k - 1 < 0) {
				printf("No solution!\n");
				break;
			}
			//令上一步的搜索方向加1(不然会重复上一次的方向)
			dir[k - 1]++;
			//回退到上一步,即让k减1
			k--;
		}

	}
	return 0;
}

运行截图

无解决方案
有解决方案

来源

华南理工大学广州学院 – 林煜东 linyd@gcu.edu.com

[小程序] 活力健身房

简介

一款基于手机加速度传感器的跑步记录小程序。
用步伐丈量世界,在活力健身房记录你的跑步轨迹,助你更快达成你的跑步目标。
运动海报,记录每一天的变化,分享好友相互勉励,在活力健身房健身不再是孤独的坚持。

小程序码

截图

仓库地址

PS

这次开发的这个小程序其实就是Lebu的升级版本,算法上升级到了2.0,计算算法更加准确且高效。加入了轨迹图,逐公里的配速曲线以及逐公里的海拔曲线。还支持运动信息海报生成。终于是把在Lebu上没实现的功能都开发完成了,开心owo

PPS

华南赛区三等奖

第一次参加只能当个混子,拿个三等奖了。希望明年能够有更好的成绩吧!

[小程序] 大头菜估价

简介

一个简易的大头菜估价小程序,除了可以基于你的历史价格数据,给出接下来一段时间的价格,还能给出一些出手的建议,实属卖菜利器。

小程序码

大头菜友会

截图

近况

上岛了这么久,其实我很少机会去卖菜,基本上都是在钓鱼ing,由于选在了南半球,所以快把图谱开完了,就一直没去买卖大头菜了。如果你想找我玩的话,欢迎通过邮箱联系我,交换SW码owo

GuFilm – Vol.1

拍摄设备: 武士X3半幅照相机

胶卷: 柯达金胶卷

人民公园 & 北京路

陈家祠 & 百合

荔湾花市

桔子🍊树 (粤语音同吉, 摆在家中寓意吉利)

桃花 & 杜鹃

荔湾湖公园 & 中山八路

永庆坊

粤剧博物馆 & 馆中的金鱼池

奶油草莓🍓

地铁🚇 & 麒麟阁(已经有30年的老饭店, 现在顺应潮流, 变成了茶餐厅😂)

太古仓 & 游艇码头 (码头提供游艇培训, 只要2w就能学习如何开游艇)

木棉花 (广州市花)

[笔记] 设计模式 面向对象设计原则

  • 课程目标
    • 面向对象设计原则
  • 原则概述
    • 可维护性
      • 指的是软件可以很方便的理解、改正、适应和拓展的难易程度
      • 就是方不方便修改了的意思
    • 可复用性
      • 指的是软件能被重复使用的难易程度
    • 指导性原则
    • 用于评价一个设计模式的使用效果的重要指标之一
    • 为支持可维护性复用诞生
  • 单一职责原则
    • 一个类制作一件事
    • 作用
      • 用于控制一个类的粒度
      • 保证一个类里面不用实现所有的功能,仅仅需要实现单一职责即可
    • 定义
      • 一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中
    • 就一个类而言,应该仅有一个引起变化的原因
  • 开闭原则
    • 不修改源代码,只添加代码
    • 定义
      • 软件实体只能增加功能,尽量不修改功能
      • 尽可能只是拓展代码来增加新功能/修改原有功能
    • 关键
      • 抽象化
    • 具有稳定的抽象层+灵活的具体层
    • 修改配置文件,增加类,这个些操作都符合开闭原则
  • 里氏代换原则
    • 父类对象可被子类对象代替,且程序将不会产生任何错误和异常(因为子类把父类的一些方法重载了)
    • 在程序中尽可能使用基类类型来对对象进行定义
  • 依赖倒转原则
    • 编程使用配置文件,仅仅是接受对象操作对象,在外部进行创建对象注入
  • 接口隔离原则(网络上的那种API接口)
    • 一个接口尽可能做少的事情
    • 把接口都拆开来
  • 合成复用原则
    • is-a继承复用  has-a组合/聚合复用
    • 就是类似于把mysql的obj反射出来,然后再操作
  • 迪米特原则
    • 减少对象之间的交互
    • 两个对象不应该发生任何直接的相互作用
    • 通过”第三者”转发这个调用
    • 引入一个合理的”第三者”来降低现有对象之间的耦合度

[笔记] 设计模式: 统一建模语言

第一章

  • 课程目标
    • 统一建模语言
  • UML
    • 统一建模语言
    • 概念
      • 通用的可视化建模语言
      • 通过一些标准的图形符号和文字对系统进行建模
    • 作用
      • 对于软件进行描述、可视化处理、构建软件系统的文档
    • 视图(View)
      • 用户视图
        • 以用户的观点来标识系统的目标,它是所有视图的核心
        • 描述系统的需求
      • 结构视图
        • 表示系统的静态行为
        • 描述系统的静态元素,如包、类与对象,以及它们之间的关系
      • 行为视图
        • 表示系统的动态行为
        • 描述系统的组成元素如对象在系统运行时的交互关系
      • 实现视图
        • 表示系统中逻辑元素的分布
        • 描述系统中的文件以及它们之间的关系
      • 环境视图
        • 表示系统中物理元素的分布
        • 描述系统中的硬件设备以及它们之间的关系
      • 视图关系图
  • 图(Diagram)
    • 用例图
    • 类图
  • 模型元素(Model)
    • 模型元素
      • 就是图上面的符号
      • 用于描述事物以及事物与事物之间的关系
    • 每一个模型元素都要一个阈值相对应的图形元素
    • 同一个模型元素可以在不同的UML图中使用
    • 定义
      • 封装了数据和行为
      • 是具有相同属性、操作、关系的对象集合的总称
      • 一个类可以有多个职责(功能),但设计的好的类通常只有单一职责(功能)
    • 类的属性
      • 类的数据职责
    • 类的操作(类实现的方法)
      • 类的行为职责
  • 类图
    • 用来描述不同的类以及它们之间的关系
  • UML类图
    • 类名
  • 类的属性
  • 类的操作(其实就是类实现的方法)
  • 类之间的关系
    • 关联关系
      • 表示一类对象与另一类对象之间的关系
      • 实线连接
      • 通常将一个类的对象作为另外一个类的成员变量
      • 单向关联
  • 双向关联(就是两个类互相作为对方的成员属性)
  • 自关联(就是自己的成员属性存储了一个自身的对象)
  • 多重性关联(就是有2个+的成员变量存储/被存储了)
    • 多重表示,通常在直线上使用一个数字/数字范围来表示
  • 图例
  • 聚合关系
    • 表示整体与部分的关系(容器与成员的关系)
    • 成员对象是整体对象的一部分,但是成员对象可以脱离整体对象独立存在
    • 使用带空心菱形的直线表示
    • 图例
  • 组合关系
    • 聚合关系相同的表示
    • 成员是整体的一部分,但是成员对象跟整体对象的生命周期一样,整体对象销毁了,成员对象也会被销毁
    • 使用带实心的菱形直线表示
    • 因为是在整体(Head)对象中new的对象,销毁了head,就会连带把成员对象都销毁掉
  • 依赖关系
    • 表示一个事物使用另外一个事物
    • 体现在某个类的方法使用另一个累的对象作为参数
    • 使用带箭头的虚线
    • 依赖的一方指向被依赖的一方
  • 三种实现方法
  • 泛化关系(继承关系)
    • 用于描述父类与子类的关系
    • 用带空心三角形的直线表示
    • 图例
  • 接口与实现关系
    • 接口之间也存在继承关系和依赖关系
    • 接口与雷志坚存在一种实现的方法
    • 使用带空心三角形的虚线表示
    • 图例
  • 拓展机制
    • 注释
      • 可以给类图(UML)增加注释

[微信小程序] 开发心得Vol.1

前言

最近开始学习ES6的语法,然后突然想到去年挖下来的小程序的坑还没有填完,就开始捣鼓起来了。接下来会分享一些我在这次开发过程中遇到的坑点和经验,由于小程序是微信发起来的,所以有很多问题都可以尝试在小程序的开发社区里面搜一下。

UI框架推荐

这次最蠢的一件事就是手莽课表,殊不知已经有前人开发出了插件。自己写CSS实在是痛苦。有一部分的UI也用了微信的WeUI,但其实还有更多选择:

  1. WeUI官方样式库
  2. iView
  3. ColorUI
  4. Vant

通过这几个组件库可以快速构建小程序,不用花过多的时间在UI上,很适用于我们这些后端开发者。

SSL配置

如果你的小程序需要向你的服务器发起数据请求的话,就要留意这一点。小程序文档中要求你的后端接口的网址必须满足以下两点:

  1. HTTPS
  2. 已经备案

无论你的主机在哪都要给你的域名备案,不然真机模拟的时候就永远都无法请求,会报图1.1的问题。

Provisional headers are shown

如果你的证书已经备案了,还是报这种错误的话,那就是你的接口缺少了证书。一般tx云或者阿里云的免费证书就够用了,直接申请就可以。

如果还是报错,那就是缺失了中间证书。具体体现就是你的浏览器可以直接访问,并且确实走的是HTTPS,但就是无法请求,你可以通过这个网址:https://www.myssl.cn/tools/check-server-cert.html检测是否缺失中间证书。一般是需要把root和domain name的证书打包在一起才行,就是用.pem和.key后缀的文件作为证书文件绑定到你的Http服务器上。

JS平台差异

这个点主要是出现在Date对象上面

//Android平台上这么写将会正常返回对象
let obj = new Date("2020-02-27");
obj.getDay();
//IOS平台只支持用"/"来分割时间
let obj = new Date("2020/02/27")
//如果你使用"-"来创建对象的话,ios将会返回null

这个是我目前认为小程序最为诟病的一个问题。就是多平台JS不通用。小程序的本质上还是VUE,样式基本上没啥问题,但js出现了bug就真的特别难复现,这个bug甚至在控制台中是无法找到的,实在是恶心,希望微信会尽快修好。

结尾

其实小程序是一个很好的分发平台,但是太多毛刺会减弱大家的开发积极性,希望以后会越做越好。也希望能帮到你,Peace

[小程序] GCU课表+

简介

一款专属于华广人的课表小程序。专注于课表信息查询,极简,优雅。不做论坛不做商城,节省流量保护隐私。

特性

  1. 支持教务系统导入课表
  2. 支持添加编辑课表
  3. 支持成绩查询
  4. 支持考试安排查询
  5. 支持深色模式
  6. 支持课表信息推送
  7. 公告信息
  8. 离线存储
  9. 弱网加载
  10. 自定义壁纸
  11. 无障碍访问
  12. 自带使用指南

小程序码

微信小程序码

截图

服务支持

现在后端已经完全迁移到了腾讯云的SCF上,每个月消耗的都是免费额度,如果未来使用人数不激增以及教务系统不升级,理论上是可以继续运行5年+的。另外目前打码已经接入Numpy等机器学习框架,自动识别,准确率高达98%,某种程度上,是不需要外部维护就能持续运行的。目前小程序的最长无维护记录是6个月,希望日后离校之后,可以实现4-5年无维护都能正常运行吧🤷‍♂️。

JavaScript OOP笔记[ES3]

简介

最近开始要学习ES6了,翻出JS看了看,发现OOP部分还没有掌握,所以就赶紧进行了补课。下面是这次学习的一些,个人认为重要的知识点。

对象

每次使用JavaScript的构造器时,都会创建一个对象。一个初始化的对象中将会含有一个属性集,称之为prototype(对象属性),还有一个constructor(构造器)。而属性集里面中则会默认存在一个属性_proto_(原型)。这个属性存储的是父类的prototype(可以理解为指向父类的一个指针)。

对象属性

访问对象属性

对象.prototype.属性名

创建对象属性

对象.prototype.属性名 = 值

继承

JavaScript中实现继承主要是通过修改对象的_proto_(原型)指向到父原型来实现的继承。一旦理解了就会很简单,但是这个设计真的不好,而且原型这个称谓真的太容易混淆了。

注意!

//错误的继承
student.prototype = person.prototype;

解释:因为如果是这么赋值的话,在后续的操作中,比如给student增加属性或者方法时,收student的本质还是person,这样子修改的话,本质上还是修改的person的对象属性。

//正确的继承
student.prototype = Object.create(person.prototype)
//此时就可以正确把student的_proto_正确的指向person.prototype了

(JavaScript在ES6中貌似已经引入了extend应该能改善当前这个反人类的设计了)

原型

原型就是对象上一个存储父类的属性,称之为_proto_。由于Object是顶层对象,所以它的原型就是NULL。

原型链

bosn的原型指向Student,Student的原型又会指向Person,Person的原型又会指向Object,则称这条联系为原型链。

InstanceOf

该方法用于判断方法右边的函数是否存在于左边对象的原型链中,返回一个Bool值。其原理还是通过遍历prototype来看看左边的原型链上面是否存在右边函数的prototype。

用途:判断对象是否存在该方法(函数)

尾言

说实话,平时对于JavaScript的应用还停留在普通的事件应用,函数闭包这种层面,第一次了解了关于JS的面对象过程,也是受益匪浅,希望可以帮助到后续的ES6的学习,如果你觉着这篇文章好的话,不妨点一个赞吧,如果我理解有错误,也欢迎在下方评论区中学习交流owo。