diff --git a/404.html b/404.html index 31ccc85f..0399cf4e 100644 --- a/404.html +++ b/404.html @@ -1,6 +1,6 @@ 404 Page not found | Zs's Blog -
404
\ No newline at end of file diff --git a/about/index.html b/about/index.html index 50b4426a..831c6603 100644 --- a/about/index.html +++ b/about/index.html @@ -8,8 +8,8 @@ sspai: @zzsqwq">

About

Github:@zzsqwq

E-mail: trizsqwq@gmail.com

Telegram: @zzsqwq

sspai: @zzsqwq

\ No newline at end of file diff --git a/archives/index.html b/archives/index.html index 5ddd7f19..2c8d87e5 100644 --- a/archives/index.html +++ b/archives/index.html @@ -1,7 +1,7 @@ Archive | Zs's Blog -

2024  1

January  1

2023 年度总结

January 3, 2024 · 1 min · zzsqwq

2023  6

December  2

App 使用体会记录 - macOS 篇

December 3, 2023 · 2 min · zzsqwq

My App Defaults - 2023 Fall

December 3, 2023 · 1 min · zzsqwq

November  1

记一次 GitHub 账号突然被 suspended 的经历

November 12, 2023 · 4 min · zzsqwq

May  1

为什么应该抵制拼多多?

May 1, 2023 · 1 min · zzsqwq

February  1

基于地平线 HAT 训练与部署 FCOS 全流程

February 25, 2023 · 9 min · zzsqwq

January  1

2022 年度总结

January 1, 2023 · 1 min · zzsqwq

2022  9

December  1

使用 OrangePi 4 LTS 做旁路由

December 31, 2022 · 1 min · zzsqwq

November  1

C++ 类使用注意事项

November 9, 2022 · 2 min · zzsqwq

October  2

关于美的一些思考

October 30, 2022 · 1 min · zzsqwq

如何善用搜索引擎?

October 30, 2022 · 1 min · zzsqwq

August  1

为什么要使用条件变量?

August 24, 2022 · 2 min · zzsqwq

May  1

一个基于 Hugo 的个人主页主题

May 3, 2022 · 1 min · zzsqwq

April  1

Docker-Gitlab 与主机共用 ssh 的 22 端口

April 24, 2022 · 3 min · zzsqwq

February  1

关于春节期间的一些碎碎念

February 10, 2022 · 1 min · zzsqwq

January  1

一个 Javascript 中异步的小技巧

January 19, 2022 · 1 min · zzsqwq

2021  10

December  2

记一次博客迁移记录

December 13, 2021 · 2 min · zzsqwq

Markdown 编辑器推荐

December 1, 2021 · 1 min · zzsqwq

November  1

2021版小新Pro14 Ubuntu 20.04 配置指南

November 2, 2021 · 2 min · zzsqwq

July  2

关于Git的一些理解

July 23, 2021 · 3 min · zzsqwq

利用树莓派为HP LaserJet 1020配置无线打印功能

July 18, 2021 · 2 min · zzsqwq

June  1

deepin-wine-qq-9.1.8版本无法正常启动的解决方案

June 16, 2021 · 4 min · zzsqwq

May  1

利用神经网络进行波士顿房价预测

May 16, 2021 · 1 min · zzsqwq

April  1

2021RoboMaster中国赛比赛记录

April 30, 2021 · 1 min · zzsqwq

March  1

关于Anaconda中pip路径指向问题

March 6, 2021 · 1 min · zzsqwq

January  1

如何使用CenterNet做3D目标检测测试

January 27, 2021 · 2 min · zzsqwq

2020  34

December  2

Git的简易教程

December 5, 2020 · 2 min · zzsqwq

Ubuntu18.04优化教程

December 4, 2020 · 1 min · zzsqwq

November  1

“程序星编程之路”第二次作业题解

November 12, 2020 · 3 min · zzsqwq

October  1

Visual Studio 2019 中 OpenCV 配置教程

October 31, 2020 · 1 min · zzsqwq

September  1

数据库的一些基础知识总结

September 11, 2020 · 1 min · zzsqwq

August  3

自买服务器建站教程

August 26, 2020 · 1 min · zzsqwq

排位三和四记录

August 19, 2020 · 3 min · zzsqwq

排位一和二记录

August 17, 2020 · 3 min · zzsqwq

April  3

高精度计算pi

April 20, 2020 · 3 min · zzsqwq

Python初步学习

April 18, 2020 · 6 min · zzsqwq

C++大数类的实现

April 6, 2020 · 5 min · zzsqwq

March  5

Linux和Vim入门

March 30, 2020 · 2 min · zzsqwq

专题四:MATLAB绘图

March 23, 2020 · 2 min · zzsqwq

专题三:MATLAB程序流程控制

March 18, 2020 · 2 min · zzsqwq

专题二:MATLAB矩阵处理

March 15, 2020 · 2 min · zzsqwq

专题一:MATLAB基础知识

March 14, 2020 · 3 min · zzsqwq

February  18

树形dp例题

February 20, 2020 · 2 min · zzsqwq

Codeforces#620 (Div.2)

February 19, 2020 · 2 min · zzsqwq

dp练习

February 18, 2020 · 2 min · zzsqwq

关于STL的一些总结

February 16, 2020 · 3 min · zzsqwq

杂题训练

February 15, 2020 · 2 min · zzsqwq

Codeforces#619 (Div.2)

February 14, 2020 · 2 min · zzsqwq

日常水题

February 13, 2020 · 2 min · zzsqwq

dp习题练习

February 12, 2020 · 2 min · zzsqwq

单调队列和单调栈总结

February 11, 2020 · 3 min · zzsqwq

Codeforces #618 (Div.2)

February 10, 2020 · 2 min · zzsqwq

背包进阶

February 9, 2020 · 2 min · zzsqwq

一些关于背包的题

February 8, 2020 · 2 min · zzsqwq

基础线性dp例题 #2

February 7, 2020 · 2 min · zzsqwq

基础线性dp例题

February 6, 2020 · 1 min · zzsqwq

Codeforces#617(Div.3)

February 5, 2020 · 2 min · zzsqwq

洛谷的一些搜索题

February 4, 2020 · 2 min · zzsqwq

LaTeX的一些总结

February 4, 2020 · 2 min · zzsqwq

CodeforcesER #81

February 2, 2020 · 2 min · zzsqwq
\ No newline at end of file diff --git a/categories/acm/index.html b/categories/acm/index.html index fdde47cb..3a7c2441 100644 --- a/categories/acm/index.html +++ b/categories/acm/index.html @@ -1,6 +1,6 @@ ACM | Zs's Blog -

排位三和四记录

Day 3 A. 黑妹的游戏Ⅰ 题意 给出三个不同的初始数字$a,b,c$,黑妹每次选择两个不同的数字,计算出差的绝对值后如果黑板上没有就写在黑板上。问黑妹最多能添加多少个数字。 +

排位三和四记录

Day 3 A. 黑妹的游戏Ⅰ 题意 给出三个不同的初始数字$a,b,c$,黑妹每次选择两个不同的数字,计算出差的绝对值后如果黑板上没有就写在黑板上。问黑妹最多能添加多少个数字。 ...

August 19, 2020 · 3 min · zzsqwq

排位一和二记录

Day 1 A. 兔子的区间密码 题意 给定一个区间$[L,R]$ ,求从这个区间任意取两个整数(可以相同),两者异或后能得到的最大值是多少? ...

August 17, 2020 · 3 min · zzsqwq

Codeforces#620 (Div.2)

A. Two Rabbits 题意 两个兔子分别位于 $(x,0)$ 和 $(y,0)$ ,两个人对头蹦,前者往前蹦 $a$ ,后者往前蹦 $b$ ,问两人是否能恰好相遇。 ...

February 19, 2020 · 2 min · zzsqwq

杂题训练

A. 配对 题意 给定含有 $n$ 个正整数的集合 $A$ 和 $B$ ,你需要建立他们之间的一一映射。将配对的两个数相加可以得到 $n$ 个和,问第 $k$ 大的和最大为多少。 @@ -8,5 +8,5 @@ ...

February 14, 2020 · 2 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/categories/acm/page/2/index.html b/categories/acm/page/2/index.html index 03ab04fb..3dfb9ca0 100644 --- a/categories/acm/page/2/index.html +++ b/categories/acm/page/2/index.html @@ -1,6 +1,6 @@ ACM | Zs's Blog -

日常水题

前言 今天又是颓废的一天,被大佬拉去跟他一起做牛客网的题,QAQ…那我会点啥嘛,就只能替大佬写两道水题了··· +

日常水题

前言 今天又是颓废的一天,被大佬拉去跟他一起做牛客网的题,QAQ…那我会点啥嘛,就只能替大佬写两道水题了··· ...

February 13, 2020 · 2 min · zzsqwq

Codeforces #618 (Div.2)

A. Non-zero 题意 给出一段含有 $n$ 个数的序列 $a$ ,可以对其中任何数加一,问最少操作多少次让每一个数和序列和都不为0。 ...

February 10, 2020 · 2 min · zzsqwq

Codeforces#617(Div.3)

A. Array with Odd Sum 题意 给出包含 n 个正整数的序列 a ,你可以把任何一个元素 $a_i$ ,赋值给另一个元素 $a_j$ ($i\neq j$) ,问通过任意此操作能否将序列 a 的和变为奇数。可以输出 YES ,不可以输入 NO. 思路 首先当起始和为奇数的时候,就直接可输出 YES 了,如果是偶数的话,我们可以发现,如果序列元素中同时包含奇数和偶数,那么就是可以的,否则不可以。 @@ -8,5 +8,5 @@ ...

February 2, 2020 · 2 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/categories/app/index.html b/categories/app/index.html index 8fadbce1..fe4df87b 100644 --- a/categories/app/index.html +++ b/categories/app/index.html @@ -1,9 +1,10 @@ App | Zs's Blog -

App 使用体会记录 - macOS 篇

平时很喜欢倒腾各种 Apple 平台的各种软件,所以体验了很多 iOS/iPadOS/macOS 上的软件,所以计划汇总一下自己的一些简短的使用体验和评价等,希望能在大家后续选择软件的时候起到一些参考和帮助。 +

App 使用体会记录 - macOS 篇

平时很喜欢倒腾各种 Apple 平台的各种软件,所以体验了很多 iOS/iPadOS/macOS 上的软件,所以计划汇总一下自己的一些简短的使用体验和评价等,希望能在大家后续选择软件的时候起到一些参考和帮助。 由于软件可能较多,不能一次性写完。同时,因为我也在不断体验新的软件,有新的感受,因此这篇博客应该是持续更新的,欢迎常来看看。 -速览表 App 名称 简短描述 功能限制 订阅形式 价格 购入时间 购入渠道 同类型产品 AIDente 电池电量管理 有免费使用功能,但有共功能需要收费 买断 Free Battery, BatFi AdGuard 广告拦截软件 AltTab 增强 macOS App 切换 Command-Tab Plus, Contexts,HyperSwitch, Bartender 5 Menubar 管理 Bob 大概是最好用翻译软件 EasyDict BuhoCleaner 垃圾清理器/软件卸载器 CleanMyMac, Sensei Clash X / Clash X Pro 代理 Surge, Stash CleanBuddy 键盘锁定清理 Cleaner CleanShot X 大概最好用的截图软件 Cleaner 键盘屏幕锁定清理 CleanBuddy Dash 文档利器 Dato Menubar 日历软件 Fantastical, Itsycal DevUtils 开发小工具合集 Downie 4 各类视频下载器 VDown HapiGo 启动器 Alfred, Raycast HazeOver 生产力工具,突出重点 Hazel 自动清理集合 JetBrains 全家桶 包含 Clion/IDEA 等 VSCode, Eclipse Lunar 显示器管理 MonitorControl, DisplayBuddy, Better Display Maccy 开源免费的剪切板管理工具 Paste, PasteNow, PastePal Manico 快速启动器 Command-Tab Plus MimeStram Gmail 客户端 MonitorControl 开源显示器管理,很够用 Lunar, DisplayBuddy, Better Display NetNewsWire 全平台 RSS 阅读器 Obsidian 笔记软件 Omnivore 稍后读软件 Pocket, MarkMark, Only Switch 一键完成各种任务 One Switch OpenImageOptim 图片压缩 TinyPNG OrbStack 容器管理,平替 Docker Desktop Docker Desktop, Podman, lima, colima Permute 3 图片/视频格式转换工具,类似于格式工厂 HandBrake, Omni Converter, Video Converter X2 Pixea 图片查看器 Viso, Picsee Pixelmator Pro 图片编辑器,80% 平替 PhotoShop Adobe PhotoShop, Darkroom, Photomator, Capture One, Adobe LightRoom Classic PopClip 划词增强 Proxyman 大概是舒服的抓包工具,略贵 Charles Rectangle 分屏软件 Magnet, Swish Swish 触控板手势增强 Stats Menubar 状态监控 iStats Menu, Sensei Subscriptions 订阅管理 Pandora on iOS Surge 代理工具 Clash X, Stash TinyPNG 图片压缩 OpenImageOptim Typora Markdown 文本编辑器 Obsidian Upscayl AI 图片超分 AI Photo Enhancer by Pictura, Pixelmator Pro Viso 6 图片查看器 Pixea, Xee Zotero 文献管理,就是界面一般 coconutBattery iPhone/iPad/Mac 电池信息查看 iRightMenu 右键增强 超级右键, iMouse, iTerm2 终端模拟器 Alacritty, Warp, Wezterm, Terminal 详细信息 AIDente 介绍:可以限制充电上限,据称电池电量维持在 70-80% 是比较健康的,不适宜过高。...

December 3, 2023 · 2 min · zzsqwq
© 2024 Zs's Blog +速览表 App 名称 简短描述 功能限制 订阅形式 价格 购入时间 购入渠道 同类型产品 AIDente 电池电量管理 有免费使用功能,但有共功能需要收费 买断 Free Battery, BatFi AdGuard 广告拦截软件 AltTab 增强 macOS App 切换 Command-Tab Plus, Contexts,HyperSwitch, Bartender 5 Menubar 管理 Bob 大概是最好用翻译软件 EasyDict BuhoCleaner 垃圾清理器/软件卸载器 CleanMyMac, Sensei Clash X / Clash X Pro 代理 Surge, Stash CleanBuddy 键盘锁定清理 Cleaner CleanShot X 大概最好用的截图软件 Cleaner 键盘屏幕锁定清理 CleanBuddy Dash 文档利器 Dato Menubar 日历软件 Fantastical, Itsycal DevUtils 开发小工具合集 Downie 4 各类视频下载器 VDown HapiGo 启动器 Alfred, Raycast HazeOver 生产力工具,突出重点 Hazel 自动清理集合 JetBrains 全家桶 包含 Clion/IDEA 等 VSCode, Eclipse Lunar 显示器管理 MonitorControl, DisplayBuddy, Better Display Maccy 开源免费的剪切板管理工具 Paste, PasteNow, PastePal Manico 快速启动器 Command-Tab Plus MimeStram Gmail 客户端 MonitorControl 开源显示器管理,很够用 Lunar, DisplayBuddy, Better Display NetNewsWire 全平台 RSS 阅读器 Obsidian 笔记软件 Omnivore 稍后读软件 Pocket, MarkMark, Only Switch 一键完成各种任务 One Switch OpenImageOptim 图片压缩 TinyPNG OrbStack 容器管理,平替 Docker Desktop Docker Desktop, Podman, lima, colima Permute 3 图片/视频格式转换工具,类似于格式工厂 HandBrake, Omni Converter, Video Converter X2 Pixea 图片查看器 Viso, Picsee Pixelmator Pro 图片编辑器,80% 平替 PhotoShop Adobe PhotoShop, Darkroom, Photomator, Capture One, Adobe LightRoom Classic PopClip 划词增强 Proxyman 大概是舒服的抓包工具,略贵 Charles Rectangle 分屏软件 Magnet, Swish Swish 触控板手势增强 Stats Menubar 状态监控 iStats Menu, Sensei Subscriptions 订阅管理 Pandora on iOS Surge 代理工具 Clash X, Stash TinyPNG 图片压缩 OpenImageOptim Typora Markdown 文本编辑器 Obsidian Upscayl AI 图片超分 AI Photo Enhancer by Pictura, Pixelmator Pro Viso 6 图片查看器 Pixea, Xee Zotero 文献管理,就是界面一般 coconutBattery iPhone/iPad/Mac 电池信息查看 iRightMenu 右键增强 超级右键, iMouse, iTerm2 终端模拟器 Alacritty, Warp, Wezterm, Terminal 详细信息 AIDente 介绍:可以限制充电上限,据称电池电量维持在 70-80% 是比较健康的,不适宜过高。 +...

December 3, 2023 · 2 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/categories/app/index.xml b/categories/app/index.xml index f737e9d8..72998b5e 100644 --- a/categories/app/index.xml +++ b/categories/app/index.xml @@ -17,490 +17,490 @@ <p>由于软件可能较多,不能一次性写完。同时,因为我也在不断体验新的软件,有新的感受,因此这篇博客应该是持续更新的,欢迎常来看看。</p> <h2 id="速览表">速览表</h2> <table> -<thead> -<tr> -<th>App 名称</th> -<th>简短描述</th> -<th>功能限制</th> -<th>订阅形式</th> -<th>价格</th> -<th>购入时间</th> -<th>购入渠道</th> -<th>同类型产品</th> -</tr> -</thead> -<tbody> -<tr> -<td>AIDente</td> -<td>电池电量管理</td> -<td>有免费使用功能,但有共功能需要收费</td> -<td>买断</td> -<td>Free</td> -<td></td> -<td></td> -<td>Battery, BatFi</td> -</tr> -<tr> -<td>AdGuard</td> -<td>广告拦截软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>AltTab</td> -<td>增强 macOS App 切换</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Command-Tab Plus, Contexts,HyperSwitch,</td> -</tr> -<tr> -<td>Bartender 5</td> -<td>Menubar 管理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Bob</td> -<td>大概是最好用翻译软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>EasyDict</td> -</tr> -<tr> -<td>BuhoCleaner</td> -<td>垃圾清理器/软件卸载器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>CleanMyMac, Sensei</td> -</tr> -<tr> -<td>Clash X / Clash X Pro</td> -<td>代理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Surge, Stash</td> -</tr> -<tr> -<td>CleanBuddy</td> -<td>键盘锁定清理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Cleaner</td> -</tr> -<tr> -<td>CleanShot X</td> -<td>大概最好用的截图软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Cleaner</td> -<td>键盘屏幕锁定清理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>CleanBuddy</td> -</tr> -<tr> -<td>Dash</td> -<td>文档利器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Dato</td> -<td>Menubar 日历软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Fantastical, Itsycal</td> -</tr> -<tr> -<td>DevUtils</td> -<td>开发小工具合集</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Downie 4</td> -<td>各类视频下载器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>VDown</td> -</tr> -<tr> -<td>HapiGo</td> -<td>启动器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Alfred, Raycast</td> -</tr> -<tr> -<td>HazeOver</td> -<td>生产力工具,突出重点</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Hazel</td> -<td>自动清理集合</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>JetBrains 全家桶</td> -<td>包含 Clion/IDEA 等</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>VSCode, Eclipse</td> -</tr> -<tr> -<td>Lunar</td> -<td>显示器管理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>MonitorControl, DisplayBuddy, Better Display</td> -</tr> -<tr> -<td>Maccy</td> -<td>开源免费的剪切板管理工具</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Paste, PasteNow, PastePal</td> -</tr> -<tr> -<td>Manico</td> -<td>快速启动器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Command-Tab Plus</td> -</tr> -<tr> -<td>MimeStram</td> -<td>Gmail 客户端</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>MonitorControl</td> -<td>开源显示器管理,很够用</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Lunar, DisplayBuddy, Better Display</td> -</tr> -<tr> -<td>NetNewsWire</td> -<td>全平台 RSS 阅读器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Obsidian</td> -<td>笔记软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Omnivore</td> -<td>稍后读软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Pocket, MarkMark,</td> -</tr> -<tr> -<td>Only Switch</td> -<td>一键完成各种任务</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>One Switch</td> -</tr> -<tr> -<td>OpenImageOptim</td> -<td>图片压缩</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>TinyPNG</td> -</tr> -<tr> -<td>OrbStack</td> -<td>容器管理,平替 Docker Desktop</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Docker Desktop, Podman, lima, colima</td> -</tr> -<tr> -<td>Permute 3</td> -<td>图片/视频格式转换工具,类似于格式工厂</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>HandBrake, Omni Converter, Video Converter X2</td> -</tr> -<tr> -<td>Pixea</td> -<td>图片查看器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Viso, Picsee</td> -</tr> -<tr> -<td>Pixelmator Pro</td> -<td>图片编辑器,80% 平替 PhotoShop</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Adobe PhotoShop, Darkroom, Photomator, Capture One, Adobe LightRoom Classic</td> -</tr> -<tr> -<td>PopClip</td> -<td>划词增强</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Proxyman</td> -<td>大概是舒服的抓包工具,略贵</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Charles</td> -</tr> -<tr> -<td>Rectangle</td> -<td>分屏软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Magnet, Swish</td> -</tr> -<tr> -<td>Swish</td> -<td>触控板手势增强</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Stats</td> -<td>Menubar 状态监控</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>iStats Menu, Sensei</td> -</tr> -<tr> -<td>Subscriptions</td> -<td>订阅管理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Pandora on iOS</td> -</tr> -<tr> -<td>Surge</td> -<td>代理工具</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Clash X, Stash</td> -</tr> -<tr> -<td>TinyPNG</td> -<td>图片压缩</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>OpenImageOptim</td> -</tr> -<tr> -<td>Typora</td> -<td>Markdown 文本编辑器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Obsidian</td> -</tr> -<tr> -<td>Upscayl</td> -<td>AI 图片超分</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>AI Photo Enhancer by Pictura, Pixelmator Pro</td> -</tr> -<tr> -<td>Viso 6</td> -<td>图片查看器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Pixea, Xee</td> -</tr> -<tr> -<td>Zotero</td> -<td>文献管理,就是界面一般</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>coconutBattery</td> -<td>iPhone/iPad/Mac 电池信息查看</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>iRightMenu</td> -<td>右键增强</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>超级右键, iMouse,</td> -</tr> -<tr> -<td>iTerm2</td> -<td>终端模拟器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Alacritty, Warp, Wezterm, Terminal</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">App 名称</th> + <th style="text-align: left">简短描述</th> + <th style="text-align: left">功能限制</th> + <th style="text-align: left">订阅形式</th> + <th style="text-align: left">价格</th> + <th style="text-align: left">购入时间</th> + <th style="text-align: left">购入渠道</th> + <th style="text-align: left">同类型产品</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">AIDente</td> + <td style="text-align: left">电池电量管理</td> + <td style="text-align: left">有免费使用功能,但有共功能需要收费</td> + <td style="text-align: left">买断</td> + <td style="text-align: left">Free</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Battery, BatFi</td> + </tr> + <tr> + <td style="text-align: left">AdGuard</td> + <td style="text-align: left">广告拦截软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">AltTab</td> + <td style="text-align: left">增强 macOS App 切换</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Command-Tab Plus, Contexts,HyperSwitch,</td> + </tr> + <tr> + <td style="text-align: left">Bartender 5</td> + <td style="text-align: left">Menubar 管理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Bob</td> + <td style="text-align: left">大概是最好用翻译软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">EasyDict</td> + </tr> + <tr> + <td style="text-align: left">BuhoCleaner</td> + <td style="text-align: left">垃圾清理器/软件卸载器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">CleanMyMac, Sensei</td> + </tr> + <tr> + <td style="text-align: left">Clash X / Clash X Pro</td> + <td style="text-align: left">代理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Surge, Stash</td> + </tr> + <tr> + <td style="text-align: left">CleanBuddy</td> + <td style="text-align: left">键盘锁定清理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Cleaner</td> + </tr> + <tr> + <td style="text-align: left">CleanShot X</td> + <td style="text-align: left">大概最好用的截图软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Cleaner</td> + <td style="text-align: left">键盘屏幕锁定清理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">CleanBuddy</td> + </tr> + <tr> + <td style="text-align: left">Dash</td> + <td style="text-align: left">文档利器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Dato</td> + <td style="text-align: left">Menubar 日历软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Fantastical, Itsycal</td> + </tr> + <tr> + <td style="text-align: left">DevUtils</td> + <td style="text-align: left">开发小工具合集</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Downie 4</td> + <td style="text-align: left">各类视频下载器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">VDown</td> + </tr> + <tr> + <td style="text-align: left">HapiGo</td> + <td style="text-align: left">启动器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Alfred, Raycast</td> + </tr> + <tr> + <td style="text-align: left">HazeOver</td> + <td style="text-align: left">生产力工具,突出重点</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Hazel</td> + <td style="text-align: left">自动清理集合</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">JetBrains 全家桶</td> + <td style="text-align: left">包含 Clion/IDEA 等</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">VSCode, Eclipse</td> + </tr> + <tr> + <td style="text-align: left">Lunar</td> + <td style="text-align: left">显示器管理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">MonitorControl, DisplayBuddy, Better Display</td> + </tr> + <tr> + <td style="text-align: left">Maccy</td> + <td style="text-align: left">开源免费的剪切板管理工具</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Paste, PasteNow, PastePal</td> + </tr> + <tr> + <td style="text-align: left">Manico</td> + <td style="text-align: left">快速启动器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Command-Tab Plus</td> + </tr> + <tr> + <td style="text-align: left">MimeStram</td> + <td style="text-align: left">Gmail 客户端</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">MonitorControl</td> + <td style="text-align: left">开源显示器管理,很够用</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Lunar, DisplayBuddy, Better Display</td> + </tr> + <tr> + <td style="text-align: left">NetNewsWire</td> + <td style="text-align: left">全平台 RSS 阅读器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Obsidian</td> + <td style="text-align: left">笔记软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Omnivore</td> + <td style="text-align: left">稍后读软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Pocket, MarkMark,</td> + </tr> + <tr> + <td style="text-align: left">Only Switch</td> + <td style="text-align: left">一键完成各种任务</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">One Switch</td> + </tr> + <tr> + <td style="text-align: left">OpenImageOptim</td> + <td style="text-align: left">图片压缩</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">TinyPNG</td> + </tr> + <tr> + <td style="text-align: left">OrbStack</td> + <td style="text-align: left">容器管理,平替 Docker Desktop</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Docker Desktop, Podman, lima, colima</td> + </tr> + <tr> + <td style="text-align: left">Permute 3</td> + <td style="text-align: left">图片/视频格式转换工具,类似于格式工厂</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">HandBrake, Omni Converter, Video Converter X2</td> + </tr> + <tr> + <td style="text-align: left">Pixea</td> + <td style="text-align: left">图片查看器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Viso, Picsee</td> + </tr> + <tr> + <td style="text-align: left">Pixelmator Pro</td> + <td style="text-align: left">图片编辑器,80% 平替 PhotoShop</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Adobe PhotoShop, Darkroom, Photomator, Capture One, Adobe LightRoom Classic</td> + </tr> + <tr> + <td style="text-align: left">PopClip</td> + <td style="text-align: left">划词增强</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Proxyman</td> + <td style="text-align: left">大概是舒服的抓包工具,略贵</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Charles</td> + </tr> + <tr> + <td style="text-align: left">Rectangle</td> + <td style="text-align: left">分屏软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Magnet, Swish</td> + </tr> + <tr> + <td style="text-align: left">Swish</td> + <td style="text-align: left">触控板手势增强</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Stats</td> + <td style="text-align: left">Menubar 状态监控</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">iStats Menu, Sensei</td> + </tr> + <tr> + <td style="text-align: left">Subscriptions</td> + <td style="text-align: left">订阅管理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Pandora on iOS</td> + </tr> + <tr> + <td style="text-align: left">Surge</td> + <td style="text-align: left">代理工具</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Clash X, Stash</td> + </tr> + <tr> + <td style="text-align: left">TinyPNG</td> + <td style="text-align: left">图片压缩</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">OpenImageOptim</td> + </tr> + <tr> + <td style="text-align: left">Typora</td> + <td style="text-align: left">Markdown 文本编辑器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Obsidian</td> + </tr> + <tr> + <td style="text-align: left">Upscayl</td> + <td style="text-align: left">AI 图片超分</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">AI Photo Enhancer by Pictura, Pixelmator Pro</td> + </tr> + <tr> + <td style="text-align: left">Viso 6</td> + <td style="text-align: left">图片查看器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Pixea, Xee</td> + </tr> + <tr> + <td style="text-align: left">Zotero</td> + <td style="text-align: left">文献管理,就是界面一般</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">coconutBattery</td> + <td style="text-align: left">iPhone/iPad/Mac 电池信息查看</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">iRightMenu</td> + <td style="text-align: left">右键增强</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">超级右键, iMouse,</td> + </tr> + <tr> + <td style="text-align: left">iTerm2</td> + <td style="text-align: left">终端模拟器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Alacritty, Warp, Wezterm, Terminal</td> + </tr> + </tbody> </table> <h2 id="详细信息">详细信息</h2> <h3 id="aidente">AIDente</h3> diff --git a/categories/c++/index.html b/categories/c++/index.html index 2cd698ae..04d66c48 100644 --- a/categories/c++/index.html +++ b/categories/c++/index.html @@ -1,14 +1,17 @@ C++ | Zs's Blog -

C++ 类使用注意事项

前言 本文包含一些在使用 C++ 类时的注意事项,可避免一些常见问题,并能让你在写代码时更加自信。 +

C++ 类使用注意事项

前言 本文包含一些在使用 C++ 类时的注意事项,可避免一些常见问题,并能让你在写代码时更加自信。 因为目前我使用的是 C++ 17,所以仅保证以下内容在 C++ 17 中正确。 -构造函数 对于单个参数的构造函数,推荐添加 explicit 关键字,防止隐式转换错误调用构造函数。 class DemoClass { explicit DemoClass(int test) { this->test_ = test; } } 显式声明有参构造函数后,编译器不会自动生成无参构造函数,若需要,请添加 DemoClass() = default; class DemoClass { explicit DemoClass(int test) { this->test_ = test; } DemoClass() = default; } 若子类中没有显式调用父类的构造函数,子类会默认调用父类的无参构造函数,如果父类没有无参构造函数,会报错。 析构函数 基类析构函数应该声明为 virtual,这样可以防止子类无法正确的析构。 由于基类析构函数为 virtual,派生类的析构函数应该显式的 override。 class DemoClass { virtual ~DemoClass() = default; } class ChildClass: public DemoClass { ~ChildClass() override { xxx; } } 成员变量默认值 对于类或局部作用域中未明确指定默认值的成员变量,其值遵循以下规则:...

November 9, 2022 · 2 min · zzsqwq

为什么要使用条件变量?

为什么要使用条件变量? 前言 最近看了很多与线程有关的 C++ 新特性,条件变量是见的比较多的一个特性。 +构造函数 对于单个参数的构造函数,推荐添加 explicit 关键字,防止隐式转换错误调用构造函数。 class DemoClass { explicit DemoClass(int test) { this->test_ = test; } } 显式声明有参构造函数后,编译器不会自动生成无参构造函数,若需要,请添加 DemoClass() = default; class DemoClass { explicit DemoClass(int test) { this->test_ = test; } DemoClass() = default; } 若子类中没有显式调用父类的构造函数,子类会默认调用父类的无参构造函数,如果父类没有无参构造函数,会报错。 析构函数 基类析构函数应该声明为 virtual,这样可以防止子类无法正确的析构。 由于基类析构函数为 virtual,派生类的析构函数应该显式的 override。 class DemoClass { virtual ~DemoClass() = default; } class ChildClass: public DemoClass { ~ChildClass() override { xxx; } } 成员变量默认值 对于类或局部作用域中未明确指定默认值的成员变量,其值遵循以下规则: +对于原生类型(primitive types),即 int、float、int*、string* 等,默认值为随机的脏数据。 对于对象(objects),例如自定义类、或 std::string 等,会调用默认(无参)构造函数,若没有默认(无参)构造函数,则报错。 对于引用(reference)类型,例如 std::string&,必须赋初始值或在构造函数中初始化,若为初始化,则报错。 float age; // 脏数据、随机值(无意义),此时访问会出现未定义行为 int *ptr; // 脏数据、随机值(无意义),此时访问会出现未定义行为 string name; // 调用默认构造函数,对于 std::string 来说为空字符串 "" DemoClass demo; // 若 DemoClass 存在无参构造函数,则调用,否则编译错误 string *pname; // 脏数据、随机值(无意义),此时访问会出现未定义行为 string &rname; // 编译错误,必须显式初始化 const string &crname; // 同上,编译错误 成员变量初始化方式 初始化成员变量一般而言有四种方式,一般而言第二种和第四种方式为等价的,不过在下面我们会看到一种例外: +...

November 9, 2022 · 2 min · zzsqwq

为什么要使用条件变量?

为什么要使用条件变量? 前言 最近看了很多与线程有关的 C++ 新特性,条件变量是见的比较多的一个特性。 看的时候我发现,想要理解一个新的特性,关键的要看它的引入到底解决了哪些问题,没有什么特性我们要实现相同的功能要怎么做? 以我的理解来看,条件变量是一个线程间互相同步与通知的手段,他通过主动唤醒的方式减小了各个线程的开销,取代了简单但是消耗较大的一直被动循环检验与等待。 没有条件变量我们如何实现相同的需求? 这里采用现代C++教程1 中关于条件变量的一个例子作为基础: -不使用条件变量版本 #include <queue> #include <chrono> #include <mutex> #include <thread> #include <iostream> #include <condition_variable> int main() { std::queue<int> produced_nums; std::mutex mtx; // 生产者 auto producer = [&]() { for (int i = 0; ; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(900)); std::unique_lock<std::mutex> lock(mtx); std::cout << "producing " << i << std::endl; produced_nums.push(i); } }; // 消费者 auto consumer = [&]() { while (true) { { std::unique_lock<std::mutex> lock(mtx); if(produced_nums....

August 24, 2022 · 2 min · zzsqwq

C++大数类的实现

C++大数类设计思路 洛谷大数类的评测结果(开了氧气优化) 这个第四个点真的优化不过去了QAQ,24W的数据,丧心病狂 +不使用条件变量版本 #include <queue> #include <chrono> #include <mutex> #include <thread> #include <iostream> #include <condition_variable> int main() { std::queue<int> produced_nums; std::mutex mtx; // 生产者 auto producer = [&]() { for (int i = 0; ; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(900)); std::unique_lock<std::mutex> lock(mtx); std::cout << "producing " << i << std::endl; produced_nums.push(i); } }; // 消费者 auto consumer = [&]() { while (true) { { std::unique_lock<std::mutex> lock(mtx); if(produced_nums.empty()) continue; } std::unique_lock<std::mutex> lock(mtx); // 短暂取消锁,使得生产者有机会在消费者消费空前继续生产 lock.unlock(); // 消费者慢于生产者 std::this_thread::sleep_for(std::chrono::milliseconds(1000)); lock.lock(); while (!produced_nums.empty()) { std::cout << "consuming " << produced_nums.front() << std::endl; produced_nums.pop(); } } }; // 分别在不同的线程中运行 std::thread p(producer); std::thread cs[2]; for (int i = 0; i < 2; ++i) { cs[i] = std::thread(consumer); } p.join(); for (int i = 0; i < 2; ++i) { cs[i].join(); } return 0; } 使用条件变量版本 #include <queue> #include <chrono> #include <mutex> #include <thread> #include <iostream> #include <condition_variable> int main() { std::queue<int> produced_nums; std::mutex mtx; std::condition_variable cv; bool notified = false; // 通知信号 // 生产者 auto producer = [&]() { for (int i = 0; ; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(900)); std::unique_lock<std::mutex> lock(mtx); std::cout << "producing " << i << std::endl; produced_nums.push(i); notified = true; cv.notify_all(); // 此处也可以使用 notify_one } }; // 消费者 auto consumer = [&]() { while (true) { std::unique_lock<std::mutex> lock(mtx); while (!notified) { // 避免虚假唤醒 cv.wait(lock); } // 短暂取消锁,使得生产者有机会在消费者消费空前继续生产 lock.unlock(); // 消费者慢于生产者 std::this_thread::sleep_for(std::chrono::milliseconds(1000)); lock.lock(); while (!produced_nums.empty()) { std::cout << "consuming " << produced_nums.front() << std::endl; produced_nums.pop(); } notified = false; } }; // 分别在不同的线程中运行 std::thread p(producer); std::thread cs[2]; for (int i = 0; i < 2; ++i) { cs[i] = std::thread(consumer); } p.join(); for (int i = 0; i < 2; ++i) { cs[i].join(); } return 0; } 这两段代码在效果上是等效的,都是一个生产者两个消费者。 +...

August 24, 2022 · 2 min · zzsqwq

C++大数类的实现

C++大数类设计思路 洛谷大数类的评测结果(开了氧气优化) 这个第四个点真的优化不过去了QAQ,24W的数据,丧心病狂 ...

April 6, 2020 · 5 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/categories/deep-learning/index.html b/categories/deep-learning/index.html index 2f60eed1..b7be9a95 100644 --- a/categories/deep-learning/index.html +++ b/categories/deep-learning/index.html @@ -1,6 +1,6 @@ Deep Learning | Zs's Blog -

基于地平线 HAT 训练与部署 FCOS 全流程

前言 最近想要使用自己采集与标注的数据集来训练与部署一下地平线微调过的 FCOS 网络,在询问和查看文档后发现如果想基于官方微调的模型训练,需要使用提供 HAT(Horizon Algorithm Toolkit,海图) 来进行,具体的文档可以查看:Horizon Algorithm Toolkit 文档,这是在线的版本,版本可能会比较旧,想看最新版的可以查看离线的版本,位置在 OE(Open Explorer,天工开物) 包的 doc 目录下,如下图: +

基于地平线 HAT 训练与部署 FCOS 全流程

前言 最近想要使用自己采集与标注的数据集来训练与部署一下地平线微调过的 FCOS 网络,在询问和查看文档后发现如果想基于官方微调的模型训练,需要使用提供 HAT(Horizon Algorithm Toolkit,海图) 来进行,具体的文档可以查看:Horizon Algorithm Toolkit 文档,这是在线的版本,版本可能会比较旧,想看最新版的可以查看离线的版本,位置在 OE(Open Explorer,天工开物) 包的 doc 目录下,如下图: 想要方便的查看离线文档可以通过 Python 来实现,在 doc 目录下执行: python3 -m http.server 3000 这样就可以在本地的 0.0.0.0:3000 地址开启一个 http server,随后可以在本地浏览器使用 localhost:3000 或者其他电脑浏览器使用 {ip}:3000 来访问文档。 但是查看 文档 过后会发现,文档其实也没有那么的全面,讲的比较简单,尝试了一下中间坑还挺多的,社区里面关于这方面的帖子也不多12,因此想记录下我尝试的全流程,也可以作为对上面教程文档的补充。 @@ -15,8 +15,10 @@ Nvidia Docker: 2.11.0-1 GPU: RTX3090 NVIDIA Driver Version: 515.65.01 -CUDA Version: 11....

February 25, 2023 · 9 min · zzsqwq
© 2024 Zs's Blog +CUDA Version: 11.7 +OE Version: v2.4.2( gcc-9.3.0 For XJ3 ) +...

February 25, 2023 · 9 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/categories/dp/index.html b/categories/dp/index.html index a1301e96..c3a09f6f 100644 --- a/categories/dp/index.html +++ b/categories/dp/index.html @@ -1,6 +1,6 @@ Dp | Zs's Blog -

树形dp例题

前言 学OI的时候就做过树形dp的题,不过那时候全在划水。看了看题解还不太懂就直接照着题解写了,现在再回来看还是不会QAQ,所以就再看看然后自己写了一遍。 +

树形dp例题

前言 学OI的时候就做过树形dp的题,不过那时候全在划水。看了看题解还不太懂就直接照着题解写了,现在再回来看还是不会QAQ,所以就再看看然后自己写了一遍。 ...

February 20, 2020 · 2 min · zzsqwq

dp练习

A. 矩阵取数游戏 题意 给定一个 $n\times m$ 的矩阵,其中每个元素为非负整数。每次你可以从每行的行首或行末取一个元素,得到的分数为当前元素的值 $a_{ij}\times 2^k$ ,$k$ 为当前是第几次取该行上的元素。 问最大得分为多少。 ...

February 18, 2020 · 2 min · zzsqwq

dp习题练习

A. 方格取数 题意 有一个 $N*N$ 的整数方阵,每个点初始值为0,在一些点上放上数,一个人从左上角走到右下角,规定只能向下或向右走,当他经过的点上有数时会取走它,问走两遍最多能取的数的和最大为多少。 ...

February 12, 2020 · 2 min · zzsqwq

基础线性dp例题 #2

1. 石子归并 题意 $N$ 堆石子摆成一条线。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价。计算将 $N$ 堆石子合并成一堆的最小代价。 思路 很经典的区间dp例题,我们可以用 $dp[i][j]$ 来表示合并 $i\sim j$ 所需的最小代价,通过枚举中间的断点,来通过方程 $dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+cost[i][j])$ ,其中 $cost[i][j]$ 表示从 $i\sim j$ 的石子总数,通过前缀和很容易计算。在进行状态转移时需要前面状态已知,因为是枚举中间断点,所以断开区间的长度一定要小于原区间,因此在转移之前需要确保比他短的区间都已经达到了最小代价,因此我们可以通过枚举区间长度从 $2\sim N$ 来实现。 @@ -9,5 +9,5 @@ ...

February 6, 2020 · 1 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/categories/dp/index.xml b/categories/dp/index.xml index f57f27dc..b87e5d74 100644 --- a/categories/dp/index.xml +++ b/categories/dp/index.xml @@ -754,58 +754,58 @@ <li>碱基配对时相似度的定义如下</li> </ul> <table> -<thead> -<tr> -<th style="text-align:center"></th> -<th style="text-align:center">A</th> -<th style="text-align:center">C</th> -<th style="text-align:center">G</th> -<th style="text-align:center">T</th> -<th style="text-align:center">空</th> -</tr> -</thead> -<tbody> -<tr> -<td style="text-align:center">A</td> -<td style="text-align:center">5</td> -<td style="text-align:center">-1</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-1</td> -<td style="text-align:center">-3</td> -</tr> -<tr> -<td style="text-align:center">C</td> -<td style="text-align:center">-1</td> -<td style="text-align:center">5</td> -<td style="text-align:center">-3</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-4</td> -</tr> -<tr> -<td style="text-align:center">G</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-3</td> -<td style="text-align:center">5</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-2</td> -</tr> -<tr> -<td style="text-align:center">T</td> -<td style="text-align:center">-1</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">5</td> -<td style="text-align:center">-1</td> -</tr> -<tr> -<td style="text-align:center">空</td> -<td style="text-align:center">-3</td> -<td style="text-align:center">-4</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-1</td> -<td style="text-align:center">非法</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: center"></th> + <th style="text-align: center">A</th> + <th style="text-align: center">C</th> + <th style="text-align: center">G</th> + <th style="text-align: center">T</th> + <th style="text-align: center">空</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: center">A</td> + <td style="text-align: center">5</td> + <td style="text-align: center">-1</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-1</td> + <td style="text-align: center">-3</td> + </tr> + <tr> + <td style="text-align: center">C</td> + <td style="text-align: center">-1</td> + <td style="text-align: center">5</td> + <td style="text-align: center">-3</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-4</td> + </tr> + <tr> + <td style="text-align: center">G</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-3</td> + <td style="text-align: center">5</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-2</td> + </tr> + <tr> + <td style="text-align: center">T</td> + <td style="text-align: center">-1</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">5</td> + <td style="text-align: center">-1</td> + </tr> + <tr> + <td style="text-align: center">空</td> + <td style="text-align: center">-3</td> + <td style="text-align: center">-4</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-1</td> + <td style="text-align: center">非法</td> + </tr> + </tbody> </table> <hr> <h4 id="思路-2">思路</h4> diff --git a/categories/git/index.html b/categories/git/index.html index dc389f2f..4af503dc 100644 --- a/categories/git/index.html +++ b/categories/git/index.html @@ -1,6 +1,6 @@ Git | Zs's Blog -

关于Git的一些理解

前言 前段时间在 Github 学完了关于 git 的小游戏 learnGitBranching ,受益匪浅。 +

关于Git的一些理解

前言 前段时间在 Github 学完了关于 git 的小游戏 learnGitBranching ,受益匪浅。 它通过可视化的方式将分支的关系,每条命令的作用等都明明白白的体现出来,可以很直观的感受到你每条命令对整个分支树,每一个 ref 的作用。 通过这种学习感觉自己对 Git 的理解更加深入一步,能够理解其中的原理,而不是浅尝辄止,照猫画虎。 学习中记了一些零零散散的思路,想要写一篇笔记记录出来,之前已经写过一个简单的 Git 教程,这篇教程将会更加深入,希望可以帮助大家更好的掌握 Git。 @@ -8,7 +8,8 @@ Git中的分区 首先,Git中存在三大分区,分别是工作区、暂存区、版本库。其中, 工作区即我们工作的目录,暂存区是我们执行 git add 后文件存在的区域。 我们可以通过 git status 对两种状态进行查看,例如: -~/test master* base ❯ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: test Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>....

July 23, 2021 · 3 min · zzsqwq

Git的简易教程

前言 最近在复习Git,因此顺手做个笔记分享出来,方便大家学习和查阅。相信无论是以后的课程作业还是工作,我们都会或多或少的接触/用到Git。 +~/test master* base ❯ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: test Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: test 上图中存在两部分, 分别为 Changes to be committed 这里是表示的版本库与暂存区的区别,还有Changes not staged for commit ,它表示的是工作区与暂存区的区别。 +...

July 23, 2021 · 3 min · zzsqwq

Git的简易教程

前言 最近在复习Git,因此顺手做个笔记分享出来,方便大家学习和查阅。相信无论是以后的课程作业还是工作,我们都会或多或少的接触/用到Git。 什么是Git? Git你可能没听说过,但是我相信你应该听说过Github,毕竟是全球最大的同性交友网站。他和Git有着密不可分的联系,我们后续再详细介绍。 Git的中文全称叫 分布式版本控制系统 ,版本控制系统是什么意思呢?我们举一个简单的例子,你在做一个大作业,很可能要写上千行的代码,但是你可能写完一个功能以后,对他不够满意,但是又害怕改了以后后悔了,又找不回来了,所以你可能就有很多版本,版本1,版本2,版本3等等等。Git就是解决这个问题的,让你文件能够保持最新,但是又能恢复到之前的版本。 那么既然有分布式版本控制系统,就有 集中式版本控制系统,前者的代表是 Git ,后者的代表有 SVN、CVS 等。 @@ -31,8 +32,9 @@ git init 顾名思义这就是一个初始化的过程,运行以后在当前目录生成一个 .git 文件夹,里面是我们版本控制的数据,一般不要修改。 把文件添加到Git的暂存区 这里出现了 暂存区 这个名词,Git内部的逻辑大概把我们工作的过程分为了三部分 -一个是 工作区 ,这个就是我们本地的文件夹。 一个是 暂存区 ,这是我们把文件暂时放到暂存区里,没有决定更新我们的版本。 一个是 最终分支,这就是我们最终的版本存放的位置。 贴一张廖雪峰老师教程中的一张图,我觉得还挺形象的。...

December 5, 2020 · 2 min · zzsqwq
© 2024 Zs's Blog +一个是 工作区 ,这个就是我们本地的文件夹。 一个是 暂存区 ,这是我们把文件暂时放到暂存区里,没有决定更新我们的版本。 一个是 最终分支,这就是我们最终的版本存放的位置。 贴一张廖雪峰老师教程中的一张图,我觉得还挺形象的。 +...

December 5, 2020 · 2 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/categories/index.html b/categories/index.html index 40621320..b4169258 100644 --- a/categories/index.html +++ b/categories/index.html @@ -1,6 +1,6 @@ Categories | Zs's Blog -
\ No newline at end of file diff --git a/categories/javascript/index.html b/categories/javascript/index.html index 32ed4206..0eb5688b 100644 --- a/categories/javascript/index.html +++ b/categories/javascript/index.html @@ -1,6 +1,6 @@ Javascript | Zs's Blog -

一个 Javascript 中异步的小技巧

前言 最近看了一些 js 有关的知识,其中令我这种初学者感到很头疼的一个问题就是异步问题。 +

一个 Javascript 中异步的小技巧

前言 最近看了一些 js 有关的知识,其中令我这种初学者感到很头疼的一个问题就是异步问题。 今天就我碰到的一个小问题详解一个关于异步的小技巧。 背景 我在程序中需要鉴权,来判断一个用户是普通用户还是管理员,针对不同的用户渲染不同的页面。 每个用户具有唯一的 ID,因此我只需要将管理员的 ID 放到数据库,然后加载程序的时候一一比对即可。 @@ -15,8 +15,9 @@ 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 所以此处加入 callback 以防止这种情况 这里判断了主程序内是否含有 userInfoReadyCallback 这个函数,如果有的话就执行。 -qq.getSetting({ success: res => { if (res.authSetting['scope.userInfo']) { // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框 qq.getUserInfo({ success: res => { // 可以将 res 发送给后台解码出 unionId this.globalData.userInfo = res.userInfo // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 if (this....

January 19, 2022 · 1 min · zzsqwq
© 2024 Zs's Blog +qq.getSetting({ success: res => { if (res.authSetting['scope.userInfo']) { // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框 qq.getUserInfo({ success: res => { // 可以将 res 发送给后台解码出 unionId this.globalData.userInfo = res.userInfo // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 if (this.userInfoReadyCallback) { this.userInfoReadyCallback(res) } } }) } } }) 页面初始化部分代码: +...

January 19, 2022 · 1 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/categories/latex/index.html b/categories/latex/index.html index 5a248d1f..ce6f9fdc 100644 --- a/categories/latex/index.html +++ b/categories/latex/index.html @@ -1,7 +1,7 @@ LaTeX | Zs's Blog -

LaTeX的一些总结

希腊字母表 ...

February 4, 2020 · 2 min · zzsqwq
© 2024 Zs's Blog +

LaTeX的一些总结

希腊字母表 ...

February 4, 2020 · 2 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号
\ No newline at end of file diff --git a/categories/matlab/index.html b/categories/matlab/index.html index 52308bed..94f641a6 100644 --- a/categories/matlab/index.html +++ b/categories/matlab/index.html @@ -1,6 +1,6 @@ MATLAB | Zs's Blog -

专题四:MATLAB绘图

4.1 二维曲线 plot函数 基本用法:plot(x,y) ,x和y分别代表横纵坐标,plot函数会将各个点连接起来,形成线,x和y一般为长度相等的向量。 最简单的调用格式:plot(x) 当x为实向量时,则以该元素下表为横坐标,元素的值为纵坐标绘制曲线。 当x为复向量时,则以实部和虚部分别为横纵坐标绘制曲线。 ...

March 23, 2020 · 2 min · zzsqwq

专题三:MATLAB程序流程控制

3.1 顺序结构程序 程序设计的基本步骤 ...

March 18, 2020 · 2 min · zzsqwq

专题二:MATLAB矩阵处理

2.1 特殊矩阵 通用的特殊矩阵 zeros函数: 产生全0矩阵,即零矩阵。 +

专题四:MATLAB绘图

4.1 二维曲线 plot函数 基本用法:plot(x,y) ,x和y分别代表横纵坐标,plot函数会将各个点连接起来,形成线,x和y一般为长度相等的向量。 最简单的调用格式:plot(x) 当x为实向量时,则以该元素下表为横坐标,元素的值为纵坐标绘制曲线。 当x为复向量时,则以实部和虚部分别为横纵坐标绘制曲线。 ...

March 23, 2020 · 2 min · zzsqwq

专题三:MATLAB程序流程控制

3.1 顺序结构程序 程序设计的基本步骤 ...

March 18, 2020 · 2 min · zzsqwq

专题二:MATLAB矩阵处理

2.1 特殊矩阵 通用的特殊矩阵 zeros函数: 产生全0矩阵,即零矩阵。 ones函数: 产生全1函数,即幺矩阵。 eye函数: 产生对角线为1的矩阵,当矩阵为方针时,为单位矩阵。 rand函数: 产生 (0,1) 区间均匀分布的随机矩阵。 @@ -9,5 +9,5 @@ 通过 $\mu+\sigma x$ 来得到均值为 $\mu$ ,方差为 $\sigma{^2}$ 的随机数据。(高中数学知识,证明可百度) ...

March 15, 2020 · 2 min · zzsqwq

专题一:MATLAB基础知识

1.1 MATLAB系统环境 MATLAB操作界面的组成 MATLAB主窗口 命令行窗口 命令行窗口含有 >> 命令提示符,表示MATLAB处于准备状态,可以接受并执行命令,按下回车键后MATLAB会执行输入命令,并在后面显示执行结果 如果指令过长可以分行输入,在一行末尾写 ... 并按下回车键,在下个命令行继续输入,...称为续行符。 当前文件夹窗口 在MATLAB编程过程中生成的文件自动存放在当前文件夹,我们可以通过cd命令(例如我们要进入E盘下的work文件夹,可以cd e:\work)或者选择文件工具栏中的文件夹来设置当前文件夹。 工作区窗口 可用于变量的显示和操作,可显示你当前创建的变量。并且可对其保存,修改,删除。 ...

March 14, 2020 · 3 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/categories/opencv/index.html b/categories/opencv/index.html index 9cc127b2..62820947 100644 --- a/categories/opencv/index.html +++ b/categories/opencv/index.html @@ -1,9 +1,9 @@ OpenCV | Zs's Blog -

Visual Studio 2019 中 OpenCV 配置教程

Windows 平台 Visual Studio 2019 中 OpenCV 配置教程 前言 我这里配置用的是4.5.0版本,但实际配置过程中需要的大部分时间只是路径,因此和版本基本无关。 +

Visual Studio 2019 中 OpenCV 配置教程

Windows 平台 Visual Studio 2019 中 OpenCV 配置教程 前言 我这里配置用的是4.5.0版本,但实际配置过程中需要的大部分时间只是路径,因此和版本基本无关。 只有一个地方是和版本有关系的,在配置链接器的 opencv_wordxyzd.lib 时,大家一定要注意!! ...

October 31, 2020 · 1 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/categories/openwrt/index.html b/categories/openwrt/index.html index 98a12a23..efe08152 100644 --- a/categories/openwrt/index.html +++ b/categories/openwrt/index.html @@ -1,14 +1,14 @@ OpenWrt | Zs's Blog -

使用 OrangePi 4 LTS 做旁路由

前言 最近同居的学长从香港带了个最新版的 Apple TV 回来,但是 Apple TV 在国内用不了,必须要代理才可以,所以考虑到了路由器代理的方案。但是现在家里在用的路由器是 Redmi AX3000,没法刷固件,也不想再买个 R2S 这种软路由了,因此就计划将公司之前用完的 香橙派(OrangePi) 4 LTS 利用一下。它的芯片是 RK3399,用来做路由器绰绰有余,不用可惜了。 +

使用 OrangePi 4 LTS 做旁路由

前言 最近同居的学长从香港带了个最新版的 Apple TV 回来,但是 Apple TV 在国内用不了,必须要代理才可以,所以考虑到了路由器代理的方案。但是现在家里在用的路由器是 Redmi AX3000,没法刷固件,也不想再买个 R2S 这种软路由了,因此就计划将公司之前用完的 香橙派(OrangePi) 4 LTS 利用一下。它的芯片是 RK3399,用来做路由器绰绰有余,不用可惜了。 为什么是旁路由? 不熟悉旁路由的同学可以看篇指南:从听说到上手,人人都能看懂的旁路由入门指南 找了一些常见的固件,貌似只有针对于 OrangePi R1 和 OrangePi R1 Plus 编译的软路由固件,并且讯龙官方也有放出针对这两个板子的 Openwrt 固件1,可以说是就是为软路由而生,价格也比较便宜,200 左右,性能和 R2S 差别不大。 试了一下在 4 LTS 上跑 R1 和 R1 Plus 的固件2,都无法正常点亮,可能可以自己编译一个对应架构的 OpenWrt,但是有点麻烦,还是没尝试。 考虑到 4 LTS 上可以使用 Docker,因此可以在上面用 Docker 跑一个 OpenWrt 然后做旁路由,到时候只需要把 Apple TV 或者路由器的网关和 DNS 改一下就可以,因此最终选择使用旁路由方案。 具体方案 这里直接参考了小苏的教程:https://mlapp.cn/376.html,写的很清晰,而且很好的考虑了没有基础的同学,赞一个! 里面写的很详细,但是需要注意的是,因为香橙派4 LTS是 ARMv8 架构的,但是直接拉教程里面的默认 latest 镜像是 ARMv7 的,因此需要指定一下镜像的版本,具体的镜像版本可以看 Docker Hub 中的介绍。 -docker pull registry....

December 31, 2022 · 1 min · zzsqwq
December 31, 2022 · 1 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/categories/python/index.html b/categories/python/index.html index 723cdbe4..2588b5df 100644 --- a/categories/python/index.html +++ b/categories/python/index.html @@ -1,6 +1,6 @@ Python | Zs's Blog -

利用神经网络进行波士顿房价预测

前言 前一阵学校有五一数模节校赛,和朋友一起参加做B题,波士顿房价预测,算是第一次自己动手实现一个简单的小网络吧,虽然很简单,但还是想记录一下。 +

利用神经网络进行波士顿房价预测

前言 前一阵学校有五一数模节校赛,和朋友一起参加做B题,波士顿房价预测,算是第一次自己动手实现一个简单的小网络吧,虽然很简单,但还是想记录一下。 题目介绍 波士顿住房数据由哈里森和鲁宾菲尔德于1978年Harrison and Rubinfeld1收集。它包括了波士顿大区每个调查行政区的506个观察值。1980年Belsley et al.2曾对此数据做过分析。 数据一共14列,每一列的含义分别如下: 英文简称 详细含义 CRIM 城镇的人均犯罪率 ZN 大于25,000平方英尺的地块的住宅用地比例。 INDUS 每个镇的非零售业务英亩的比例。 CHAS 查尔斯河虚拟变量(如果环河,则等于1;否则等于0) NOX 一氧化氮的浓度(百万分之几) RM 每个住宅的平均房间数 AGE 1940年之前建造的自有住房的比例 DIS 到五个波士顿就业中心的加权距离 RAD 径向公路通达性的指标 TAX 每一万美元的全值财产税率 PTRATIO 各镇的师生比率 B 计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例 LSTAT 底层人口的百分比(%) price 自有住房数的中位数,单位(千美元) 基于上述数据,请完成以下问题: @@ -10,7 +10,8 @@ 建立前馈神经网络模型,根据通用逼近定理,我们可以拟合此回归模型。 我们对上述模型来进行实现并确定评估标准来对他们进行比较,选择最优的模型作为预测模型。 算法流程 传统的回归算法 自变量的选择 首先,考虑到数据集中13列自变量其中某一些可能和最终的房价并无强相关性,如果全部使用进行预测可能会对模型引入噪声,因此我们首先计算了房价price与各个自变量之间的相关系数 $r$ ,其中 $r$ 计算公式如下: $$ r = \frac{\sum(x_i-\bar{x})(y_i-\bar{y})}{\sqrt{\sum(x_i-\bar{x})^2\sum(y_i-\bar{y})^2}} $$ 其中 $x_i,y_i$ 为数据的每个分量,$\bar{x},\bar{y}$ 为数据的均值 -该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下:...

May 16, 2021 · 1 min · zzsqwq

Python初步学习

Python学习笔记 Python的不同解释器 CPython +该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下: +...

May 16, 2021 · 1 min · zzsqwq

Python初步学习

Python学习笔记 Python的不同解释器 CPython 这是自带的用C语言开发的解释器,因此叫CPython。它也是使用最广的Python解释器。 IPython 这是基于CPython之上的一个交互式解释器,只是相比于CPython多了交互上的优化。 @@ -19,5 +20,5 @@ ...

April 18, 2020 · 6 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/categories/python/index.xml b/categories/python/index.xml index 5d9c2646..74b096c8 100644 --- a/categories/python/index.xml +++ b/categories/python/index.xml @@ -19,70 +19,70 @@ <p>波士顿住房数据由哈里森和鲁宾菲尔德于1978年Harrison and Rubinfeld<sup><a href="https://blog.zzsqwq.cn/usr/uploads/2021/05/406125417.png">1</a></sup>收集。它包括了波士顿大区每个调查行政区的506个观察值。1980年Belsley et al.<sup><a href="https://blog.zzsqwq.cn/usr/uploads/2021/05/3238192089.png">2</a></sup>曾对此数据做过分析。</p> <p>数据一共14列,每一列的含义分别如下:</p> <table> -<thead> -<tr> -<th>英文简称</th> -<th>详细含义</th> -</tr> -</thead> -<tbody> -<tr> -<td>CRIM</td> -<td>城镇的人均犯罪率</td> -</tr> -<tr> -<td>ZN</td> -<td>大于25,000平方英尺的地块的住宅用地比例。</td> -</tr> -<tr> -<td>INDUS</td> -<td>每个镇的非零售业务英亩的比例。</td> -</tr> -<tr> -<td>CHAS</td> -<td>查尔斯河虚拟变量(如果环河,则等于1;否则等于0)</td> -</tr> -<tr> -<td>NOX</td> -<td>一氧化氮的浓度(百万分之几)</td> -</tr> -<tr> -<td>RM</td> -<td>每个住宅的平均房间数</td> -</tr> -<tr> -<td>AGE</td> -<td>1940年之前建造的自有住房的比例</td> -</tr> -<tr> -<td>DIS</td> -<td>到五个波士顿就业中心的加权距离</td> -</tr> -<tr> -<td>RAD</td> -<td>径向公路通达性的指标</td> -</tr> -<tr> -<td>TAX</td> -<td>每一万美元的全值财产税率</td> -</tr> -<tr> -<td>PTRATIO</td> -<td>各镇的师生比率</td> -</tr> -<tr> -<td>B</td> -<td>计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例</td> -</tr> -<tr> -<td>LSTAT</td> -<td>底层人口的百分比(%)</td> -</tr> -<tr> -<td><strong>price</strong></td> -<td>自有住房数的中位数,单位(千美元)</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">英文简称</th> + <th style="text-align: left">详细含义</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">CRIM</td> + <td style="text-align: left">城镇的人均犯罪率</td> + </tr> + <tr> + <td style="text-align: left">ZN</td> + <td style="text-align: left">大于25,000平方英尺的地块的住宅用地比例。</td> + </tr> + <tr> + <td style="text-align: left">INDUS</td> + <td style="text-align: left">每个镇的非零售业务英亩的比例。</td> + </tr> + <tr> + <td style="text-align: left">CHAS</td> + <td style="text-align: left">查尔斯河虚拟变量(如果环河,则等于1;否则等于0)</td> + </tr> + <tr> + <td style="text-align: left">NOX</td> + <td style="text-align: left">一氧化氮的浓度(百万分之几)</td> + </tr> + <tr> + <td style="text-align: left">RM</td> + <td style="text-align: left">每个住宅的平均房间数</td> + </tr> + <tr> + <td style="text-align: left">AGE</td> + <td style="text-align: left">1940年之前建造的自有住房的比例</td> + </tr> + <tr> + <td style="text-align: left">DIS</td> + <td style="text-align: left">到五个波士顿就业中心的加权距离</td> + </tr> + <tr> + <td style="text-align: left">RAD</td> + <td style="text-align: left">径向公路通达性的指标</td> + </tr> + <tr> + <td style="text-align: left">TAX</td> + <td style="text-align: left">每一万美元的全值财产税率</td> + </tr> + <tr> + <td style="text-align: left">PTRATIO</td> + <td style="text-align: left">各镇的师生比率</td> + </tr> + <tr> + <td style="text-align: left">B</td> + <td style="text-align: left">计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例</td> + </tr> + <tr> + <td style="text-align: left">LSTAT</td> + <td style="text-align: left">底层人口的百分比(%)</td> + </tr> + <tr> + <td style="text-align: left"><strong>price</strong></td> + <td style="text-align: left">自有住房数的中位数,单位(千美元)</td> + </tr> + </tbody> </table> <p>基于上述数据,请完成以下问题:</p> <p><strong>建立波士顿房价预测模型并对预测结果进行评价。</strong></p> @@ -107,46 +107,46 @@ $$ 其中 $x_i,y_i$ 为数据的每个分量,$\bar{x},\bar{y}$ 为数据的均值</p> <p>该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下:</p> <table> -<thead> -<tr> -<th>CRIM</th> -<th>ZN</th> -<th>INDUS</th> -<th>CHAS</th> -<th>NOX</th> -<th>RM</th> -<th>LSTAT</th> -</tr> -</thead> -<tbody> -<tr> -<td>-0.385832</td> -<td>0.360445</td> -<td>-0.483725</td> -<td>0.175260</td> -<td>-0.427321</td> -<td>0.695360</td> -<td>-0.737663</td> -</tr> -<tr> -<td><strong>AGE</strong></td> -<td><strong>DIS</strong></td> -<td><strong>RAD</strong></td> -<td><strong>TAX</strong></td> -<td><strong>PTRATIO</strong></td> -<td><strong>B</strong></td> -<td></td> -</tr> -<tr> -<td>-0.376955</td> -<td>0.249929</td> -<td>-0.381626</td> -<td>-0.468536</td> -<td>-0.507787</td> -<td>0.333461</td> -<td></td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">CRIM</th> + <th style="text-align: left">ZN</th> + <th style="text-align: left">INDUS</th> + <th style="text-align: left">CHAS</th> + <th style="text-align: left">NOX</th> + <th style="text-align: left">RM</th> + <th style="text-align: left">LSTAT</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">-0.385832</td> + <td style="text-align: left">0.360445</td> + <td style="text-align: left">-0.483725</td> + <td style="text-align: left">0.175260</td> + <td style="text-align: left">-0.427321</td> + <td style="text-align: left">0.695360</td> + <td style="text-align: left">-0.737663</td> + </tr> + <tr> + <td style="text-align: left"><strong>AGE</strong></td> + <td style="text-align: left"><strong>DIS</strong></td> + <td style="text-align: left"><strong>RAD</strong></td> + <td style="text-align: left"><strong>TAX</strong></td> + <td style="text-align: left"><strong>PTRATIO</strong></td> + <td style="text-align: left"><strong>B</strong></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">-0.376955</td> + <td style="text-align: left">0.249929</td> + <td style="text-align: left">-0.381626</td> + <td style="text-align: left">-0.468536</td> + <td style="text-align: left">-0.507787</td> + <td style="text-align: left">0.333461</td> + <td style="text-align: left"></td> + </tr> + </tbody> </table> <p>观察结果可以发现,在给定的十三个变量中,<strong>LSTAT <strong>与 <strong>price</strong> 的相关程度最高$(|r|&gt;0.7)$,其次是 <strong>RM</strong> 与</strong>PTRATIO</strong> $(|r|&gt;0.5)$,再者是 <strong>TAX,INDUS,NOX</strong> $(|r|&gt;0.4)$,除上述之外的七个变量都与 <strong>price</strong> 无较强的相关性,因此我们考虑使用六个相关性较强变量和十三个变量分别来对房价进行预测,并对他们进行对比,来寻找最优的回归模型。</p> <h5 id="模型的构建">模型的构建</h5> diff --git a/categories/stl/index.html b/categories/stl/index.html index d4a4b5af..22d5b6ed 100644 --- a/categories/stl/index.html +++ b/categories/stl/index.html @@ -1,8 +1,8 @@ STL | Zs's Blog -

关于STL的一些总结

前言 STL之前只会用 stack 和 queue ,set 和 map 啥的也不太会用。学习一下。 +

关于STL的一些总结

前言 STL之前只会用 stack 和 queue ,set 和 map 啥的也不太会用。学习一下。 ...

February 16, 2020 · 3 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/categories/study/index.html b/categories/study/index.html index 68e7f88e..9e7b1e18 100644 --- a/categories/study/index.html +++ b/categories/study/index.html @@ -1,6 +1,6 @@ Study | Zs's Blog -

如何善用搜索引擎?

前言 我们使用搜索引擎可能是为了搜集信息、或者是解决一些问题。但如果不能正确的使用搜索引擎,使用关键字等,可能搜到的答案就与问题相关不大,或者与我们的问题相差甚远。 +

如何善用搜索引擎?

前言 我们使用搜索引擎可能是为了搜集信息、或者是解决一些问题。但如果不能正确的使用搜索引擎,使用关键字等,可能搜到的答案就与问题相关不大,或者与我们的问题相差甚远。 这篇文章意在分享我个人在学习、工作中使用搜索引擎的一些技巧与思考,可能后续会不断的更新,如有纰漏,还请大家指正。 应该使用什么搜索平台? 想要提高搜索的效率,选择一个好的搜索引擎或者内容平台颇为重要。 下面列举的是我平时会使用的一些平台,列出的顺序代表了我个人对于他们的推荐程度: @@ -10,8 +10,9 @@ 如何正确的知道问题所在? 我们遇到一个问题,要首先能够定位这个问题的关键。 例如编译中出错了,可能有很多 log,你必须能够精确定位到到底哪一条 log 才是这次编译出错的关键,进而才能解决这个问题。 以 CMake 为例,编译时报错 log 一般为红色,警告 log 一般为黄色,普通 log 一般为白色。得益于这种等级/颜色分明的 log ,我们可以快速的定位报错。我们日常编程中,为了便于 Debug,最好也遵循这个规范,例如在 C++ 中打印错误 log 时推荐使用 std::stderr 而不是 std::stdout 。 -见过很多身边的同学遇到了报错,就一股脑粘贴所有的报错 log,然后贴到搜索引擎中,发现相关的错误基本没有。这就是没有其中错误的关键,报错时的 log 可能 100 行只有 10 行是关键的,甚至只有一行是关键的,例如 100 行 log 中只有 未定义的引用(undefined reference to ‘xxx’) 这一句是最关键的。...

October 30, 2022 · 1 min · zzsqwq
© 2024 Zs's Blog +见过很多身边的同学遇到了报错,就一股脑粘贴所有的报错 log,然后贴到搜索引擎中,发现相关的错误基本没有。这就是没有其中错误的关键,报错时的 log 可能 100 行只有 10 行是关键的,甚至只有一行是关键的,例如 100 行 log 中只有 未定义的引用(undefined reference to ‘xxx’) 这一句是最关键的。 +...

October 30, 2022 · 1 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/categories/thread/index.html b/categories/thread/index.html index ef7478b3..4cf4e631 100644 --- a/categories/thread/index.html +++ b/categories/thread/index.html @@ -1,11 +1,12 @@ Thread | Zs's Blog -

为什么要使用条件变量?

为什么要使用条件变量? 前言 最近看了很多与线程有关的 C++ 新特性,条件变量是见的比较多的一个特性。 +

为什么要使用条件变量?

为什么要使用条件变量? 前言 最近看了很多与线程有关的 C++ 新特性,条件变量是见的比较多的一个特性。 看的时候我发现,想要理解一个新的特性,关键的要看它的引入到底解决了哪些问题,没有什么特性我们要实现相同的功能要怎么做? 以我的理解来看,条件变量是一个线程间互相同步与通知的手段,他通过主动唤醒的方式减小了各个线程的开销,取代了简单但是消耗较大的一直被动循环检验与等待。 没有条件变量我们如何实现相同的需求? 这里采用现代C++教程1 中关于条件变量的一个例子作为基础: -不使用条件变量版本 #include <queue> #include <chrono> #include <mutex> #include <thread> #include <iostream> #include <condition_variable> int main() { std::queue<int> produced_nums; std::mutex mtx; // 生产者 auto producer = [&]() { for (int i = 0; ; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(900)); std::unique_lock<std::mutex> lock(mtx); std::cout << "producing " << i << std::endl; produced_nums.push(i); } }; // 消费者 auto consumer = [&]() { while (true) { { std::unique_lock<std::mutex> lock(mtx); if(produced_nums....

August 24, 2022 · 2 min · zzsqwq
© 2024 Zs's Blog +不使用条件变量版本 #include <queue> #include <chrono> #include <mutex> #include <thread> #include <iostream> #include <condition_variable> int main() { std::queue<int> produced_nums; std::mutex mtx; // 生产者 auto producer = [&]() { for (int i = 0; ; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(900)); std::unique_lock<std::mutex> lock(mtx); std::cout << "producing " << i << std::endl; produced_nums.push(i); } }; // 消费者 auto consumer = [&]() { while (true) { { std::unique_lock<std::mutex> lock(mtx); if(produced_nums.empty()) continue; } std::unique_lock<std::mutex> lock(mtx); // 短暂取消锁,使得生产者有机会在消费者消费空前继续生产 lock.unlock(); // 消费者慢于生产者 std::this_thread::sleep_for(std::chrono::milliseconds(1000)); lock.lock(); while (!produced_nums.empty()) { std::cout << "consuming " << produced_nums.front() << std::endl; produced_nums.pop(); } } }; // 分别在不同的线程中运行 std::thread p(producer); std::thread cs[2]; for (int i = 0; i < 2; ++i) { cs[i] = std::thread(consumer); } p.join(); for (int i = 0; i < 2; ++i) { cs[i].join(); } return 0; } 使用条件变量版本 #include <queue> #include <chrono> #include <mutex> #include <thread> #include <iostream> #include <condition_variable> int main() { std::queue<int> produced_nums; std::mutex mtx; std::condition_variable cv; bool notified = false; // 通知信号 // 生产者 auto producer = [&]() { for (int i = 0; ; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(900)); std::unique_lock<std::mutex> lock(mtx); std::cout << "producing " << i << std::endl; produced_nums.push(i); notified = true; cv.notify_all(); // 此处也可以使用 notify_one } }; // 消费者 auto consumer = [&]() { while (true) { std::unique_lock<std::mutex> lock(mtx); while (!notified) { // 避免虚假唤醒 cv.wait(lock); } // 短暂取消锁,使得生产者有机会在消费者消费空前继续生产 lock.unlock(); // 消费者慢于生产者 std::this_thread::sleep_for(std::chrono::milliseconds(1000)); lock.lock(); while (!produced_nums.empty()) { std::cout << "consuming " << produced_nums.front() << std::endl; produced_nums.pop(); } notified = false; } }; // 分别在不同的线程中运行 std::thread p(producer); std::thread cs[2]; for (int i = 0; i < 2; ++i) { cs[i] = std::thread(consumer); } p.join(); for (int i = 0; i < 2; ++i) { cs[i].join(); } return 0; } 这两段代码在效果上是等效的,都是一个生产者两个消费者。 +...

August 24, 2022 · 2 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/categories/ubuntu/index.html b/categories/ubuntu/index.html index 40ead93f..4722b70e 100644 --- a/categories/ubuntu/index.html +++ b/categories/ubuntu/index.html @@ -1,6 +1,6 @@ Ubuntu | Zs's Blog -

2021版小新Pro14 Ubuntu 20.04 配置指南

2021版小新Pro14 Ubuntu 20.04 配置指南 补充 最近重装了 Ubuntu 20.04,又找了相关的一些帖子,发现 聯想Yoga 14s 2021款裝機小記 中提到了下文中提到的屏幕闪烁的问题,解决办法是:只需要在内核参数中加入 i915.enable_psr=0 即可。 +

2021版小新Pro14 Ubuntu 20.04 配置指南

2021版小新Pro14 Ubuntu 20.04 配置指南 补充 最近重装了 Ubuntu 20.04,又找了相关的一些帖子,发现 聯想Yoga 14s 2021款裝機小記 中提到了下文中提到的屏幕闪烁的问题,解决办法是:只需要在内核参数中加入 i915.enable_psr=0 即可。 具体操作步骤如下: $ sudo vim /etc/default/grub 在 GRUB_CMDLINE_LINUX_DEFAULT 这一行的最后添加 i915.enable_psr=0,保存后终端运行: $ sudo update-grub 然后重启即可。 @@ -8,7 +8,8 @@ CPU:酷睿 i5-11300H 显卡:集成显卡 Intel 锐炬Iris Xe 内存:16G 外存:512 SSD 屏幕:分辨率 2880x1800、400nits、100%sRGB 这里需要注意的是,不同时间出的小新Pro14配置是不太一样的,所以我这里列了一下配置。主要区别在于有一部分是2.2K分辨率+MX450显卡,而我这个是2.8K分辨率+锐炬Iris Xe显卡。 为了工作的需要,要装一个Ubuntu,先是装了之前用过的 Ubuntu 18.04,安装后发现触摸板无法使用,一系列探索后无果,在朋友的推荐下,还是决定安装 Ubuntu 20.04 试一下,踩了一些坑,在这里记录一下。 问题列表 如果你遇到了以下问题,那么这篇文章的方法可能会对你有益处: -Ubuntu 18.04 相关 Ubuntu 18.04 无法使用触摸板 Ubuntu 18.04 无法使用内置键盘 Ubuntu 18.04 无法调节亮 Ubuntu 18.04 查看GPU发现是llvm,而不是Iris Xe Ubuntu 20.04 相关 Ubuntu 20....

November 2, 2021 · 2 min · zzsqwq

关于Git的一些理解

前言 前段时间在 Github 学完了关于 git 的小游戏 learnGitBranching ,受益匪浅。 +Ubuntu 18.04 相关 Ubuntu 18.04 无法使用触摸板 Ubuntu 18.04 无法使用内置键盘 Ubuntu 18.04 无法调节亮 Ubuntu 18.04 查看GPU发现是llvm,而不是Iris Xe Ubuntu 20.04 相关 Ubuntu 20.04 进入后屏幕花屏、黑屏 Ubuntu 20.04 查看GPU发现是llvm,而不是Iris Xe 现在达成的效果 Ubuntu 20.04 能够正常使用,触摸板以及外界屏幕,亮度调节均无问题。 +...

November 2, 2021 · 2 min · zzsqwq

关于Git的一些理解

前言 前段时间在 Github 学完了关于 git 的小游戏 learnGitBranching ,受益匪浅。 它通过可视化的方式将分支的关系,每条命令的作用等都明明白白的体现出来,可以很直观的感受到你每条命令对整个分支树,每一个 ref 的作用。 通过这种学习感觉自己对 Git 的理解更加深入一步,能够理解其中的原理,而不是浅尝辄止,照猫画虎。 学习中记了一些零零散散的思路,想要写一篇笔记记录出来,之前已经写过一个简单的 Git 教程,这篇教程将会更加深入,希望可以帮助大家更好的掌握 Git。 @@ -16,7 +17,8 @@ Git中的分区 首先,Git中存在三大分区,分别是工作区、暂存区、版本库。其中, 工作区即我们工作的目录,暂存区是我们执行 git add 后文件存在的区域。 我们可以通过 git status 对两种状态进行查看,例如: -~/test master* base ❯ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: test Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>....

July 23, 2021 · 3 min · zzsqwq

利用树莓派为HP LaserJet 1020配置无线打印功能

前言 最近基地的打印机突然又好起来了。 +~/test master* base ❯ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: test Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: test 上图中存在两部分, 分别为 Changes to be committed 这里是表示的版本库与暂存区的区别,还有Changes not staged for commit ,它表示的是工作区与暂存区的区别。 +...

July 23, 2021 · 3 min · zzsqwq

利用树莓派为HP LaserJet 1020配置无线打印功能

前言 最近基地的打印机突然又好起来了。 因为基地的打印机型号比较老——HP LaserJet 1020,没有无线打印的功能。所以之前一位学长1 用树莓派配置了打印机的无线打印功能,但是后来发现有一些问题,有时候发送打印请求树莓派无法接收,而且不知道为何,学长之前用的是树莓派自己创建WiFi,连接对应WiFi才能打印,但是这个显然不是最优的解决办法。 考虑到之间已经配置好基地WiFi,我决定重新配置一下打印功能,使其连接基地WiFi即可实现局域网打印。 配置过程 查看树莓派内容 通过ssh连接树莓派,发现里面除了Github上的一个开源项目create_ap ,就没有什么其他的内容了,连接屏幕后发现没有任何图像信号,无从下手,因此考虑重新刷机。 @@ -30,13 +32,15 @@ $ sudo ifconfig 查看WiFi对应的IP,至此,树莓派可以摆脱屏幕,我们可以使用电脑进行使用 ssh 连接。 这里也可以使用网线进行连接,具体操作如下 用网线连接树莓派和自己的电脑。 -在树莓派的利用 nmtui 选择 Edit a connection ,Add一个Ethernet connect,对IPv4 CONFIGURATION进行设置,首先讲 Automatic 设置为 Manual,设置 Address 为 静态IP 如 192....

July 18, 2021 · 2 min · zzsqwq

deepin-wine-qq-9.1.8版本无法正常启动的解决方案

问题描述 ​Ubuntu下想要使用QQ有一个比较好的解决方案就是deepin-wine的版本,deepin-wine版本的QQ一共有两个版本,分别是 8.9.1 和 9.1.8 ,前者安装后发现无法登陆,登录时会提示版本过低的问题,于是我换到9.1.8版本后,启动初始化后就无任何信息了,于是开始排查问题 +在树莓派的利用 nmtui 选择 Edit a connection ,Add一个Ethernet connect,对IPv4 CONFIGURATION进行设置,首先讲 Automatic 设置为 Manual,设置 Address 为 静态IP 如 192.168.3.2 ,Gateway 设置为 192.168.3.1 。 +...

July 18, 2021 · 2 min · zzsqwq

deepin-wine-qq-9.1.8版本无法正常启动的解决方案

问题描述 ​Ubuntu下想要使用QQ有一个比较好的解决方案就是deepin-wine的版本,deepin-wine版本的QQ一共有两个版本,分别是 8.9.1 和 9.1.8 ,前者安装后发现无法登陆,登录时会提示版本过低的问题,于是我换到9.1.8版本后,启动初始化后就无任何信息了,于是开始排查问题 解决方案 ​首先我们根据上文的启示,因为每一个应用程序对应了一个 xxx.desktop 文件,因此在应用库中的QQ一定也有一个对应的 desktop 文件 ​我们进入到 /usr/share/applications ,运行 $ ls | grep -i qq ​可以发现其中有一个名为 deepin.com.qq.im.desktop 的文件,我们打开后发现内容如下: #!/usr/bin/env xdg-open [Desktop Entry] Encoding=UTF-8 Type=Application X-Created-By=Deepin WINE Team Categories=chat; Icon=deepin.com.qq.im Exec="/opt/deepinwine/apps/Deepin-QQ/run.sh" -u %u Name=QQ Name[zh_CN]=QQ Comment=Tencent QQ Client on Deepin Wine StartupWMClass=QQ.exe MimeType= ​可以看到Exec那一栏为 Exec="/opt/deepinwine/apps/Deepin-QQ/run.sh" -u %u ,发现他是运行目录下的一个 run.sh 脚本来启动的。 ​我们进入目录下直接运行该脚本,查看log信息: -base ❯ ./run.sh Run Deepin-QQ 9.1.8deepin0 c:/Program Files/Tencent/QQ/Bin/QQ.exe run Deepin-QQ progress pid Gtk-Message: 01:16:58.069: GtkDialog mapped without a transient parent....

June 16, 2021 · 4 min · zzsqwq

关于Anaconda中pip路径指向问题

前言 最近使用Anaconda的时候遇到了一个很奇怪的问题,如当我新建环境 condatest 后,使用 pip -V 查看pip的路径指向,会发现pip指向的是另一个环境 CenterNet 的路径。搜索了很久得到一个有一些用的解决方法 +base ❯ ./run.sh Run Deepin-QQ 9.1.8deepin0 c:/Program Files/Tencent/QQ/Bin/QQ.exe run Deepin-QQ progress pid Gtk-Message: 01:16:58.069: GtkDialog mapped without a transient parent. This is discouraged. total 0 lrwxrwxrwx 1 zs zs 10 6月 16 01:16 c: -> ../drive_c lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com1 -> /dev/ttyS0 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com10 -> /dev/ttyS9 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com11 -> /dev/ttyS10 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com12 -> /dev/ttyS11 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com13 -> /dev/ttyS12 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com14 -> /dev/ttyS13 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com15 -> /dev/ttyS14 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com16 -> /dev/ttyS15 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com17 -> /dev/ttyS16 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com18 -> /dev/ttyS17 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com19 -> /dev/ttyS18 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com2 -> /dev/ttyS1 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com20 -> /dev/ttyS19 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com21 -> /dev/ttyS20 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com22 -> /dev/ttyS21 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com23 -> /dev/ttyS22 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com24 -> /dev/ttyS23 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com25 -> /dev/ttyS24 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com26 -> /dev/ttyS25 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com27 -> /dev/ttyS26 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com28 -> /dev/ttyS27 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com29 -> /dev/ttyS28 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com3 -> /dev/ttyS2 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com30 -> /dev/ttyS29 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com31 -> /dev/ttyS30 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com32 -> /dev/ttyS31 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com4 -> /dev/ttyS3 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com5 -> /dev/ttyS4 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com6 -> /dev/ttyS5 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com7 -> /dev/ttyS6 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com8 -> /dev/ttyS7 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com9 -> /dev/ttyS8 lrwxrwxrwx 1 zs zs 8 6月 16 01:16 y: -> /home/zs lrwxrwxrwx 1 zs zs 1 6月 16 01:16 z: -> / CallApp Deepin-QQ c:/Program Files/Tencent/QQ/Bin/QQ.exe 2021年 06月 16日 星期三 01:16:58 CST:kill QQ.exe block 2021年 06月 16日 星期三 01:16:58 CST:No wine process found /home/zs/.deepinwine/Deepin-QQ/drive_c/Program Files/Tencent/QQ/Bin Starting process c:/Program Files/Tencent/QQ/Bin/QQ.exe ... /opt/deepinwine/apps/Deepin-QQ base ❯ wine: cannot find L"C:\\windows\\system32\\winemenubuilder.exe" wine version: 2.18 libGL error: No matching fbConfigs or visuals found libGL error: failed to load driver: swrast X Error of failed request: GLXBadContext Major opcode of failed request: 152 (GLX) Minor opcode of failed request: 6 (X_GLXIsDirect) Serial number of failed request: 207 Current serial number in output stream: 206 ​可以发现最下面的log信息有一些异常,首先第一行是因为我们是Ubuntu系统,可以暂且不关注 +...

June 16, 2021 · 4 min · zzsqwq

关于Anaconda中pip路径指向问题

前言 最近使用Anaconda的时候遇到了一个很奇怪的问题,如当我新建环境 condatest 后,使用 pip -V 查看pip的路径指向,会发现pip指向的是另一个环境 CenterNet 的路径。搜索了很久得到一个有一些用的解决方法 解决方案 设有问题的环境为 condatest ,python版本为 3.6 然后进入 ~/anaconda3/envs/condatest/lib/python3.6 编辑目录下的 site.py 文件,将其中的 USER_SITE 的值修改为 /home/zs/anaconda3/envs/condatest ,注意这里路径里面的 zs 是你的当前用户名, USER_BASE 的值修改为 /home/zs/anaconda3/envs/condatest/lib/python3.6/site.py,然后问题应该就解决了。 @@ -44,5 +48,5 @@ 参考链接 更改conda环境中的pip包安装的默认路径

March 6, 2021 · 1 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/categories/ubuntu/page/2/index.html b/categories/ubuntu/page/2/index.html index 38d03ac8..5ae54528 100644 --- a/categories/ubuntu/page/2/index.html +++ b/categories/ubuntu/page/2/index.html @@ -1,6 +1,6 @@ Ubuntu | Zs's Blog -

如何使用CenterNet做3D目标检测测试

CenterNet—Objects as Points介绍 ​CenterNet是一个anchor-free的目标检测网络,与YOLOv3相比,精度有所提升,此外他不仅能够用于2D目标检测,也能够用于人体姿态识别,3D目标检测等··· +

如何使用CenterNet做3D目标检测测试

CenterNet—Objects as Points介绍 ​CenterNet是一个anchor-free的目标检测网络,与YOLOv3相比,精度有所提升,此外他不仅能够用于2D目标检测,也能够用于人体姿态识别,3D目标检测等··· 安装CenterNet ​其实安装CenterNet的过程就是一个配置环境的问题,直接跟着官方给出的这里Install.md配置一下即可,十分推荐使用Conda来管理环境,这里给出我的环境给大家参考一下: Ubuntu = 18.04 LTS pytorch = 1.2.0 @@ -13,7 +13,11 @@ python demo.py ctdet --demo ${CenterNet_Root}/images/17790319373_bd19b24cfc_k.jpg --load_model ../models/ctdet_coco_dla_2x.pth ​这里需要注意的是 --demo 后面的 ${CenterNet_Root}/images/17790319373_bd19b24cfc_k.jpg ,这里我使用的是官方给出的实例图片,它位于CenterNet根目录的images文件夹中,前面的 ${CenterNet_Root} 代表的是 CenterNet根目录,好比我的就位于 /home/zs/CenterNet 。 ​如果不出意外的话效果应该如下图所示: 运行CenterNet的3D目标检测 配置数据集和模型 ​我们可以直接参考官方的 DATA.md 来配置我们的数据集。 -​然后到 Model zoo 下载3D检测使用的模型 ddd_3dop....

January 27, 2021 · 2 min · zzsqwq

Ubuntu18.04优化教程

前言 因为最近Ubuntu用的比较频繁,所以前一阵把Ubuntu16.04换成Ubuntu18.04了,并且囿于机械硬盘那启动速度,我忍痛割爱把我80G的固态硬盘分给了Ubuntu。 +​然后到 Model zoo 下载3D检测使用的模型 ddd_3dop.pth 。 +​这里说一下遇到的几个坑: +首先是配置数据集的过程中,我们需要配置的目录结构如图所示(官方给出的结构树有点模糊不清的感觉) +. ├── ImageSets_3dop │ ├── test.txt │ ├── train.txt │ ├── trainval.txt │ └── val.txt ├── ImageSets_subcnn │ ├── test.txt │ ├── train.txt │ ├── trainval.txt │ └── val.txt └── training ├── calib ├── image_2 └── label_2 然后去到 ${CenterNet_ROOT}/src/tools目录下,运行 python convert_kitti_to_coco.py 将 kitti 数据集转换为 coco 数据集的格式,不出意外应该会报错如下: +...

January 27, 2021 · 2 min · zzsqwq

Ubuntu18.04优化教程

前言 因为最近Ubuntu用的比较频繁,所以前一阵把Ubuntu16.04换成Ubuntu18.04了,并且囿于机械硬盘那启动速度,我忍痛割爱把我80G的固态硬盘分给了Ubuntu。 后来,用着用着就觉得这个Ubuntu的原始界面确实不是特别的好看,配色偏基佬紫的感觉。“工欲善其事,必先利其器“,我们只有将自己的工作环境布置的舒心一些才能有做下去的动力!所以我想给Ubuntu换一个看起来舒服点的界面,然后上网找教程乱七八糟的倒腾了一会,感觉换完以后完全不一样了,这个界面真的好看!!用起来也特别的舒心,感觉自己马上就要告别Windows投奔Linux的怀抱了。后续还有一些其他的优化,例如装QQ、微信、配置终端等,一并写在这里吧。 Ubuntu界面的优化 具体效果 先放几张效果图上来,是我改后的界面。大概就是这样(自我感觉挺好看的),当然也有其他的主题可供选择。 1.安装GNOME桌面环境主题配置工具 如果要改主题,那么首先要有一个利器,这里我用的Ubuntu18.04,桌面环境为 GNOME 3.28.2 ,因为我目前接触的只有GNOME桌面环境的,Ubuntu18.04本来的桌面环境就是GNOME,但是Ubuntu16.04好像没有自带,但是可以安装,这里大家可以自行百度了解。 @@ -28,8 +32,9 @@ 然后我们回到 GNOME Tweaks 软件中就可以发现,我们已经可以在主题\图标\光标\Shell清单中找到我们移动到文件夹中的文件了,然后选择就可以切换了。这里需要注意的,很多主题都是自带Shell的,你下了一个主题,那么你可以在Shell和主题这两个栏目中都找到他们,是一个配套的。 4.一些后续的调整 我们后续可以改变左边收藏夹的位置,我觉得放在左边有一丢丢的丑,所以我选择把它放在的下面。 我们去Ubuntu软件中搜索 Dash to dock,然后安装这个拓展,然后打开 GNOME Tweaks 软件在拓展中找到他就可以随心所欲的调我们的收藏夹的位置了。 -5.我自己的配置 theme&shell Canta-light-compact icons 01-McMojave-circle 6.界面修改的参考链接 Ubuntu18.04美化主题(mac主题) Ubuntu18.04美化主题(完整版) GNOME-LOOK.ORG 30个非常不错的Ubuntu主题供你选择 ubuntu18....

December 4, 2020 · 1 min · zzsqwq
© 2024 Zs's Blog +5.我自己的配置 theme&shell Canta-light-compact icons 01-McMojave-circle 6.界面修改的参考链接 Ubuntu18.04美化主题(mac主题) Ubuntu18.04美化主题(完整版) GNOME-LOOK.ORG 30个非常不错的Ubuntu主题供你选择 ubuntu18.04更换鼠标游标主题 配置终端 前言 唔,终端本来用起来感觉也还行,感觉终端就是linux的灵魂,啥都能干。 +...

December 4, 2020 · 1 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/categories/\345\215\232\345\256\242\344\270\273\351\242\230/index.html" "b/categories/\345\215\232\345\256\242\344\270\273\351\242\230/index.html" index 433fac6c..fed640ad 100644 --- "a/categories/\345\215\232\345\256\242\344\270\273\351\242\230/index.html" +++ "b/categories/\345\215\232\345\256\242\344\270\273\351\242\230/index.html" @@ -1,6 +1,6 @@ 博客主题 | Zs's Blog -

一个基于 Hugo 的个人主页主题

背景 之前看到过学长学姐做过个人主页,多是用来申请一些学校的夏令营使用的,觉得非常的 Nice,自己也想搞一个。 +

一个基于 Hugo 的个人主页主题

背景 之前看到过学长学姐做过个人主页,多是用来申请一些学校的夏令营使用的,觉得非常的 Nice,自己也想搞一个。 大家之前好像大多用的是基于 Hexo 的一个主题 — hexo-theme-academia,但是由于之前我用过 Hexo,觉得他有一些比较明显的弊端,例如环境配置比较麻烦、需要安装 Nodejs、npm 等环境,然后再安装 Hexo。其次它的构建速度比较慢,用起来感觉比较僵硬。 后来随着了解增多,尝试了 Typecho、WordPress,Hugo 等主题后,目前还是决定使用 Hugo。它构建速度快,而且安装简单,在 Ubuntu 上只需要一行 sudo apt install hugo 即可,不可谓不简单。因此萌生了移植一个 Hugo 版本主题的想法,刚好可以锻炼一下自己。 欢迎点击 这里 查看我的个人主页。 @@ -18,5 +18,5 @@ 中文效果图:

May 3, 2022 · 1 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/categories/\346\213\274\345\244\232\345\244\232/index.html" "b/categories/\346\213\274\345\244\232\345\244\232/index.html" index 599195a6..88fb1be2 100644 --- "a/categories/\346\213\274\345\244\232\345\244\232/index.html" +++ "b/categories/\346\213\274\345\244\232\345\244\232/index.html" @@ -1,6 +1,6 @@ 拼多多 | Zs's Blog -

为什么应该抵制拼多多?

TL;DR 本文旨在结合一系列事实总结拼多多过去的一系列恶心行为,包括不限于 +

为什么应该抵制拼多多?

TL;DR 本文旨在结合一系列事实总结拼多多过去的一系列恶心行为,包括不限于 虚假宣传 砍一刀套路多 拉人助力 铺天盖地的广告 利用漏洞 希望大家抵制拼多多这种无良平台,非必要不使用拼多多。 前言 最近看了很多拼多多令人反感的操作以及看了很多拼多多的软广,如 拼多多,让谁不爽,看到这么一个无良平台逐渐壮大实在是令人恼火,因此我觉得有必要写一篇文章来总结一下拼多多各种恶心人的操作来让大家了解这个无良平台,来看看他到底为什么让人不爽,并呼吁大家可以联合抵制这个平台。 本文会尽量客观理性,陈述已发生的事实而不是自己的观点,同时因为我不是商家,也不是拼多多的员工,本文只是作为用户角度评判。除了对用户方面的恶心行为,还有对员工及商家的压榨,这个后面有时间再写。欢迎大家补充、批评、指正。 @@ -17,8 +17,9 @@ 据小桀自己回应,直到3月17号下午2点40分左右下播,也没有砍成功,但是突然在4点40分左右莫名其妙的成功了,赠送了一张无门槛购物券可以下单此手机,随后客服回应:砍价不成功不属实,已经发放「特制」优惠券。这一通操作,实在是闻所未闻,谁也能看出来是事态发展到不可预料的地步搞了个东西出来封口的。 实在是太像诈骗、传销了,即使这样广泛的虚假宣传,到现在也没有被整治,也还是随处可见。 附小桀对这件事情的声明: -三、拉人助力 拼多多最特色的行为,应该就是这个拉人助力,可能算是拉人助力的始祖了,如今算是各个软件的标配了,美团、饿了么、携程旅行、智行中也都随处可见。好处显而易见,可以提高自己活动的参与率、提高 App 的下载率、提高品牌知名度、提高用户粘性。...

May 1, 2023 · 1 min · zzsqwq
© 2024 Zs's Blog +三、拉人助力 拼多多最特色的行为,应该就是这个拉人助力,可能算是拉人助力的始祖了,如今算是各个软件的标配了,美团、饿了么、携程旅行、智行中也都随处可见。好处显而易见,可以提高自己活动的参与率、提高 App 的下载率、提高品牌知名度、提高用户粘性。 +...

May 1, 2023 · 1 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/categories/\346\220\234\347\264\242/index.html" "b/categories/\346\220\234\347\264\242/index.html" index 8f04382b..49544829 100644 --- "a/categories/\346\220\234\347\264\242/index.html" +++ "b/categories/\346\220\234\347\264\242/index.html" @@ -1,8 +1,8 @@ 搜索 | Zs's Blog -

洛谷的一些搜索题

1. P1378 油滴扩展 题意 在长方形框中,最多有 n ($0\le{n}\le6$)个相异点,在框中点上依次放置可扩展的油滴,当碰到其他油滴边界或者长方形边框时会停止,扩展呈圆形展开。放置下一个时会确保上一个已经扩展完成。问通过变换放置顺序可使得最终框中剩下的面积最小为多少。 +

洛谷的一些搜索题

1. P1378 油滴扩展 题意 在长方形框中,最多有 n ($0\le{n}\le6$)个相异点,在框中点上依次放置可扩展的油滴,当碰到其他油滴边界或者长方形边框时会停止,扩展呈圆形展开。放置下一个时会确保上一个已经扩展完成。问通过变换放置顺序可使得最终框中剩下的面积最小为多少。 ...

February 4, 2020 · 2 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/categories/\346\225\260\346\215\256\345\272\223/index.html" "b/categories/\346\225\260\346\215\256\345\272\223/index.html" index b3fc7db9..810bc205 100644 --- "a/categories/\346\225\260\346\215\256\345\272\223/index.html" +++ "b/categories/\346\225\260\346\215\256\345\272\223/index.html" @@ -1,6 +1,6 @@ 数据库 | Zs's Blog -

数据库的一些基础知识总结

了解SQL 一.什么是SQL SQL是结构化查询语言(Structured Query Language)的缩写。是一种专门用来与数据库通信的语言。 +

数据库的一些基础知识总结

了解SQL 一.什么是SQL SQL是结构化查询语言(Structured Query Language)的缩写。是一种专门用来与数据库通信的语言。 二.什么是数据库? 数据库(Database):保存有组织的数据的容器(通常是一个文件或一组文件)。 ​[scode type = “yellow”]需要注意的是,有时候我们把数据库软件也简称为数据库,但是数据库软件和数据库有本质区别,数据库软件应称为DBMS(数据库管理系统),我们通过数据库软件对数据库进行删减等操作,他代替你操作和访问数据库。[/scode] 三.数据库的组成 表 数据库中通常有多张表,这类似于一个清单。就好像我们管理两个班级就可以用两个表单。 @@ -37,5 +37,5 @@ 参考链接 数据库设计三大范式_dosthing 数据库设计三大范式_张龙豪 mysql必知必会

September 11, 2020 · 1 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/categories/\346\225\260\346\215\256\347\273\223\346\236\204/index.html" "b/categories/\346\225\260\346\215\256\347\273\223\346\236\204/index.html" index 7ff245ae..9b640a17 100644 --- "a/categories/\346\225\260\346\215\256\347\273\223\346\236\204/index.html" +++ "b/categories/\346\225\260\346\215\256\347\273\223\346\236\204/index.html" @@ -1,8 +1,8 @@ 数据结构 | Zs's Blog -

高精度计算pi

高精度计算PI值 题目描述 使用双向链表作为存储结构,请根据用户输入的一个整数(该整数表示精确到小数点后的位数,可能要求精确到小数点后 500 位),高精度计算PI值。提示:可以利用反三角函数幂级展开式来进行计算。 +

高精度计算pi

高精度计算PI值 题目描述 使用双向链表作为存储结构,请根据用户输入的一个整数(该整数表示精确到小数点后的位数,可能要求精确到小数点后 500 位),高精度计算PI值。提示:可以利用反三角函数幂级展开式来进行计算。 ...

April 20, 2020 · 3 min · zzsqwq

单调队列和单调栈总结

前言 最近感觉遇到了好多单调队列和单调栈的问题,但是因为以前没学好,所以遇见了就一脸懵逼,然后绝对下决心来学一下。。感觉遇到啥都不会,这可咋办呐。。补不完的漏洞。 ...

February 11, 2020 · 3 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/categories/\346\225\260\346\215\256\347\273\223\346\236\204/index.xml" "b/categories/\346\225\260\346\215\256\347\273\223\346\236\204/index.xml" index 820737bc..94f1725c 100644 --- "a/categories/\346\225\260\346\215\256\347\273\223\346\236\204/index.xml" +++ "b/categories/\346\225\260\346\215\256\347\273\223\346\236\204/index.xml" @@ -272,46 +272,46 @@ $$</p> <p>顾名思义,他就是一个单调的队列,那么我们可以规定他是单调递增的还是单调递减的,他和普通的队列有点区别,队列一般是尾进头出,而单调队列要实现的话要确保头和尾都可以出,尾可以进。如果要用STL库的话可以用里面的双端队列。 跟普通队列相比他的进队需要确保一个条件就是要<strong>不破坏原有序列的单调性</strong>,好比我们有一个单调递增的单调队列,也就是从队首到队尾是单调递增的,那么有一段序列是 $[2,3,1,5,8,7,4,2]$ ,我们从左到右依次入队。</p> <table> -<thead> -<tr> -<th>队列中元素</th> -<th>关于元素进出的备注</th> -</tr> -</thead> -<tbody> -<tr> -<td>2</td> -<td>2入队</td> -</tr> -<tr> -<td>2,3</td> -<td>3比2大,可以满足递增性质,入队</td> -</tr> -<tr> -<td>1</td> -<td>因为1比2,3都小,要满足递增性质,先把2,3出队,再将1入队</td> -</tr> -<tr> -<td>1,5</td> -<td>5比1大,可以满足递增性质,入队</td> -</tr> -<tr> -<td>1,5,8</td> -<td>8比5大,可以满足递增性质,入队</td> -</tr> -<tr> -<td>1,5,7</td> -<td>7小于8,大于5,要满足递增性质,我们把8出队,然后将7入队</td> -</tr> -<tr> -<td>1,4</td> -<td>4小于5、7,但是大于1,因此7,5依次出队,4入队</td> -</tr> -<tr> -<td>1,2</td> -<td>2小于4,大于1,因此4出队,2入队</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">队列中元素</th> + <th style="text-align: left">关于元素进出的备注</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">2</td> + <td style="text-align: left">2入队</td> + </tr> + <tr> + <td style="text-align: left">2,3</td> + <td style="text-align: left">3比2大,可以满足递增性质,入队</td> + </tr> + <tr> + <td style="text-align: left">1</td> + <td style="text-align: left">因为1比2,3都小,要满足递增性质,先把2,3出队,再将1入队</td> + </tr> + <tr> + <td style="text-align: left">1,5</td> + <td style="text-align: left">5比1大,可以满足递增性质,入队</td> + </tr> + <tr> + <td style="text-align: left">1,5,8</td> + <td style="text-align: left">8比5大,可以满足递增性质,入队</td> + </tr> + <tr> + <td style="text-align: left">1,5,7</td> + <td style="text-align: left">7小于8,大于5,要满足递增性质,我们把8出队,然后将7入队</td> + </tr> + <tr> + <td style="text-align: left">1,4</td> + <td style="text-align: left">4小于5、7,但是大于1,因此7,5依次出队,4入队</td> + </tr> + <tr> + <td style="text-align: left">1,2</td> + <td style="text-align: left">2小于4,大于1,因此4出队,2入队</td> + </tr> + </tbody> </table> <p>根据上述例子不难看出,我们要入队的时候首先要确保队尾元素要比想要入队的元素小,然后才能入队,否则的话就一直循环让尾部元素出队,直到能够满足单调性为止。</p> <h2 id="单调队列的应用">单调队列的应用</h2> @@ -449,38 +449,38 @@ $$</p> <h2 id="理解-1">理解</h2> <p>单调栈也是在普通栈的基础上加了单调性,一般是用从栈底到栈顶的单调性来命名,好比从栈底到栈顶是单调递增的,那么他就是单调增的栈。跟单调队列一样,他的入栈规则也是<strong>要不破坏单调性</strong>,因此一个单调递增的栈如果有元素要入栈,如果他比栈顶的元素还要大,就可以直接入栈,如果他比栈顶的元素小,那么就要将栈顶的元素一直出栈到比要入栈元素小为止。如果序列为 $[2,3,1,5,4,7]$,要加入单调递增栈中,过程如下。<strong>PS:注意从左到右对应栈底到栈顶。</strong></p> <table> -<thead> -<tr> -<th>栈中的元素</th> -<th>关于元素进出的备注</th> -</tr> -</thead> -<tbody> -<tr> -<td>2</td> -<td>元素2压入栈中</td> -</tr> -<tr> -<td>2,3</td> -<td>3大于2,压入栈中</td> -</tr> -<tr> -<td>1</td> -<td>1小于3、2,因此全部弹出将1入栈</td> -</tr> -<tr> -<td>1,5</td> -<td>5大于1,压入栈中</td> -</tr> -<tr> -<td>1,4</td> -<td>4比5小,比1大,弹出5,压入4</td> -</tr> -<tr> -<td>1,4,7</td> -<td>7大于4,压入栈中</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">栈中的元素</th> + <th style="text-align: left">关于元素进出的备注</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">2</td> + <td style="text-align: left">元素2压入栈中</td> + </tr> + <tr> + <td style="text-align: left">2,3</td> + <td style="text-align: left">3大于2,压入栈中</td> + </tr> + <tr> + <td style="text-align: left">1</td> + <td style="text-align: left">1小于3、2,因此全部弹出将1入栈</td> + </tr> + <tr> + <td style="text-align: left">1,5</td> + <td style="text-align: left">5大于1,压入栈中</td> + </tr> + <tr> + <td style="text-align: left">1,4</td> + <td style="text-align: left">4比5小,比1大,弹出5,压入4</td> + </tr> + <tr> + <td style="text-align: left">1,4,7</td> + <td style="text-align: left">7大于4,压入栈中</td> + </tr> + </tbody> </table> <p>根据上述描述不难看出,其实单调栈就是单调队列的半部分,他能完成的任务理论上单调队列都能够完成,但是有些时候不需要麻烦的去维护单调队列只需要维护单调栈即可完成。</p> <h2 id="单调栈的应用">单调栈的应用</h2> diff --git "a/categories/\346\235\202\345\255\246/index.html" "b/categories/\346\235\202\345\255\246/index.html" index c366a00e..ef5299fa 100644 --- "a/categories/\346\235\202\345\255\246/index.html" +++ "b/categories/\346\235\202\345\255\246/index.html" @@ -1,6 +1,6 @@ 杂学 | Zs's Blog -

利用树莓派为HP LaserJet 1020配置无线打印功能

前言 最近基地的打印机突然又好起来了。 +

利用树莓派为HP LaserJet 1020配置无线打印功能

前言 最近基地的打印机突然又好起来了。 因为基地的打印机型号比较老——HP LaserJet 1020,没有无线打印的功能。所以之前一位学长1 用树莓派配置了打印机的无线打印功能,但是后来发现有一些问题,有时候发送打印请求树莓派无法接收,而且不知道为何,学长之前用的是树莓派自己创建WiFi,连接对应WiFi才能打印,但是这个显然不是最优的解决办法。 考虑到之间已经配置好基地WiFi,我决定重新配置一下打印功能,使其连接基地WiFi即可实现局域网打印。 配置过程 查看树莓派内容 通过ssh连接树莓派,发现里面除了Github上的一个开源项目create_ap ,就没有什么其他的内容了,连接屏幕后发现没有任何图像信号,无从下手,因此考虑重新刷机。 @@ -14,7 +14,8 @@ $ sudo ifconfig 查看WiFi对应的IP,至此,树莓派可以摆脱屏幕,我们可以使用电脑进行使用 ssh 连接。 这里也可以使用网线进行连接,具体操作如下 用网线连接树莓派和自己的电脑。 -在树莓派的利用 nmtui 选择 Edit a connection ,Add一个Ethernet connect,对IPv4 CONFIGURATION进行设置,首先讲 Automatic 设置为 Manual,设置 Address 为 静态IP 如 192....

July 18, 2021 · 2 min · zzsqwq

利用神经网络进行波士顿房价预测

前言 前一阵学校有五一数模节校赛,和朋友一起参加做B题,波士顿房价预测,算是第一次自己动手实现一个简单的小网络吧,虽然很简单,但还是想记录一下。 +在树莓派的利用 nmtui 选择 Edit a connection ,Add一个Ethernet connect,对IPv4 CONFIGURATION进行设置,首先讲 Automatic 设置为 Manual,设置 Address 为 静态IP 如 192.168.3.2 ,Gateway 设置为 192.168.3.1 。 +...

July 18, 2021 · 2 min · zzsqwq

利用神经网络进行波士顿房价预测

前言 前一阵学校有五一数模节校赛,和朋友一起参加做B题,波士顿房价预测,算是第一次自己动手实现一个简单的小网络吧,虽然很简单,但还是想记录一下。 题目介绍 波士顿住房数据由哈里森和鲁宾菲尔德于1978年Harrison and Rubinfeld1收集。它包括了波士顿大区每个调查行政区的506个观察值。1980年Belsley et al.2曾对此数据做过分析。 数据一共14列,每一列的含义分别如下: 英文简称 详细含义 CRIM 城镇的人均犯罪率 ZN 大于25,000平方英尺的地块的住宅用地比例。 INDUS 每个镇的非零售业务英亩的比例。 CHAS 查尔斯河虚拟变量(如果环河,则等于1;否则等于0) NOX 一氧化氮的浓度(百万分之几) RM 每个住宅的平均房间数 AGE 1940年之前建造的自有住房的比例 DIS 到五个波士顿就业中心的加权距离 RAD 径向公路通达性的指标 TAX 每一万美元的全值财产税率 PTRATIO 各镇的师生比率 B 计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例 LSTAT 底层人口的百分比(%) price 自有住房数的中位数,单位(千美元) 基于上述数据,请完成以下问题: @@ -24,7 +25,8 @@ 建立前馈神经网络模型,根据通用逼近定理,我们可以拟合此回归模型。 我们对上述模型来进行实现并确定评估标准来对他们进行比较,选择最优的模型作为预测模型。 算法流程 传统的回归算法 自变量的选择 首先,考虑到数据集中13列自变量其中某一些可能和最终的房价并无强相关性,如果全部使用进行预测可能会对模型引入噪声,因此我们首先计算了房价price与各个自变量之间的相关系数 $r$ ,其中 $r$ 计算公式如下: $$ r = \frac{\sum(x_i-\bar{x})(y_i-\bar{y})}{\sqrt{\sum(x_i-\bar{x})^2\sum(y_i-\bar{y})^2}} $$ 其中 $x_i,y_i$ 为数据的每个分量,$\bar{x},\bar{y}$ 为数据的均值 -该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下:...

May 16, 2021 · 1 min · zzsqwq

如何使用CenterNet做3D目标检测测试

CenterNet—Objects as Points介绍 ​CenterNet是一个anchor-free的目标检测网络,与YOLOv3相比,精度有所提升,此外他不仅能够用于2D目标检测,也能够用于人体姿态识别,3D目标检测等··· +该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下: +...

May 16, 2021 · 1 min · zzsqwq

如何使用CenterNet做3D目标检测测试

CenterNet—Objects as Points介绍 ​CenterNet是一个anchor-free的目标检测网络,与YOLOv3相比,精度有所提升,此外他不仅能够用于2D目标检测,也能够用于人体姿态识别,3D目标检测等··· 安装CenterNet ​其实安装CenterNet的过程就是一个配置环境的问题,直接跟着官方给出的这里Install.md配置一下即可,十分推荐使用Conda来管理环境,这里给出我的环境给大家参考一下: Ubuntu = 18.04 LTS pytorch = 1.2.0 @@ -37,17 +39,22 @@ python demo.py ctdet --demo ${CenterNet_Root}/images/17790319373_bd19b24cfc_k.jpg --load_model ../models/ctdet_coco_dla_2x.pth ​这里需要注意的是 --demo 后面的 ${CenterNet_Root}/images/17790319373_bd19b24cfc_k.jpg ,这里我使用的是官方给出的实例图片,它位于CenterNet根目录的images文件夹中,前面的 ${CenterNet_Root} 代表的是 CenterNet根目录,好比我的就位于 /home/zs/CenterNet 。 ​如果不出意外的话效果应该如下图所示: 运行CenterNet的3D目标检测 配置数据集和模型 ​我们可以直接参考官方的 DATA.md 来配置我们的数据集。 -​然后到 Model zoo 下载3D检测使用的模型 ddd_3dop....

January 27, 2021 · 2 min · zzsqwq

“程序星编程之路”第二次作业题解

“程序星编程之路”第二次作业题解 A. Zs的回文质数 题目描述 读入一个整数 $n$ ,输出 $[1,n]$ 的所有回文质数,我们规定 $1\sim9$ 也是回文数。 +​然后到 Model zoo 下载3D检测使用的模型 ddd_3dop.pth 。 +​这里说一下遇到的几个坑: +首先是配置数据集的过程中,我们需要配置的目录结构如图所示(官方给出的结构树有点模糊不清的感觉) +. ├── ImageSets_3dop │ ├── test.txt │ ├── train.txt │ ├── trainval.txt │ └── val.txt ├── ImageSets_subcnn │ ├── test.txt │ ├── train.txt │ ├── trainval.txt │ └── val.txt └── training ├── calib ├── image_2 └── label_2 然后去到 ${CenterNet_ROOT}/src/tools目录下,运行 python convert_kitti_to_coco.py 将 kitti 数据集转换为 coco 数据集的格式,不出意外应该会报错如下: +...

January 27, 2021 · 2 min · zzsqwq

“程序星编程之路”第二次作业题解

“程序星编程之路”第二次作业题解 A. Zs的回文质数 题目描述 读入一个整数 $n$ ,输出 $[1,n]$ 的所有回文质数,我们规定 $1\sim9$ 也是回文数。 思路 首先我们需要了解什么是回文数,以及什么是质数。 简单点说,回文数就是正着读反着读都是一样的,也就是对称的,形如 $abcba $ 或者 $123321$ 这样的。 质数的话,对于一个数 $n$ ,如果他是质数,那它除了 $1$ 和 $n$ 没有其他因子。例如 $2,3,5,7,11$ 这样的。 那么接下来我们考虑一下解决这个问题应该怎么做,首先我们看一下数据范围,$[1,100000]$ ,还是挺小的,我们可以考虑直接枚举每一个数来判断它是不是回文数,然后再判断一下是不是质数,如果两个都满足,我们就输出它。 判断回文数,我们可以考虑到 NOJ05 幸运数 一题的解题思路,也就是说我们把一个数倒置过来,好比一个数 $xyz$ 倒置成 $zyx$ ,然后判断是否 $xyz == zyx$ ,如果相等的话就是回文数,如果不相等就不是。 判断质数,我们可以在 $[2,\lfloor\sqrt{n}\rfloor]$ 枚举它的因子,这个的完备性我上课的时候证明过,不再赘述。这里需要注意 $1,2$ 需要特判一下。 -代码 #include<stdio.h> #include<math.h> //我们需要用到sqrt函数,因此需要引入数学库 int main() { int n; bool flag = false; // 标记 i 是否满足条件 scanf("%d",&n); for(int i=1;i<=n;i++) { flag = true; int p=i,j=0; while(p) // 将 p 反转为 j { j=j*10+p%10; p/=10; } if(j==i) { if(j==1) continue; // 特判 1 if(j==2) // 特判 2 { printf("2\n"); continue; } int sqrtj = sqrt(j); for(int k=2;k<=sqrtj;k++) // 枚举 [2,sqrt(n)] { if(j%k==0) // 如果能够整除(余数为0),那么是 j 的因子 { flag = false; break; } } if(flag) { printf("%d\n",j); } } } } 其他 因为我们讲到这里的时候,我们没讲函数,但是这道题如果我们把判断是否为回文数,判断是否为质数,都另成一个函数模块,将使得程序变得更加简洁。我在这里也将函数版本的贴出来,有兴趣的可以看一下。...

November 12, 2020 · 3 min · zzsqwq

自买服务器建站教程

引言 本来之前是用的 Hexo + Github 搭建的,虽然用的是 Github 的服务器,但是我用家里的移动网访问起来还是没什么压力,就是慢一点,可以接受。 +代码 #include<stdio.h> #include<math.h> //我们需要用到sqrt函数,因此需要引入数学库 int main() { int n; bool flag = false; // 标记 i 是否满足条件 scanf("%d",&n); for(int i=1;i<=n;i++) { flag = true; int p=i,j=0; while(p) // 将 p 反转为 j { j=j*10+p%10; p/=10; } if(j==i) { if(j==1) continue; // 特判 1 if(j==2) // 特判 2 { printf("2\n"); continue; } int sqrtj = sqrt(j); for(int k=2;k<=sqrtj;k++) // 枚举 [2,sqrt(n)] { if(j%k==0) // 如果能够整除(余数为0),那么是 j 的因子 { flag = false; break; } } if(flag) { printf("%d\n",j); } } } } 其他 因为我们讲到这里的时候,我们没讲函数,但是这道题如果我们把判断是否为回文数,判断是否为质数,都另成一个函数模块,将使得程序变得更加简洁。我在这里也将函数版本的贴出来,有兴趣的可以看一下。 +...

November 12, 2020 · 3 min · zzsqwq

自买服务器建站教程

引言 本来之前是用的 Hexo + Github 搭建的,虽然用的是 Github 的服务器,但是我用家里的移动网访问起来还是没什么压力,就是慢一点,可以接受。 后来到了学校,我们学校网访问 Github 的速度简直可以用龟速来形容,白天可以说不开代理根本进不去,只有晚上了才能勉强进得去。然后我就寻思,能不能换成国内的服务器,然后就发现了 Gitee ,这个可以算是中国版的 Github ,他具有的服务 Gitee Pages 在国内可以飞速的访问,But如果想要自定义域名/每次推送自动更新需要开 Github Pages Pro ,还挺贵的,一年大概 120¥ 吧。此外,如果想要将域名解析到国内的服务器必须要备案,备案又必须有服务器,那我有服务器了还费那些事了,于是考虑自己买服务器重构一下博客。 ...

August 26, 2020 · 1 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/categories/\346\235\202\345\255\246/index.xml" "b/categories/\346\235\202\345\255\246/index.xml" index abf5d1e0..d224a6cf 100644 --- "a/categories/\346\235\202\345\255\246/index.xml" +++ "b/categories/\346\235\202\345\255\246/index.xml" @@ -148,70 +148,70 @@ <p>波士顿住房数据由哈里森和鲁宾菲尔德于1978年Harrison and Rubinfeld<sup><a href="https://blog.zzsqwq.cn/usr/uploads/2021/05/406125417.png">1</a></sup>收集。它包括了波士顿大区每个调查行政区的506个观察值。1980年Belsley et al.<sup><a href="https://blog.zzsqwq.cn/usr/uploads/2021/05/3238192089.png">2</a></sup>曾对此数据做过分析。</p> <p>数据一共14列,每一列的含义分别如下:</p> <table> -<thead> -<tr> -<th>英文简称</th> -<th>详细含义</th> -</tr> -</thead> -<tbody> -<tr> -<td>CRIM</td> -<td>城镇的人均犯罪率</td> -</tr> -<tr> -<td>ZN</td> -<td>大于25,000平方英尺的地块的住宅用地比例。</td> -</tr> -<tr> -<td>INDUS</td> -<td>每个镇的非零售业务英亩的比例。</td> -</tr> -<tr> -<td>CHAS</td> -<td>查尔斯河虚拟变量(如果环河,则等于1;否则等于0)</td> -</tr> -<tr> -<td>NOX</td> -<td>一氧化氮的浓度(百万分之几)</td> -</tr> -<tr> -<td>RM</td> -<td>每个住宅的平均房间数</td> -</tr> -<tr> -<td>AGE</td> -<td>1940年之前建造的自有住房的比例</td> -</tr> -<tr> -<td>DIS</td> -<td>到五个波士顿就业中心的加权距离</td> -</tr> -<tr> -<td>RAD</td> -<td>径向公路通达性的指标</td> -</tr> -<tr> -<td>TAX</td> -<td>每一万美元的全值财产税率</td> -</tr> -<tr> -<td>PTRATIO</td> -<td>各镇的师生比率</td> -</tr> -<tr> -<td>B</td> -<td>计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例</td> -</tr> -<tr> -<td>LSTAT</td> -<td>底层人口的百分比(%)</td> -</tr> -<tr> -<td><strong>price</strong></td> -<td>自有住房数的中位数,单位(千美元)</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">英文简称</th> + <th style="text-align: left">详细含义</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">CRIM</td> + <td style="text-align: left">城镇的人均犯罪率</td> + </tr> + <tr> + <td style="text-align: left">ZN</td> + <td style="text-align: left">大于25,000平方英尺的地块的住宅用地比例。</td> + </tr> + <tr> + <td style="text-align: left">INDUS</td> + <td style="text-align: left">每个镇的非零售业务英亩的比例。</td> + </tr> + <tr> + <td style="text-align: left">CHAS</td> + <td style="text-align: left">查尔斯河虚拟变量(如果环河,则等于1;否则等于0)</td> + </tr> + <tr> + <td style="text-align: left">NOX</td> + <td style="text-align: left">一氧化氮的浓度(百万分之几)</td> + </tr> + <tr> + <td style="text-align: left">RM</td> + <td style="text-align: left">每个住宅的平均房间数</td> + </tr> + <tr> + <td style="text-align: left">AGE</td> + <td style="text-align: left">1940年之前建造的自有住房的比例</td> + </tr> + <tr> + <td style="text-align: left">DIS</td> + <td style="text-align: left">到五个波士顿就业中心的加权距离</td> + </tr> + <tr> + <td style="text-align: left">RAD</td> + <td style="text-align: left">径向公路通达性的指标</td> + </tr> + <tr> + <td style="text-align: left">TAX</td> + <td style="text-align: left">每一万美元的全值财产税率</td> + </tr> + <tr> + <td style="text-align: left">PTRATIO</td> + <td style="text-align: left">各镇的师生比率</td> + </tr> + <tr> + <td style="text-align: left">B</td> + <td style="text-align: left">计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例</td> + </tr> + <tr> + <td style="text-align: left">LSTAT</td> + <td style="text-align: left">底层人口的百分比(%)</td> + </tr> + <tr> + <td style="text-align: left"><strong>price</strong></td> + <td style="text-align: left">自有住房数的中位数,单位(千美元)</td> + </tr> + </tbody> </table> <p>基于上述数据,请完成以下问题:</p> <p><strong>建立波士顿房价预测模型并对预测结果进行评价。</strong></p> @@ -236,46 +236,46 @@ $$ 其中 $x_i,y_i$ 为数据的每个分量,$\bar{x},\bar{y}$ 为数据的均值</p> <p>该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下:</p> <table> -<thead> -<tr> -<th>CRIM</th> -<th>ZN</th> -<th>INDUS</th> -<th>CHAS</th> -<th>NOX</th> -<th>RM</th> -<th>LSTAT</th> -</tr> -</thead> -<tbody> -<tr> -<td>-0.385832</td> -<td>0.360445</td> -<td>-0.483725</td> -<td>0.175260</td> -<td>-0.427321</td> -<td>0.695360</td> -<td>-0.737663</td> -</tr> -<tr> -<td><strong>AGE</strong></td> -<td><strong>DIS</strong></td> -<td><strong>RAD</strong></td> -<td><strong>TAX</strong></td> -<td><strong>PTRATIO</strong></td> -<td><strong>B</strong></td> -<td></td> -</tr> -<tr> -<td>-0.376955</td> -<td>0.249929</td> -<td>-0.381626</td> -<td>-0.468536</td> -<td>-0.507787</td> -<td>0.333461</td> -<td></td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">CRIM</th> + <th style="text-align: left">ZN</th> + <th style="text-align: left">INDUS</th> + <th style="text-align: left">CHAS</th> + <th style="text-align: left">NOX</th> + <th style="text-align: left">RM</th> + <th style="text-align: left">LSTAT</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">-0.385832</td> + <td style="text-align: left">0.360445</td> + <td style="text-align: left">-0.483725</td> + <td style="text-align: left">0.175260</td> + <td style="text-align: left">-0.427321</td> + <td style="text-align: left">0.695360</td> + <td style="text-align: left">-0.737663</td> + </tr> + <tr> + <td style="text-align: left"><strong>AGE</strong></td> + <td style="text-align: left"><strong>DIS</strong></td> + <td style="text-align: left"><strong>RAD</strong></td> + <td style="text-align: left"><strong>TAX</strong></td> + <td style="text-align: left"><strong>PTRATIO</strong></td> + <td style="text-align: left"><strong>B</strong></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">-0.376955</td> + <td style="text-align: left">0.249929</td> + <td style="text-align: left">-0.381626</td> + <td style="text-align: left">-0.468536</td> + <td style="text-align: left">-0.507787</td> + <td style="text-align: left">0.333461</td> + <td style="text-align: left"></td> + </tr> + </tbody> </table> <p>观察结果可以发现,在给定的十三个变量中,<strong>LSTAT <strong>与 <strong>price</strong> 的相关程度最高$(|r|&gt;0.7)$,其次是 <strong>RM</strong> 与</strong>PTRATIO</strong> $(|r|&gt;0.5)$,再者是 <strong>TAX,INDUS,NOX</strong> $(|r|&gt;0.4)$,除上述之外的七个变量都与 <strong>price</strong> 无较强的相关性,因此我们考虑使用六个相关性较强变量和十三个变量分别来对房价进行预测,并对他们进行对比,来寻找最优的回归模型。</p> <h5 id="模型的构建">模型的构建</h5> @@ -856,34 +856,34 @@ $$</p> <p><strong>tar</strong> 命令:压缩或解压命令。<code>tar [参数] 打包文件名 要打包的各个文件 </code> 。</p> <p>参数表:</p> <table> -<thead> -<tr> -<th>参数</th> -<th>含义</th> -</tr> -</thead> -<tbody> -<tr> -<td>-c</td> -<td>生成档案文件,创建打包文件</td> -</tr> -<tr> -<td>-v</td> -<td>列出归档解档的详细过程,显示进度</td> -</tr> -<tr> -<td>-f</td> -<td>指定档案文件名称,f后面一定是.tar文件,所以放选项最后</td> -</tr> -<tr> -<td>-t</td> -<td>列出档案中包含的文件</td> -</tr> -<tr> -<td>-x</td> -<td>解开档案文件</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">参数</th> + <th style="text-align: left">含义</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">-c</td> + <td style="text-align: left">生成档案文件,创建打包文件</td> + </tr> + <tr> + <td style="text-align: left">-v</td> + <td style="text-align: left">列出归档解档的详细过程,显示进度</td> + </tr> + <tr> + <td style="text-align: left">-f</td> + <td style="text-align: left">指定档案文件名称,f后面一定是.tar文件,所以放选项最后</td> + </tr> + <tr> + <td style="text-align: left">-t</td> + <td style="text-align: left">列出档案中包含的文件</td> + </tr> + <tr> + <td style="text-align: left">-x</td> + <td style="text-align: left">解开档案文件</td> + </tr> + </tbody> </table> <p>打包实例: <code>tar -cvf 文件名 要打包的文件</code> 解压实例:<code>tar -xvf 压缩包名</code></p> </li> diff --git "a/categories/\346\235\202\345\255\246/page/2/index.html" "b/categories/\346\235\202\345\255\246/page/2/index.html" index 2c907c34..bc695bb7 100644 --- "a/categories/\346\235\202\345\255\246/page/2/index.html" +++ "b/categories/\346\235\202\345\255\246/page/2/index.html" @@ -1,8 +1,8 @@ 杂学 | Zs's Blog -

Linux和Vim入门

Linux系统常见命令 基本操作 **cd (Change Directory)**命令:跳转目录 +

Linux和Vim入门

Linux系统常见命令 基本操作 **cd (Change Directory)**命令:跳转目录 cd path : path为路径,进入相应目录 cd # 或 cd ~ :回到主目录 cd - : 回到上次所在目录 cd !$ :将上个命令的参数做为输入 cd .. :回到上层目录 ...

March 30, 2020 · 2 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/categories/\346\235\202\350\260\210/index.html" "b/categories/\346\235\202\350\260\210/index.html" index 04326f21..acb5c6be 100644 --- "a/categories/\346\235\202\350\260\210/index.html" +++ "b/categories/\346\235\202\350\260\210/index.html" @@ -1,6 +1,6 @@ 杂谈 | Zs's Blog -

关于美的一些思考

楔子 昨天听了学弟们关于博客搭建的一些教程,在听的过程中,也想起了我之前对于博客的种种尝试,发现整体的趋势就是,简约再简约。 +

关于美的一些思考

楔子 昨天听了学弟们关于博客搭建的一些教程,在听的过程中,也想起了我之前对于博客的种种尝试,发现整体的趋势就是,简约再简约。 这引发了我对我过去几年的审视,感觉自己的审美一直在变化,对于美的认识和感受也是一直在变的,故写此文来记一些我对美认识的思考。 简约是我最终的归宿 遥记得我还在小学和初中时,非常迷恋 QQ飞车 这款游戏,这款游戏里面有一个虚拟人物,人物可以搭配各种装饰,包括但不限于上衣、裤子、发型、发饰、翅膀等,起初我是喜欢要多花哨有多花哨造型,各种发饰、翅膀、脸部特效搞的飞起,现在想起来真是非常搞笑,而且喜欢五颜六色的,当时觉得,真的是太好看了。 但是过了一段时间,就开始感觉不对劲了,这么花哨,这么丑,这怎么可能是我当时亲手选择的造型。后来就逐渐向简约范靠拢,装饰越简单,色调越单一越喜欢。 @@ -20,7 +20,8 @@ 我觉得美这个东西,很不像生活中常见的发展规律,例如芯片的研发,需要数学、物理、化学等学科实际理论的支持。 2001 年的人是没有办法设计出 Apple M2 的芯片的,因为受到了各种硬件的制约。而 2001 年的设计师有没有可能设计出最新版 Mac QQ 这样的界面呢,如果不能,是什么制约着它呢?如果能,为什么没有出现这种设计,是因为当时大家觉得他不好看吗? 因为我不是学设计和美术等专业的,并且这种很很直觉的东西我不知道该怎么去搜索,因此想在这里和大家探讨一下。如果有已经相对成熟的理论,还请大家能够告知与我,解答困扰我好久的疑问。 -AI 绘图 看网上有人调侃说,愿意称 2022 年为 AI 绘图元年。...

October 30, 2022 · 1 min · zzsqwq

关于春节期间的一些碎碎念

前言 春节期间,走亲访友是必不可少的。交谈的多了,免不得一些问题的讨论。 +AI 绘图 看网上有人调侃说,愿意称 2022 年为 AI 绘图元年。 +...

October 30, 2022 · 1 min · zzsqwq

关于春节期间的一些碎碎念

前言 春节期间,走亲访友是必不可少的。交谈的多了,免不得一些问题的讨论。 读了很多书,经历了很多事,似乎想法也有一些”离经叛道“,记一下自己目前的一些想法,不知道多年后的自己看这篇文章会是什么想法,还会一如既往的坚持吗。 讨论的话题 打点关系 无论是父母,还是各方亲戚,大家好像都喜欢打点关系,以此来获得一些好处。 最常见的是求人办事,很多时候是我们常说的”走后门“,想让孩子上个好点的小学,避免不了又送礼又吃饭。 @@ -64,8 +65,9 @@ 具体导出为 zip 的时候可能会提示损坏,这样的话可以直接去服务器 \tmp\Export2Hugo 下面打包。 安装 hugo 过程基于 Windows 平台,很简单,在 这里 下载 hugo 最新的 release 版本,找到对应自己系统的即可。下载后解压到某个目录下,设置一下环境变量即可。这里牵扯到 hugo 和 hugo_extended 两个版本的区别,以下是某个 issue 中的解释: I agree. -The only functional difference is SASS/SCSS The technical build time difference is that it requires a C++ build chain for the target platform to build, the reason why we currently only build the extended for 3 platforms (Windows, Linux, MacOS) Binaries are slightly less portable as you need a compatible Libc version on your computer (for Windows we build a fully static version as Libc is rather uncommon unless you have Visual Studio or something installed)....

December 13, 2021 · 2 min · zzsqwq
© 2024 Zs's Blog +The only functional difference is SASS/SCSS The technical build time difference is that it requires a C++ build chain for the target platform to build, the reason why we currently only build the extended for 3 platforms (Windows, Linux, MacOS) Binaries are slightly less portable as you need a compatible Libc version on your computer (for Windows we build a fully static version as Libc is rather uncommon unless you have Visual Studio or something installed). via: Please document the difference between the “extended” and non-“extended” versions +...

December 13, 2021 · 2 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/categories/\347\236\216\346\212\230\350\205\276/index.html" "b/categories/\347\236\216\346\212\230\350\205\276/index.html" index 195f20a1..b7f076b2 100644 --- "a/categories/\347\236\216\346\212\230\350\205\276/index.html" +++ "b/categories/\347\236\216\346\212\230\350\205\276/index.html" @@ -1,12 +1,13 @@ 瞎折腾 | Zs's Blog -

Docker-Gitlab 与主机共用 ssh 的 22 端口

背景 在使用 Docker 搭建 Gitlab/Gitee 会导致无法与主机端共用 22 端口,这导致 ssh 连接的时候会使用形如 ssh://git@git.xxxx.cn:4022/zs/zsblog.git 的 ssh 链接,而不是像官方 Gitlab 那种非常干净的 git@git.xxxx.cn/zs/zsblog.git 链接。这对于我这种强迫症而言非常的难受啊,但因为主机的 22 端口已经被占用了,无法共用,所以需要考虑两者共享端口的问题。 +

Docker-Gitlab 与主机共用 ssh 的 22 端口

背景 在使用 Docker 搭建 Gitlab/Gitee 会导致无法与主机端共用 22 端口,这导致 ssh 连接的时候会使用形如 ssh://git@git.xxxx.cn:4022/zs/zsblog.git 的 ssh 链接,而不是像官方 Gitlab 那种非常干净的 git@git.xxxx.cn/zs/zsblog.git 链接。这对于我这种强迫症而言非常的难受啊,但因为主机的 22 端口已经被占用了,无法共用,所以需要考虑两者共享端口的问题。 虽说是两者共用,但其实还是使用类似于端口转发的特点,简单说就是在主机设置 git 用户,然后通过一个脚本将 git 用户的所有 ssh 流量转发到 Gitlab 容器中,从而完成对应的事情。 关于 Gitee 的设置,Gitee 官方的 Docker 部署教程1已经说的很清楚了,按照该步骤执行完全没问题。 而关于 Gitlab 貌似没有比较详尽的教程,搜索后发现了一个 Issue2 以及一篇博文3,后者讲的比较清楚,但是经过实践后发现存在一定问题,因此决定将可行的方案记录下来。 具体步骤 一、初始设置 在开始之前,docker-compose.yml 中设置比较关键的几个配置如下: -gitlab-web: image: 'gitlab/gitlab-ce:latest' container_name: 'gitlab' restart: always environment: GITLAB_OMNIBUS_CONFIG: | gitlab_rails['gitlab_shell_ssh_port'] = 4022 ports: - '3090:80' - '4022:22' - '6060:6060' volumes: - '/srv/gitlab/config:/etc/gitlab' - '/srv/gitlab/logs:/var/log/gitlab' - '/srv/gitlab/data:/var/opt/gitlab' - ....

April 24, 2022 · 3 min · zzsqwq
© 2024 Zs's Blog +gitlab-web: image: 'gitlab/gitlab-ce:latest' container_name: 'gitlab' restart: always environment: GITLAB_OMNIBUS_CONFIG: | gitlab_rails['gitlab_shell_ssh_port'] = 4022 ports: - '3090:80' - '4022:22' - '6060:6060' volumes: - '/srv/gitlab/config:/etc/gitlab' - '/srv/gitlab/logs:/var/log/gitlab' - '/srv/gitlab/data:/var/opt/gitlab' - .... #一些其他的配置 如上设置基本可以确保 Gitlab 形如 ssh://git@git.xxxx.cn:4022/zs/zsblog.git 的链接可以使用。 +...

April 24, 2022 · 3 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/categories/\347\242\216\347\242\216\345\277\265/index.html" "b/categories/\347\242\216\347\242\216\345\277\265/index.html" index 334fe35d..ef253eb3 100644 --- "a/categories/\347\242\216\347\242\216\345\277\265/index.html" +++ "b/categories/\347\242\216\347\242\216\345\277\265/index.html" @@ -1,6 +1,6 @@ 碎碎念 | Zs's Blog -

2023 年度总结

前言 在回望过去时,我们常感叹时间飞逝,我想这或许是因为过去发生的无数大小事情最终在脑海中留存的只有寥寥几件。因此,撰写年度总结这件事似乎变得格外有意义,它能帮助我们更充分地回味过去的一年。可能正是因为如此,现在各大 APP 似乎都很喜欢推出年度总结,例如网易云、QQ音乐、知乎、飞书、京东、美团、支付宝等。为此,我写下了这篇 2023 年度总结。 +

2023 年度总结

前言 在回望过去时,我们常感叹时间飞逝,我想这或许是因为过去发生的无数大小事情最终在脑海中留存的只有寥寥几件。因此,撰写年度总结这件事似乎变得格外有意义,它能帮助我们更充分地回味过去的一年。可能正是因为如此,现在各大 APP 似乎都很喜欢推出年度总结,例如网易云、QQ音乐、知乎、飞书、京东、美团、支付宝等。为此,我写下了这篇 2023 年度总结。 仔细回味我这过去的一年,我想用几个关键词来概括:#消费升级、#数码科技、#大模型、#老友重逢。 #消费升级:这一年是我消费升级的一年,尽管今年「消费降级」这个词似乎很火,但我似乎与大众走上了一条相反的道路。可能是因为我以往的消费水平本就不高,所以「降级」更是无从谈起。 #数码科技:这一年我购入了一些新的数码设备,虽然数量不多,但每一件都还挺满意的。同时今年由于消费观念的转变,也支持了很多正版软件,因此今年在软件上的开销也不小。 @@ -17,8 +17,7 @@ 五月 五月似乎是相对平淡的一月,在继续社畜日常的同时开始写毕设了。 六月 月初和朋友去海底捞过了生日,属于是 404 的「企业文化」了。然后终于把毕设给忙完了,返校进行了答辩,结果还算顺利。因为返校了也见了很多老朋友,舍友、基地的伙伴们、学弟们(是的应该是没有学妹),约了数不清次数的饭。 基地的大伙聚会 七月 我正式本科毕业了。 -就像开头说的,回望过去总是很快。感觉开学和父母踏进工大校园的那一天还历历在目,转眼间就要毕业了。纵有万般不舍,但还是不得不和朋友们分别了,最后一晚大家一起在 KTV 合唱《朋友》的时候,忍不住泪奔。 -再见,工大 八月 相对平淡的一月,学弟来深圳参加夏令营,顺便过来找我玩,一起逛了腾讯大厦和华强北,看完感觉大厂平常的这些福利确实还是很不错的(不过确实加班严重)。...

January 3, 2024 · 1 min · zzsqwq

2022 年度总结

2022 依旧是被疫情伴随的一年,时间正着看总是要比回看慢很多,现在回头看过往一年似乎一瞬间就过去了。 +...

January 3, 2024 · 1 min · zzsqwq

2022 年度总结

2022 依旧是被疫情伴随的一年,时间正着看总是要比回看慢很多,现在回头看过往一年似乎一瞬间就过去了。 今年共发了 11 篇文章,其中还包含了两篇碎碎念,还是没有达到月更,新的一年希望可以。2022 年对我来说变化很大,算是暂时摆脱了学生生活,体验了社畜的感觉,打卡了北上广深中的北和深。 接下来按月份盘点一些值得纪念的事情吧。 一月: @@ -45,12 +44,8 @@ 哦对了,这个月还搬了新的住所,因为人逐渐变多了,之前的屋子已经住不下了。九月,真是繁忙的一月。 十月: 这个月初入手了 Apple Watch,补齐了个人设备的最后一块拼图算是。iMac 这种没有算进来,因为 iOS、iPadOS、MacOS、WatchOS 四个系统已经集齐了,苹果生态给人的感觉真的很不错。 -有了 Watch 以后,借着新鲜感锻炼了一段时间,但是体重不降反增了,于是动力没了,又回到了肥宅的生活😁。 -同时这个月还和乐乐和雷宝一起去了深圳的欢乐谷游玩,体验了失重的感觉,下次不敢了。 -十一月:平淡的一个月,上班、吃吃吃、玩玩玩。卓卓越来越好看了。 -十二月: -学长从 HK 带回来了最新版的 Apple TV,苹果生态又添一员。现在的联动已经非常棒了,手机可以直接推流到 Homepod、电视、Mac、耳机等。...

January 1, 2023 · 1 min · zzsqwq
January 1, 2023 · 1 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/categories/\347\245\236\347\273\217\347\275\221\347\273\234/index.html" "b/categories/\347\245\236\347\273\217\347\275\221\347\273\234/index.html" index 287e6106..073d9228 100644 --- "a/categories/\347\245\236\347\273\217\347\275\221\347\273\234/index.html" +++ "b/categories/\347\245\236\347\273\217\347\275\221\347\273\234/index.html" @@ -1,6 +1,6 @@ 神经网络 | Zs's Blog -

利用神经网络进行波士顿房价预测

前言 前一阵学校有五一数模节校赛,和朋友一起参加做B题,波士顿房价预测,算是第一次自己动手实现一个简单的小网络吧,虽然很简单,但还是想记录一下。 +

利用神经网络进行波士顿房价预测

前言 前一阵学校有五一数模节校赛,和朋友一起参加做B题,波士顿房价预测,算是第一次自己动手实现一个简单的小网络吧,虽然很简单,但还是想记录一下。 题目介绍 波士顿住房数据由哈里森和鲁宾菲尔德于1978年Harrison and Rubinfeld1收集。它包括了波士顿大区每个调查行政区的506个观察值。1980年Belsley et al.2曾对此数据做过分析。 数据一共14列,每一列的含义分别如下: 英文简称 详细含义 CRIM 城镇的人均犯罪率 ZN 大于25,000平方英尺的地块的住宅用地比例。 INDUS 每个镇的非零售业务英亩的比例。 CHAS 查尔斯河虚拟变量(如果环河,则等于1;否则等于0) NOX 一氧化氮的浓度(百万分之几) RM 每个住宅的平均房间数 AGE 1940年之前建造的自有住房的比例 DIS 到五个波士顿就业中心的加权距离 RAD 径向公路通达性的指标 TAX 每一万美元的全值财产税率 PTRATIO 各镇的师生比率 B 计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例 LSTAT 底层人口的百分比(%) price 自有住房数的中位数,单位(千美元) 基于上述数据,请完成以下问题: @@ -10,8 +10,9 @@ 建立前馈神经网络模型,根据通用逼近定理,我们可以拟合此回归模型。 我们对上述模型来进行实现并确定评估标准来对他们进行比较,选择最优的模型作为预测模型。 算法流程 传统的回归算法 自变量的选择 首先,考虑到数据集中13列自变量其中某一些可能和最终的房价并无强相关性,如果全部使用进行预测可能会对模型引入噪声,因此我们首先计算了房价price与各个自变量之间的相关系数 $r$ ,其中 $r$ 计算公式如下: $$ r = \frac{\sum(x_i-\bar{x})(y_i-\bar{y})}{\sqrt{\sum(x_i-\bar{x})^2\sum(y_i-\bar{y})^2}} $$ 其中 $x_i,y_i$ 为数据的每个分量,$\bar{x},\bar{y}$ 为数据的均值 -该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下:...

May 16, 2021 · 1 min · zzsqwq
© 2024 Zs's Blog +该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下: +...

May 16, 2021 · 1 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/categories/\347\245\236\347\273\217\347\275\221\347\273\234/index.xml" "b/categories/\347\245\236\347\273\217\347\275\221\347\273\234/index.xml" index 52c20f7c..81ee85c2 100644 --- "a/categories/\347\245\236\347\273\217\347\275\221\347\273\234/index.xml" +++ "b/categories/\347\245\236\347\273\217\347\275\221\347\273\234/index.xml" @@ -19,70 +19,70 @@ <p>波士顿住房数据由哈里森和鲁宾菲尔德于1978年Harrison and Rubinfeld<sup><a href="https://blog.zzsqwq.cn/usr/uploads/2021/05/406125417.png">1</a></sup>收集。它包括了波士顿大区每个调查行政区的506个观察值。1980年Belsley et al.<sup><a href="https://blog.zzsqwq.cn/usr/uploads/2021/05/3238192089.png">2</a></sup>曾对此数据做过分析。</p> <p>数据一共14列,每一列的含义分别如下:</p> <table> -<thead> -<tr> -<th>英文简称</th> -<th>详细含义</th> -</tr> -</thead> -<tbody> -<tr> -<td>CRIM</td> -<td>城镇的人均犯罪率</td> -</tr> -<tr> -<td>ZN</td> -<td>大于25,000平方英尺的地块的住宅用地比例。</td> -</tr> -<tr> -<td>INDUS</td> -<td>每个镇的非零售业务英亩的比例。</td> -</tr> -<tr> -<td>CHAS</td> -<td>查尔斯河虚拟变量(如果环河,则等于1;否则等于0)</td> -</tr> -<tr> -<td>NOX</td> -<td>一氧化氮的浓度(百万分之几)</td> -</tr> -<tr> -<td>RM</td> -<td>每个住宅的平均房间数</td> -</tr> -<tr> -<td>AGE</td> -<td>1940年之前建造的自有住房的比例</td> -</tr> -<tr> -<td>DIS</td> -<td>到五个波士顿就业中心的加权距离</td> -</tr> -<tr> -<td>RAD</td> -<td>径向公路通达性的指标</td> -</tr> -<tr> -<td>TAX</td> -<td>每一万美元的全值财产税率</td> -</tr> -<tr> -<td>PTRATIO</td> -<td>各镇的师生比率</td> -</tr> -<tr> -<td>B</td> -<td>计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例</td> -</tr> -<tr> -<td>LSTAT</td> -<td>底层人口的百分比(%)</td> -</tr> -<tr> -<td><strong>price</strong></td> -<td>自有住房数的中位数,单位(千美元)</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">英文简称</th> + <th style="text-align: left">详细含义</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">CRIM</td> + <td style="text-align: left">城镇的人均犯罪率</td> + </tr> + <tr> + <td style="text-align: left">ZN</td> + <td style="text-align: left">大于25,000平方英尺的地块的住宅用地比例。</td> + </tr> + <tr> + <td style="text-align: left">INDUS</td> + <td style="text-align: left">每个镇的非零售业务英亩的比例。</td> + </tr> + <tr> + <td style="text-align: left">CHAS</td> + <td style="text-align: left">查尔斯河虚拟变量(如果环河,则等于1;否则等于0)</td> + </tr> + <tr> + <td style="text-align: left">NOX</td> + <td style="text-align: left">一氧化氮的浓度(百万分之几)</td> + </tr> + <tr> + <td style="text-align: left">RM</td> + <td style="text-align: left">每个住宅的平均房间数</td> + </tr> + <tr> + <td style="text-align: left">AGE</td> + <td style="text-align: left">1940年之前建造的自有住房的比例</td> + </tr> + <tr> + <td style="text-align: left">DIS</td> + <td style="text-align: left">到五个波士顿就业中心的加权距离</td> + </tr> + <tr> + <td style="text-align: left">RAD</td> + <td style="text-align: left">径向公路通达性的指标</td> + </tr> + <tr> + <td style="text-align: left">TAX</td> + <td style="text-align: left">每一万美元的全值财产税率</td> + </tr> + <tr> + <td style="text-align: left">PTRATIO</td> + <td style="text-align: left">各镇的师生比率</td> + </tr> + <tr> + <td style="text-align: left">B</td> + <td style="text-align: left">计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例</td> + </tr> + <tr> + <td style="text-align: left">LSTAT</td> + <td style="text-align: left">底层人口的百分比(%)</td> + </tr> + <tr> + <td style="text-align: left"><strong>price</strong></td> + <td style="text-align: left">自有住房数的中位数,单位(千美元)</td> + </tr> + </tbody> </table> <p>基于上述数据,请完成以下问题:</p> <p><strong>建立波士顿房价预测模型并对预测结果进行评价。</strong></p> @@ -107,46 +107,46 @@ $$ 其中 $x_i,y_i$ 为数据的每个分量,$\bar{x},\bar{y}$ 为数据的均值</p> <p>该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下:</p> <table> -<thead> -<tr> -<th>CRIM</th> -<th>ZN</th> -<th>INDUS</th> -<th>CHAS</th> -<th>NOX</th> -<th>RM</th> -<th>LSTAT</th> -</tr> -</thead> -<tbody> -<tr> -<td>-0.385832</td> -<td>0.360445</td> -<td>-0.483725</td> -<td>0.175260</td> -<td>-0.427321</td> -<td>0.695360</td> -<td>-0.737663</td> -</tr> -<tr> -<td><strong>AGE</strong></td> -<td><strong>DIS</strong></td> -<td><strong>RAD</strong></td> -<td><strong>TAX</strong></td> -<td><strong>PTRATIO</strong></td> -<td><strong>B</strong></td> -<td></td> -</tr> -<tr> -<td>-0.376955</td> -<td>0.249929</td> -<td>-0.381626</td> -<td>-0.468536</td> -<td>-0.507787</td> -<td>0.333461</td> -<td></td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">CRIM</th> + <th style="text-align: left">ZN</th> + <th style="text-align: left">INDUS</th> + <th style="text-align: left">CHAS</th> + <th style="text-align: left">NOX</th> + <th style="text-align: left">RM</th> + <th style="text-align: left">LSTAT</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">-0.385832</td> + <td style="text-align: left">0.360445</td> + <td style="text-align: left">-0.483725</td> + <td style="text-align: left">0.175260</td> + <td style="text-align: left">-0.427321</td> + <td style="text-align: left">0.695360</td> + <td style="text-align: left">-0.737663</td> + </tr> + <tr> + <td style="text-align: left"><strong>AGE</strong></td> + <td style="text-align: left"><strong>DIS</strong></td> + <td style="text-align: left"><strong>RAD</strong></td> + <td style="text-align: left"><strong>TAX</strong></td> + <td style="text-align: left"><strong>PTRATIO</strong></td> + <td style="text-align: left"><strong>B</strong></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">-0.376955</td> + <td style="text-align: left">0.249929</td> + <td style="text-align: left">-0.381626</td> + <td style="text-align: left">-0.468536</td> + <td style="text-align: left">-0.507787</td> + <td style="text-align: left">0.333461</td> + <td style="text-align: left"></td> + </tr> + </tbody> </table> <p>观察结果可以发现,在给定的十三个变量中,<strong>LSTAT <strong>与 <strong>price</strong> 的相关程度最高$(|r|&gt;0.7)$,其次是 <strong>RM</strong> 与</strong>PTRATIO</strong> $(|r|&gt;0.5)$,再者是 <strong>TAX,INDUS,NOX</strong> $(|r|&gt;0.4)$,除上述之外的七个变量都与 <strong>price</strong> 无较强的相关性,因此我们考虑使用六个相关性较强变量和十三个变量分别来对房价进行预测,并对他们进行对比,来寻找最优的回归模型。</p> <h5 id="模型的构建">模型的构建</h5> diff --git "a/categories/\347\273\217\351\252\214\345\210\206\344\272\253/index.html" "b/categories/\347\273\217\351\252\214\345\210\206\344\272\253/index.html" index 9a9311ae..f9f6badd 100644 --- "a/categories/\347\273\217\351\252\214\345\210\206\344\272\253/index.html" +++ "b/categories/\347\273\217\351\252\214\345\210\206\344\272\253/index.html" @@ -1,14 +1,15 @@ 经验分享 | Zs's Blog -

记一次 GitHub 账号突然被 suspended 的经历

TL;DR 我在 2023.11.07 凌晨被 GitHub 封禁了账号,GitHub 账号被 suspended 后会在 GitHub 上完全除名(只有自建创建的组织不会消失)。 +

记一次 GitHub 账号突然被 suspended 的经历

TL;DR 我在 2023.11.07 凌晨被 GitHub 封禁了账号,GitHub 账号被 suspended 后会在 GitHub 上完全除名(只有自建创建的组织不会消失)。 被封禁后我首先通过 Google 查找了相关的文章。 根据博主 @phith0n 的指引首先通过 API:https://api.github.com/users/[username]/starred 备份了自己 star 过的项目,同时通过 Can’t sign-in form 来在无法登陆的情况下发起 GitHub Support 工单来询问/请求解封/询问原因等,一般在两天内收到了回复。最终账号顺利恢复。 我此次被封禁的原因是由于管理的组织内部有成员被盗号,在组织内创建了违法仓库,因此管理员和被盗号的成员都被封禁了,但后续都被解除了封禁。同时也有可能因为创建违反 DMCA 条款 的仓库、fork 违反 DMCA 条款的仓库、贩卖学生/教师教育包等原因被封禁。 背景 大约在 2023.11.07 凌晨 00:30 左右,在 GitHub 上看到了一个不错的项目想要 Star,被提示没有登陆。当时我还在想:“怎么这次 session 过期的这么快?” 就当我边疑惑边重新登录后,突然收到了下图的提示我的账号「Account suspended」: 确认无法登录后,查看邮箱没有任何相关通知。同时我查看了其他内容是否还存在,最后综合表现如下: 没有任何邮件/信息通知被封禁及更加具体的封禁原因,只告诉违反了 ToS 个人页面(https://github.com/zzsqwq)无法访问,访问显示 404 提的相关 Issue 全部被删除(隐藏),无法找到 个人创建的所有项目,访问全部 404,也无法拉取 自己参与的项目,被除名 自己加入的组织,被除名 自己创建的组织,访问 404 简单说就是跟这个账号从来没存在过一样,除了仍可以登陆,但是显示 suspended。接下来开始尝试找办法恢复。 -恢复经过 试图查找封禁原因 首先看提示上显示违反了 Github Terms of Service,快速的看了一眼 ToS 没发现我有什么明显违规的地方。...

November 12, 2023 · 4 min · zzsqwq
© 2024 Zs's Blog +恢复经过 试图查找封禁原因 首先看提示上显示违反了 Github Terms of Service,快速的看了一眼 ToS 没发现我有什么明显违规的地方。 +...

November 12, 2023 · 4 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/categories/\350\203\214\345\214\205/index.html" "b/categories/\350\203\214\345\214\205/index.html" index debc5194..5a0b067a 100644 --- "a/categories/\350\203\214\345\214\205/index.html" +++ "b/categories/\350\203\214\345\214\205/index.html" @@ -1,10 +1,10 @@ 背包 | Zs's Blog -

背包进阶

1. 分组背包 题意 在01背包基础上,将其中的物体分成 $k$ 组,每组内的物品相互冲突,即只能取其中一个,问最大价值。 +

背包进阶

1. 分组背包 题意 在01背包基础上,将其中的物体分成 $k$ 组,每组内的物品相互冲突,即只能取其中一个,问最大价值。 ...

February 9, 2020 · 2 min · zzsqwq

一些关于背包的题

前言 今天跟着背包九讲把背包再学习一下,dd_engi大佬的背包九讲Github链接: 背包九讲 1. 采药(01背包) 题意 有 $n$ 个价值为 $w_i$ ,体积为 $v_i$ 的物品,装入体积为 $V$ 的背包中,问能获得的最大为多少。 ...

February 8, 2020 · 2 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/categories/\350\266\263\347\220\203\346\234\272\345\231\250\344\272\272\345\237\272\345\234\260/index.html" "b/categories/\350\266\263\347\220\203\346\234\272\345\231\250\344\272\272\345\237\272\345\234\260/index.html" index fbc73f4f..151b2971 100644 --- "a/categories/\350\266\263\347\220\203\346\234\272\345\231\250\344\272\272\345\237\272\345\234\260/index.html" +++ "b/categories/\350\266\263\347\220\203\346\234\272\345\231\250\344\272\272\345\237\272\345\234\260/index.html" @@ -1,6 +1,6 @@ 足球机器人基地 | Zs's Blog -

2021RoboMaster中国赛比赛记录

前言 ​说起来的话今天距离比赛已经过去近一个月了,比赛结束一直想要记录一下and总结一下经验,但是实在是太懒了,临近五一假期,在四月的末尾为这次中国赛画一个句号吧。 +

2021RoboMaster中国赛比赛记录

前言 ​说起来的话今天距离比赛已经过去近一个月了,比赛结束一直想要记录一下and总结一下经验,但是实在是太懒了,临近五一假期,在四月的末尾为这次中国赛画一个句号吧。 比赛过程 ​如果没记错的话比赛是3.30号(周二)去,4.1号(周四)结束,共三天。但是因为第三天没做什么有意义的事情,就只记录两天了。 第一天 ​第一天大概中午十点到的吧,去的时候登记完领了牌,就在当地布置场地了。到了场地上才发现,我们好像是拿的东西最多的,包括外接显示屏和集成主机,好像都基本没人带过去····集成主机拿了过去也没怎么用到,本来预想用到的哨岗相机因为 ROS 的通信问题也没能跑成,最后两个机器人还是各跑各的策略了。 ​调试的时候出了一点问题,两个哨岗相机通过20m的USB延长线后,只有一个能连接,后来排查了一下,好像是因为有一条线是光纤USB3.0的线,跟相机的接口不兼容···这个问题还没想好怎么解决,可能会考虑到时候自己带一根USB延长线过去。 @@ -15,5 +15,5 @@ 最后,这一天还拿到了和Charm young的合照,还挺动容的,之前看Robomaster的一个宣传标语就是让工程师们成为明星,给他们一个展示的舞台,看到大家对Charm young的热情,深深的感受到了这一点。

April 30, 2021 · 1 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/categories/\351\232\217\347\254\224/index.html" "b/categories/\351\232\217\347\254\224/index.html" index d1585a7d..a5deec8e 100644 --- "a/categories/\351\232\217\347\254\224/index.html" +++ "b/categories/\351\232\217\347\254\224/index.html" @@ -1,6 +1,6 @@ 随笔 | Zs's Blog -

Markdown 编辑器推荐

前言 近期著名 Markdown 编辑器 Typora 宣布收费了,起初感觉很难受,后来感慨之余也觉得算是合理,毕竟 Typora 用起来感觉是真的很良心,也在考虑是否买一份支持一下。 +

Markdown 编辑器推荐

前言 近期著名 Markdown 编辑器 Typora 宣布收费了,起初感觉很难受,后来感慨之余也觉得算是合理,毕竟 Typora 用起来感觉是真的很良心,也在考虑是否买一份支持一下。 已于2021/12/10购入,还是选择回归了 Typora 了哈哈哈 虽说左右分屏的设计可能更符合 Markdown 的初衷,但是像 Typora 这种所见即所得(WYSIWYG) 的书写体验确实是感觉习惯了就回不去了。 因此近期也搜集了 Markdown 编辑器作为 Typora 的替代品,在这里给大家分享一下。 @@ -15,8 +15,9 @@ 在我使用的一段时间内,他给我的感觉是,功能十分丰富的一个 Markdown 文件管理工具。如果你购买了他的同步服务,那你可以很轻松的在各平台同步你的 Markdown 文件夹,并且基于他强大的插件,可以很完成很多 Markdown 文件份外的事,例如待办清单、日历等等。 他虽没有所见即所得的模式,但是依靠其一款第三方插件,可以达成类似的效果,不过还是用起来不如 Typora 这种顺手。同时,它的各端同步如果不开启官方的服务,用起来还是挺麻烦的,经过我的一阵倒腾,我总结了如下几个方案: 使用第三方Git管理插件,可以定时推送文件夹中的内容到仓库,这样可以完成 linux 与 Windwos 平台的同步,只需要在某一方推送某一方拉取即可。而 Windows 平台与 iPad 平台的同步,可以借助 Apple 的 iCloud,Windows上有对应的客户端,这也是 Obsidian 官方支持的。不过在我使用的过程中我发现,这样异常的麻烦,使用 Git 来管理很可能会产生冲突,导致需要手动处理冲突,久而久之就会觉得很烦。 -使用自建云盘如 NextCloud + Obsidian,或者 Seafile + Obsidian。 这个是我觉得目前非常可行的一个方案,最近我也有在尝试 NextCloud,它的多端同步做的非常不错,依靠此可以在各个平台同步文件夹,加上 Obsidian 强悍的能力,是不错的组合!...

December 1, 2021 · 1 min · zzsqwq
© 2024 Zs's Blog +使用自建云盘如 NextCloud + Obsidian,或者 Seafile + Obsidian。 这个是我觉得目前非常可行的一个方案,最近我也有在尝试 NextCloud,它的多端同步做的非常不错,依靠此可以在各个平台同步文件夹,加上 Obsidian 强悍的能力,是不错的组合! +...

December 1, 2021 · 1 min · zzsqwq
+ PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/friends/index.html b/friends/index.html index 3e850833..79ac6659 100644 --- a/friends/index.html +++ b/friends/index.html @@ -8,6 +8,7 @@ pg999w https://blog.pg999w.top Jiacheng Lyu https://ljcheng.cc SiYun https://siyun916.github.io + Bowen https://www.tomcatdeng.cn 斯文孙 https://www.vhrise.com immortalqx https://immortalqx.github.io @@ -21,6 +22,7 @@ pg999w https://blog.pg999w.top Jiacheng Lyu https://ljcheng.cc SiYun https://siyun916.github.io + Bowen https://www.tomcatdeng.cn 斯文孙 https://www.vhrise.com immortalqx https://immortalqx.github.io @@ -34,12 +36,13 @@ pg999w https://blog.pg999w.top Jiacheng Lyu https://ljcheng.cc SiYun https://siyun916.github.io + Bowen https://www.tomcatdeng.cn 斯文孙 https://www.vhrise.com immortalqx https://immortalqx.github.io Kehan https://blog.kehan.xyz -Zhang Jiale https://zjlzjl.com">

Friends

To request a link, please make sure your blog has https enabled.

HuaDeity https://blog.huadeity.com

70loKirin https://qllokirin.github.io

Angine https://angine.tech

MurphyHou https://cosmicdusty.cc

Orangii https://orangii.cn

pg999w https://blog.pg999w.top

Jiacheng Lyu https://ljcheng.cc

SiYun https://siyun916.github.io

Bowen https://www.tomcatdeng.cn

斯文孙 https://www.vhrise.com

immortalqx https://immortalqx.github.io

Kehan https://blog.kehan.xyz

Zhang Jiale https://zjlzjl.com

© 2024 Zs's Blog +Zhang Jiale https://zjlzjl.com">

Friends

To request a link, please make sure your blog has https enabled.

HuaDeity https://blog.huadeity.com

70loKirin https://qllokirin.github.io

Angine https://angine.tech

MurphyHou https://cosmicdusty.cc

Orangii https://orangii.cn

pg999w https://blog.pg999w.top

Jiacheng Lyu https://ljcheng.cc

SiYun https://siyun916.github.io

Bowen https://www.tomcatdeng.cn

斯文孙 https://www.vhrise.com

immortalqx https://immortalqx.github.io

Kehan https://blog.kehan.xyz

Zhang Jiale https://zjlzjl.com

+ PaperMod | 鲁ICP备2020034310号
\ No newline at end of file diff --git a/index.html b/index.html index 92bc059b..bbbcdcbf 100644 --- a/index.html +++ b/index.html @@ -1,9 +1,9 @@ -Zs's Blog -
Profile avatar

zzsqwq

Do whatever you want.
© 2024 Zs's Blog +Zs's Blog +
Profile avatar

zzsqwq

Do whatever you want.
+ PaperMod | 鲁ICP备2020034310号
\ No newline at end of file diff --git a/index.json b/index.json index bb9137a0..26919967 100644 --- a/index.json +++ b/index.json @@ -1 +1 @@ -[{"content":"前言 在回望过去时,我们常感叹时间飞逝,我想这或许是因为过去发生的无数大小事情最终在脑海中留存的只有寥寥几件。因此,撰写年度总结这件事似乎变得格外有意义,它能帮助我们更充分地回味过去的一年。可能正是因为如此,现在各大 APP 似乎都很喜欢推出年度总结,例如网易云、QQ音乐、知乎、飞书、京东、美团、支付宝等。为此,我写下了这篇 2023 年度总结。\n仔细回味我这过去的一年,我想用几个关键词来概括:#消费升级、#数码科技、#大模型、#老友重逢。\n#消费升级:这一年是我消费升级的一年,尽管今年「消费降级」这个词似乎很火,但我似乎与大众走上了一条相反的道路。可能是因为我以往的消费水平本就不高,所以「降级」更是无从谈起。\n#数码科技:这一年我购入了一些新的数码设备,虽然数量不多,但每一件都还挺满意的。同时今年由于消费观念的转变,也支持了很多正版软件,因此今年在软件上的开销也不小。\n#大模型:这一年也是我被大模型深刻影响的一年。虽然去年 ChatGPT 就已经面世,但各种大模型热潮的真正兴起还是在今年。仅短短一年的时间,大模型就已经渗透到了我日常生活和工作的方方面面,无论是电脑上的生产力工具(HapiGo)、编程使用的 IDE(JetBrains CLion)、浏览网页使用的浏览器(Microsoft Edge)还是日常娱乐使用的流媒体软件(Bilibili),都有着大模型的加持,让我的生活和工作流效率倍增。\n#老友重逢:看完下面就知道了~\n下面,还是照例按月份盘点下发生的大小事:\n一月 这一个月包含了回家过年和返回深圳的往返之旅。在老家见了几个老同学,很开心。古人言人生四件快意的事 ——「久旱逢甘雨,他乡遇故知,洞房花烛夜,金榜挂名时」。虽然不是在「他乡」相遇,但仅是久别重逢就已足够令人欣喜。\n二月 二月和朋友二刷了《流浪地球2》,这可能是我第一部影院二刷的电影,感觉细节满满,二刷还是有很多没注意到的点。\n同时这一月 Microsoft 联合 OpenAI 推出了 ChatGPT 加持的 New Bing,刚出时感觉很震撼,参见这个知乎回答,真的像有感情一样,有点细思极恐的感觉。虽然后续 Microsoft 对其进行了「改善」让他更少的表述情感,导致它现在变得有些弱智,远远比不上 GPT4,但它之前的表示还是很让我印象深刻。同时我想也正是这种 ChatGPT 对现有设施的加持和增强让 ChatGPT 彻底出圈,也算是后续大模型浪潮兴起的起点了。\n同时二月家里还来了个新朋友 —— 波妞,是只公布偶猫(虽然一开始以为是母的)。虽然是朋友养的,当时偶尔寄养在这边。但怎么说我也是短暂的成为了拥有两只猫的人了,值得记录一下。\n二者同框 三月 三月购入了新的显示器 —— LG 27UP850N-W,很满意,虽然感觉 27 寸用来办公还是稍大。但我购入的时候价格是 2599,这才短短一年时间就降到了 1999,太不保值了!但也只能用「早买早享受,晚买享折扣」来安慰自己了。\n哦还有一个就是三月开始尝试着健身了,深圳好吃的太多了,一直在不停的变肥。因此在周围一个健身房办了年卡,虽然没有几个月这个健身房就跑路了\u0026hellip;不过这是后话了。\n加入新显示器后的桌面 四月 这个月入坑了《原神》,比较神奇的是几乎在同一时间也有个朋友 @HuaDeity 入坑。\n五月 五月似乎是相对平淡的一月,在继续社畜日常的同时开始写毕设了。\n六月 月初和朋友去海底捞过了生日,属于是 404 的「企业文化」了。然后终于把毕设给忙完了,返校进行了答辩,结果还算顺利。因为返校了也见了很多老朋友,舍友、基地的伙伴们、学弟们(是的应该是没有学妹),约了数不清次数的饭。\n基地的大伙聚会 七月 我正式本科毕业了。\n就像开头说的,回望过去总是很快。感觉开学和父母踏进工大校园的那一天还历历在目,转眼间就要毕业了。纵有万般不舍,但还是不得不和朋友们分别了,最后一晚大家一起在 KTV 合唱《朋友》的时候,忍不住泪奔。\n再见,工大 八月 相对平淡的一月,学弟来深圳参加夏令营,顺便过来找我玩,一起逛了腾讯大厦和华强北,看完感觉大厂平常的这些福利确实还是很不错的(不过确实加班严重)。\n九月 九月病了一场,还把同寝的大伙给传染了,虽然最后没查出来是什么病,既不是甲流乙流也不是新冠,但是跟新冠的症状很像。生病了才发现这种穿戴设备(例如 Apple Watch)还是蛮有用的,可以量化一些健康相关的数据,例如深度睡眠时间、心率变异性指数(HRV)、静息心率,通过这些可以稍微早一些发现自己身体存在的问题。\n一些软件上的体现,从左往右依次是 AutoSleep、压力自测、Apple Health 这月还规划了国庆假期游玩的路线,因此还从学长那里收了一个二手的 Nikon Z FC + NIKKOR 16-50mm 套机,同时还买了一颗长焦镜头 NIKKOR 50-250mm,不过国庆回来就把这颗镜头出掉了。凭心而论,相机体验还是很不错的,虽说只是个半画幅相机,但成像质量感觉还是要比目前的手机好一大截,在川西拿着它拍了很多照片,还发了条 小红书 记录。\nNikon Z FC(熊猫热靴版) 十月 国庆假期狠狠的去川西自驾游了,大概是我人生中第一次这么「酣畅淋漓」的旅游。见到了贡嘎雪山和雅拉雪山的日照金山,体验了在冷嘎措 4600 米海拔徒步的感觉,不虚此行!当然最重要的,还是有这么多伙伴一起。\n这个月还看了广受好评的、被安利了无数次、感觉身边人都看过的《进击的巨人》,确实好看!感觉立体机动装置这个设定还挺不错的,可以画出来很多很帅的镜头,就像是人均蜘蛛侠一样。\n太美丽啦,贡嘎 十一月 十一月去北京参加了奇绩创坛的2023秋季路演。同时也见了在北京的老同学们,又是「他乡遇故知」!这大概也算是第一次在北京游玩了。\n还有一个不得不提的点是这月换了新的 Mac,其实本来是想换 M3 的 Macbook Air 的,但是今年的发布会没有发布 Air 只发布了 Pro,实在有点等不及了。但是 Pro 的话、感觉今年 M3 和 M3 Pro 提升比较小,甚至 M3 Pro 有牙膏倒吸的情况,导致性价比较低。所以最终换了一个官翻的 M2 Max 芯片的 Macbook Pro 版本,预计可以服役很久了,虽然实在是不便宜,但也是真的好用!这应该是今年我最满意的一件数码产品了,Mac 真的很好用!\n同时也正是从这个月双十一开始倒腾很多软件,一个直接原因是 数码荔枝 双十一有很多正版软件打折。关于 macOS 上的软件还有一个 未完成的总结帖 ,希望新的一年可以填上这个坑。\n购买的一些 Lifetime 软件 十二月 这个月我想想,大概是见到了八个许久未见的朋友,我愿称之为最幸福的一月。\n月中见到了一位了许久未见的老同学,来深圳好久了,但这个月才第一次见。相约一起去爬了塘朗山,第一次在深圳爬山,选了个比较小的山,还蛮轻松的。后续还见了一位许久未见的学弟。\n月底一个好兄弟考完研之后来我们这边住了一周,然后在月底也一起参加了公司的团建和跨年,乐爷也来一起团建来着。这个元旦假期真的可以说是爽玩了。\n这个月还冲动之下换了新的手机,之前的 iPhone 13 更新到 iOS 17 以后真的是卡爆了,可能是因为 iPhone 13 是 4GB 内存的原因,导致这个杀后台和卡顿的问题变得格外突出。不过一个神奇点是,我这个用了近两年的手机居然还可以在官方抵扣 3300,感觉血赚,很保值。\n新年快乐! 总结 写完回望一年,欢乐时光似乎大多与老友重逢相伴。感觉是因为今年大伙很多都离开了学校、分散在了世界各地,无论去哪里出差都能遇到老同学,分隔许久再见总是令人格外开心,仿佛有说不完的话。我想说,谢谢朋友们,新的一年也要多多联系\u0026amp;见面!\n这一年「置办」了几个新的大件,LG 显示器、Nikon Z FC、Macbook Pro、 iPhone 15 Pro,购买数码产品令我心情愉悦。现在持有的消费观念就是喜欢就冲,在自己力所能及的范围内尽可能的支持正版,不吝啬在于兴趣爱好方面的消费。\n同时今年虽然入坑了《原神》,但是玩了半年左右,通关了剧情就退坑了,游戏还是很不错的,就是长草期有点过于无聊了。感觉自己目前除了对数码相关的东西还有些兴趣,对其他的貌似都很兴致缺缺的样子,不知道算是好事还是坏事。\n新一年的希冀 除了总结上一年,也对新的一年有一些希冀:\n在年末辞旧迎新之际,少数派开始了「放轻松」系列征文活动,看到了一篇参选文章:放轻松 | 累了就休息,放松一下没关系,感觉很不错。里面提到了很多观点,例如放过自己、关注当下等让我感触颇深。\n这一年似乎可能是因为 All in 创业的原因,似乎无时无刻都在觉得自己太菜了(当然也不只有这一个原因),无法「堪当大任」,总是不由自主的焦虑,非常浮躁。这个时间看到这个文章,可能正是提醒我新的一年要更加关注自己的内心、关注当下、放过自己,让自己不再那么浮躁,学会 Take it easy。当然,有适当的压力可能也是好事,希望新的一年也可以多读书、多看报、少吃零食多睡觉,多多提升自己,最好也让自己更 E 一些,无限进步。\n关注当下大意就是:喝一杯茶就认真去品味这杯茶,总想着喝完茶之后的事情,这茶也就饮之无味,属于你的饮茶时间也就被偷走了。夜晚想着明天的事情难以入眠,那就关注躺在床上的自己,此刻的你不可能爬起来去做明天的事,想到这里便可以安心入睡;疼痛的时候就去感知疼痛,去关照你身体此刻的感受,不去想别的,它反而就没那么痛了。\n原来看问题还有这种角度?长久以来我做事确实都是魂不附体,思绪永远快于肉体,刷着牙想着等下要洗脸,洗着脸想着马上要洗澡,洗着澡,魂早飘到一会躺床上刷手机用什么姿势?总是很急,急来急去俨然一副空壳子,对生活的细节毫无感知,其实就是浮躁,而关注当下就是浮躁的解药,也是我在病前期意外抓到的一根救命稻草。听人劝吃饱饭,得益于此书,我的心态开始转变,关注当下进而去关照自身,帮助自己真正放松了下来。\n再就是三月份提到的办了年卡的健身房,六月份跑路了。在多次协调无果、12315 也不起作用的情况下,尝试起诉了健身房,第一次尝试当原告,最终在 12 月末成功立案,希望新的一年可以起诉成功,到时候可以总结一下发个经验帖供大家参考。 终于立案成功了,太不容易了。 希望新的一年能多拿着手机、相机出去走走。做年终总结的时候深感照片和文字记录的重要性。如果没有照片、没有朋友圈的一些文字,我可能根本想不起来那个月、那一天发生了什么。但是有了照片的帮助,我瞬间就能回忆起来我当时拍这张照片时的心情和场景,籍此前前后后的事情也能够串起来。\n照片不仅可以「冻结」那一瞬间,也可以「存储」一段记忆。\n感谢 Apple Photos 的时间线整理助我完成这篇文章 ","permalink":"https://blog.zzsqwq.cn/posts/summary-2023/","summary":"前言 在回望过去时,我们常感叹时间飞逝,我想这或许是因为过去发生的无数大小事情最终在脑海中留存的只有寥寥几件。因此,撰写年度总结这件事似乎变得格外有意义,它能帮助我们更充分地回味过去的一年。可能正是因为如此,现在各大 APP 似乎都很喜欢推出年度总结,例如网易云、QQ音乐、知乎、飞书、京东、美团、支付宝等。为此,我写下了这篇 2023 年度总结。\n仔细回味我这过去的一年,我想用几个关键词来概括:#消费升级、#数码科技、#大模型、#老友重逢。\n#消费升级:这一年是我消费升级的一年,尽管今年「消费降级」这个词似乎很火,但我似乎与大众走上了一条相反的道路。可能是因为我以往的消费水平本就不高,所以「降级」更是无从谈起。\n#数码科技:这一年我购入了一些新的数码设备,虽然数量不多,但每一件都还挺满意的。同时今年由于消费观念的转变,也支持了很多正版软件,因此今年在软件上的开销也不小。\n#大模型:这一年也是我被大模型深刻影响的一年。虽然去年 ChatGPT 就已经面世,但各种大模型热潮的真正兴起还是在今年。仅短短一年的时间,大模型就已经渗透到了我日常生活和工作的方方面面,无论是电脑上的生产力工具(HapiGo)、编程使用的 IDE(JetBrains CLion)、浏览网页使用的浏览器(Microsoft Edge)还是日常娱乐使用的流媒体软件(Bilibili),都有着大模型的加持,让我的生活和工作流效率倍增。\n#老友重逢:看完下面就知道了~\n下面,还是照例按月份盘点下发生的大小事:\n一月 这一个月包含了回家过年和返回深圳的往返之旅。在老家见了几个老同学,很开心。古人言人生四件快意的事 ——「久旱逢甘雨,他乡遇故知,洞房花烛夜,金榜挂名时」。虽然不是在「他乡」相遇,但仅是久别重逢就已足够令人欣喜。\n二月 二月和朋友二刷了《流浪地球2》,这可能是我第一部影院二刷的电影,感觉细节满满,二刷还是有很多没注意到的点。\n同时这一月 Microsoft 联合 OpenAI 推出了 ChatGPT 加持的 New Bing,刚出时感觉很震撼,参见这个知乎回答,真的像有感情一样,有点细思极恐的感觉。虽然后续 Microsoft 对其进行了「改善」让他更少的表述情感,导致它现在变得有些弱智,远远比不上 GPT4,但它之前的表示还是很让我印象深刻。同时我想也正是这种 ChatGPT 对现有设施的加持和增强让 ChatGPT 彻底出圈,也算是后续大模型浪潮兴起的起点了。\n同时二月家里还来了个新朋友 —— 波妞,是只公布偶猫(虽然一开始以为是母的)。虽然是朋友养的,当时偶尔寄养在这边。但怎么说我也是短暂的成为了拥有两只猫的人了,值得记录一下。\n二者同框 三月 三月购入了新的显示器 —— LG 27UP850N-W,很满意,虽然感觉 27 寸用来办公还是稍大。但我购入的时候价格是 2599,这才短短一年时间就降到了 1999,太不保值了!但也只能用「早买早享受,晚买享折扣」来安慰自己了。\n哦还有一个就是三月开始尝试着健身了,深圳好吃的太多了,一直在不停的变肥。因此在周围一个健身房办了年卡,虽然没有几个月这个健身房就跑路了\u0026hellip;不过这是后话了。\n加入新显示器后的桌面 四月 这个月入坑了《原神》,比较神奇的是几乎在同一时间也有个朋友 @HuaDeity 入坑。\n五月 五月似乎是相对平淡的一月,在继续社畜日常的同时开始写毕设了。\n六月 月初和朋友去海底捞过了生日,属于是 404 的「企业文化」了。然后终于把毕设给忙完了,返校进行了答辩,结果还算顺利。因为返校了也见了很多老朋友,舍友、基地的伙伴们、学弟们(是的应该是没有学妹),约了数不清次数的饭。\n基地的大伙聚会 七月 我正式本科毕业了。\n就像开头说的,回望过去总是很快。感觉开学和父母踏进工大校园的那一天还历历在目,转眼间就要毕业了。纵有万般不舍,但还是不得不和朋友们分别了,最后一晚大家一起在 KTV 合唱《朋友》的时候,忍不住泪奔。\n再见,工大 八月 相对平淡的一月,学弟来深圳参加夏令营,顺便过来找我玩,一起逛了腾讯大厦和华强北,看完感觉大厂平常的这些福利确实还是很不错的(不过确实加班严重)。","title":"2023 年度总结"},{"content":"平时很喜欢倒腾各种 Apple 平台的各种软件,所以体验了很多 iOS/iPadOS/macOS 上的软件,所以计划汇总一下自己的一些简短的使用体验和评价等,希望能在大家后续选择软件的时候起到一些参考和帮助。\n由于软件可能较多,不能一次性写完。同时,因为我也在不断体验新的软件,有新的感受,因此这篇博客应该是持续更新的,欢迎常来看看。\n速览表 App 名称 简短描述 功能限制 订阅形式 价格 购入时间 购入渠道 同类型产品 AIDente 电池电量管理 有免费使用功能,但有共功能需要收费 买断 Free Battery, BatFi AdGuard 广告拦截软件 AltTab 增强 macOS App 切换 Command-Tab Plus, Contexts,HyperSwitch, Bartender 5 Menubar 管理 Bob 大概是最好用翻译软件 EasyDict BuhoCleaner 垃圾清理器/软件卸载器 CleanMyMac, Sensei Clash X / Clash X Pro 代理 Surge, Stash CleanBuddy 键盘锁定清理 Cleaner CleanShot X 大概最好用的截图软件 Cleaner 键盘屏幕锁定清理 CleanBuddy Dash 文档利器 Dato Menubar 日历软件 Fantastical, Itsycal DevUtils 开发小工具合集 Downie 4 各类视频下载器 VDown HapiGo 启动器 Alfred, Raycast HazeOver 生产力工具,突出重点 Hazel 自动清理集合 JetBrains 全家桶 包含 Clion/IDEA 等 VSCode, Eclipse Lunar 显示器管理 MonitorControl, DisplayBuddy, Better Display Maccy 开源免费的剪切板管理工具 Paste, PasteNow, PastePal Manico 快速启动器 Command-Tab Plus MimeStram Gmail 客户端 MonitorControl 开源显示器管理,很够用 Lunar, DisplayBuddy, Better Display NetNewsWire 全平台 RSS 阅读器 Obsidian 笔记软件 Omnivore 稍后读软件 Pocket, MarkMark, Only Switch 一键完成各种任务 One Switch OpenImageOptim 图片压缩 TinyPNG OrbStack 容器管理,平替 Docker Desktop Docker Desktop, Podman, lima, colima Permute 3 图片/视频格式转换工具,类似于格式工厂 HandBrake, Omni Converter, Video Converter X2 Pixea 图片查看器 Viso, Picsee Pixelmator Pro 图片编辑器,80% 平替 PhotoShop Adobe PhotoShop, Darkroom, Photomator, Capture One, Adobe LightRoom Classic PopClip 划词增强 Proxyman 大概是舒服的抓包工具,略贵 Charles Rectangle 分屏软件 Magnet, Swish Swish 触控板手势增强 Stats Menubar 状态监控 iStats Menu, Sensei Subscriptions 订阅管理 Pandora on iOS Surge 代理工具 Clash X, Stash TinyPNG 图片压缩 OpenImageOptim Typora Markdown 文本编辑器 Obsidian Upscayl AI 图片超分 AI Photo Enhancer by Pictura, Pixelmator Pro Viso 6 图片查看器 Pixea, Xee Zotero 文献管理,就是界面一般 coconutBattery iPhone/iPad/Mac 电池信息查看 iRightMenu 右键增强 超级右键, iMouse, iTerm2 终端模拟器 Alacritty, Warp, Wezterm, Terminal 详细信息 AIDente 介绍:可以限制充电上限,据称电池电量维持在 70-80% 是比较健康的,不适宜过高。\n目前是否在用:是\n收费形式:139/3设备\n评价:好用,界面也挺好看的\n同类型产品:Battery, BatFi\n软件快照:\nTODO\u0026hellip;\n","permalink":"https://blog.zzsqwq.cn/posts/macos-app-use-experience-record/","summary":"平时很喜欢倒腾各种 Apple 平台的各种软件,所以体验了很多 iOS/iPadOS/macOS 上的软件,所以计划汇总一下自己的一些简短的使用体验和评价等,希望能在大家后续选择软件的时候起到一些参考和帮助。\n由于软件可能较多,不能一次性写完。同时,因为我也在不断体验新的软件,有新的感受,因此这篇博客应该是持续更新的,欢迎常来看看。\n速览表 App 名称 简短描述 功能限制 订阅形式 价格 购入时间 购入渠道 同类型产品 AIDente 电池电量管理 有免费使用功能,但有共功能需要收费 买断 Free Battery, BatFi AdGuard 广告拦截软件 AltTab 增强 macOS App 切换 Command-Tab Plus, Contexts,HyperSwitch, Bartender 5 Menubar 管理 Bob 大概是最好用翻译软件 EasyDict BuhoCleaner 垃圾清理器/软件卸载器 CleanMyMac, Sensei Clash X / Clash X Pro 代理 Surge, Stash CleanBuddy 键盘锁定清理 Cleaner CleanShot X 大概最好用的截图软件 Cleaner 键盘屏幕锁定清理 CleanBuddy Dash 文档利器 Dato Menubar 日历软件 Fantastical, Itsycal DevUtils 开发小工具合集 Downie 4 各类视频下载器 VDown HapiGo 启动器 Alfred, Raycast HazeOver 生产力工具,突出重点 Hazel 自动清理集合 JetBrains 全家桶 包含 Clion/IDEA 等 VSCode, Eclipse Lunar 显示器管理 MonitorControl, DisplayBuddy, Better Display Maccy 开源免费的剪切板管理工具 Paste, PasteNow, PastePal Manico 快速启动器 Command-Tab Plus MimeStram Gmail 客户端 MonitorControl 开源显示器管理,很够用 Lunar, DisplayBuddy, Better Display NetNewsWire 全平台 RSS 阅读器 Obsidian 笔记软件 Omnivore 稍后读软件 Pocket, MarkMark, Only Switch 一键完成各种任务 One Switch OpenImageOptim 图片压缩 TinyPNG OrbStack 容器管理,平替 Docker Desktop Docker Desktop, Podman, lima, colima Permute 3 图片/视频格式转换工具,类似于格式工厂 HandBrake, Omni Converter, Video Converter X2 Pixea 图片查看器 Viso, Picsee Pixelmator Pro 图片编辑器,80% 平替 PhotoShop Adobe PhotoShop, Darkroom, Photomator, Capture One, Adobe LightRoom Classic PopClip 划词增强 Proxyman 大概是舒服的抓包工具,略贵 Charles Rectangle 分屏软件 Magnet, Swish Swish 触控板手势增强 Stats Menubar 状态监控 iStats Menu, Sensei Subscriptions 订阅管理 Pandora on iOS Surge 代理工具 Clash X, Stash TinyPNG 图片压缩 OpenImageOptim Typora Markdown 文本编辑器 Obsidian Upscayl AI 图片超分 AI Photo Enhancer by Pictura, Pixelmator Pro Viso 6 图片查看器 Pixea, Xee Zotero 文献管理,就是界面一般 coconutBattery iPhone/iPad/Mac 电池信息查看 iRightMenu 右键增强 超级右键, iMouse, iTerm2 终端模拟器 Alacritty, Warp, Wezterm, Terminal 详细信息 AIDente 介绍:可以限制充电上限,据称电池电量维持在 70-80% 是比较健康的,不适宜过高。","title":"App 使用体会记录 - macOS 篇"},{"content":"After seeing Duel of the Defaults and App Defaults, I\u0026rsquo;d like to share here some of my app defaults at the end of 2023.\nSince I am from China, some apps may not be suitable to everyone, such as WeChat, NeteaseMusic, etc.\nThe software built-in on iPhone or Mac will have the .app extension.\n📨 Mail Client:Gmail, Mail.app 📮 Mail Server:Gmail 📝 Notes:Obsidian, Typora, Notes.app ✅ To-Do:Reminders.app 📷 iPhone Photo Shooting: Camera.app 📸 Photo Shooting: Nikon ZFC, iPhone 13 🟦 Photo Management \u0026amp; Editing: Photos.app, Capture One, Pixelmator Pro 📆 Calendar: Dato, Calendar.app 📁 Cloud File Storage: iCloud Drive 📖 RSS Client: NetNewsWire 📖 RSS Server: FreshRSS with RSSHub 🙍🏻‍♂️ Contacts: Contacts.app 🌐 Browser: Microsoft Edge 💬 Chat: Telegram, WeChat(Not recommended, unless absolutely necessary.), iMeesage.app? 🔖 Bookmarks: Microsoft Edge 📑 Read It Later: Omnivore 📜 Word Processing: Lark Docs, Microsoft 365 📈 Spreadsheets: N/A 📊 Presentations: Microsoft PowerPoint 🛒 Shopping Lists: N/A 🍴 Meal Planning: N/A 💰 Budgeting and Personal Finance: iCost, Subscriptions 📰 News: Channels on Telegram, RSS, Web 🎵 Music: NeteaseMusic, Music.app 🎤 Podcasts: N/A 🔐 Password Management: iCloud Keychain 🧑‍💻 Code Editor: JetBrains Series, VS Code, Vim 🪄 Launcher: HapiGo 😘 Blog Platform: Hugo ","permalink":"https://blog.zzsqwq.cn/posts/default-apps-f2023/","summary":"After seeing Duel of the Defaults and App Defaults, I\u0026rsquo;d like to share here some of my app defaults at the end of 2023.\nSince I am from China, some apps may not be suitable to everyone, such as WeChat, NeteaseMusic, etc.\nThe software built-in on iPhone or Mac will have the .app extension.\n📨 Mail Client:Gmail, Mail.app 📮 Mail Server:Gmail 📝 Notes:Obsidian, Typora, Notes.app ✅ To-Do:Reminders.app 📷 iPhone Photo Shooting: Camera.","title":"My App Defaults - 2023 Fall"},{"content":"TL;DR 我在 2023.11.07 凌晨被 GitHub 封禁了账号,GitHub 账号被 suspended 后会在 GitHub 上完全除名(只有自建创建的组织不会消失)。\n被封禁后我首先通过 Google 查找了相关的文章。\n根据博主 @phith0n 的指引首先通过 API:https://api.github.com/users/[username]/starred 备份了自己 star 过的项目,同时通过 Can\u0026rsquo;t sign-in form 来在无法登陆的情况下发起 GitHub Support 工单来询问/请求解封/询问原因等,一般在两天内收到了回复。最终账号顺利恢复。\n我此次被封禁的原因是由于管理的组织内部有成员被盗号,在组织内创建了违法仓库,因此管理员和被盗号的成员都被封禁了,但后续都被解除了封禁。同时也有可能因为创建违反 DMCA 条款 的仓库、fork 违反 DMCA 条款的仓库、贩卖学生/教师教育包等原因被封禁。\n背景 大约在 2023.11.07 凌晨 00:30 左右,在 GitHub 上看到了一个不错的项目想要 Star,被提示没有登陆。当时我还在想:“怎么这次 session 过期的这么快?” 就当我边疑惑边重新登录后,突然收到了下图的提示我的账号「Account suspended」:\n确认无法登录后,查看邮箱没有任何相关通知。同时我查看了其他内容是否还存在,最后综合表现如下:\n没有任何邮件/信息通知被封禁及更加具体的封禁原因,只告诉违反了 ToS 个人页面(https://github.com/zzsqwq)无法访问,访问显示 404 提的相关 Issue 全部被删除(隐藏),无法找到 个人创建的所有项目,访问全部 404,也无法拉取 自己参与的项目,被除名 自己加入的组织,被除名 自己创建的组织,访问 404 简单说就是跟这个账号从来没存在过一样,除了仍可以登陆,但是显示 suspended。接下来开始尝试找办法恢复。\n恢复经过 试图查找封禁原因 首先看提示上显示违反了 Github Terms of Service,快速的看了一眼 ToS 没发现我有什么明显违规的地方。\n通过搜索引擎搜索 「Github 账号 suspended」相关信息,找到了两个比较强相关的帖子:\n分享下我 GitHub 被封的经历 GitHub 无预警突然封号 其中第一个是因为 fork 了违反 DMCA 的仓库而被封禁,第二个看起来是因为购买了违规的教师包而被封禁。\n首先我是使用正规身份申请的学生教育包,第二个博主的情况可以排除。关于第一个,我仔细想了一下我过去几天的行为:由于过去几天大量 Clash 相关仓库被删除和停止维护,我 fork 了五个与 Clash 有关的仓库,但是理论上 Clash 相关的仓库是不存在违反 DMCA 这一说的,因此第一个博主的情况也可以被排除。\n同时第一个博主提到,我们可以通过 API:https://api.github.com/users/[username]/starred 来找到之前 star 过的仓库,我试了一下确实,遂备份了一份 json 文件。同时查看了关于关注和被关注相关的 API:https://api.github.com/users/[username]/followers 和 https://api.github.com/users/[username]/following,均为空,看来只能找到 star 过的仓库。\n但是有一个比较神奇的点是:第一个博主提到:「但是我创建的 Group 还是好的,没有受影响。」。但是在我账号上,我唯一创建的组织 nwpusr-vision-team 访问时也显示 404,和这个博主的情况不符,但暂时不明是什么原因。\n联系 GitHub 寻求帮助 于是经过一系列查找,我在 GitHub 上使用新的邮箱注册了一个新的账号(旧的邮箱无法注册新账号),并通过 Github Support 界面发起了一个工单说明我的情况。当时是大概凌晨一点多提交的工单,2023.11.07 下午五点多收到了回复,告知我必须使用原邮箱来联系 Github Support 支持才可以处理我的原账号,可以通过 Can\u0026rsquo;t sign-in form 来在无法登录的情况下提交相关工单(但是似乎直接给 Github 发邮件也可以成功创建工单,不确定)。\n同时在这一天的下午,我也得知了有另外两位认识的同学也跟我一模一样在没有任何通知的情况下被封禁,具体的表现也和我一样。而我们之间的联系就是我们同属于一个组织:nwpusr-vision-team 。至此我推断出了一个大致的原因 —— 我创建的这个 Github 组织出了问题,导致我们三个都受到了牵连,但是具体的什么原因还未知,因为这个组织从我创建后几乎就没用过,里面也只有一个 README 一样的仓库,实在是想不明白有什么封禁的理由。\n一直等到第三天即 2023.11.09 的早上9点多,我收到了一封关于密码被重置的邮件,于是我查看了我的 GitHub个人主页 发现已经不再是 404 了。于是我按照提示重置了密码后,顺利的登录了 Github,同时也收到了 GitHub Support 的回复,全文如下:\nHello Zhan,\nThanks for contacting GitHub Support on the email address associated with your zzsqwq account.\nWe recently detected suspicious activity on your account and applied restrictions out of an abundance of caution while we investigated what took place.\nTo secure your account, we have forced a password reset. If you haven’t already, please reset your password.\nI’ve sent you a separate email just now with a link to complete this process. Please note that the link will expire in 24 hours. Alternatively, visit the following to request a password reset token:\nhttps://github.com/password_reset\nTo protect your account from unauthorized access, please choose a strong and unique password for your account. We have a help article with some recommendations here:\nhttps://docs.github.com/authentication/keeping-your-account-and-data-secure/creating-a-strong-password\nAs an added precaution, we also recommend reviewing your security log and reverting any changes you don’t recognize.\nFor more information, read Reviewing your security log in the GitHub Docs.\nAdditionally, we also recommend double checking your stars and removing any that weren’t added by you:\nhttps://github.com/stars\nI hope this clears things up. If you have any further questions, please let us know.\nKind regards, Pip, GitHub Support\n大意就是 GitHub 最近在我的帐户上检测到可疑活动,并在调查发生的事情的同时出于谨慎考虑对我的账号施加了限制。现在已经把我的账号解封了,但是需要重置密码后才可以继续使用。\n后续处理 登录账号后,我发现组织 nwpusr-vision-team 仍存在限制,提示如下:\n由于被对外隐藏了,因此我自己可以访问这个组织,但是如果不登录账号查看这个组织仍是 404 的。\n通过对组织进行查看,发现组织内多了一个新的仓库,并且是违规仓库,是 fork 了一个 仓库 并更新了 README 更新成违规信息。\n这下我大概推测出了封号原因:首先下图是我们目前仓库成员图,红框内的是这次被封禁的人,从上到下依次是被盗号且创建违法仓库的同学、另一位管理员同学和我。应该由于那位同学被盗号并且在组织内创建了违法仓库,但是身为管理员的我们两个人在有管理权的情况下没有及时将仓库删除,因此 GitHub 认为我们三个人都可能账号存在风险,因此一起被禁了。随后进一步的调查发现这三个账号都已经没什么异常,因此就直接解除了封禁。\n随后我将组织内的违法仓库删除并反馈给 Github Support 后,组织状态也恢复了正常。\n随后我又就被封号原因这个问题,和 Github Support 人员展开了一些沟通,但是他们只是一直在说「GitHub 在我的帐户上检测到可疑活动,并在调查发生的事情的同时出于谨慎考虑对我的账号施加了限制,由于这个过程是他们检测工具自动进行的,恕他们无法告知更准确的原因」,最后仍是无法得知我推断的是否正确,但是应该除此之外没什么其他的原因了,由于我 GitHub 开启了 2FA 同时没泄露任何 token,理论上不会被有被异地登陆的可能。\nOur security team has recently been investigating suspicious activity and account hijacking, and we were concerned that your account may have been affected. Out of an abundance of caution, restrictions were placed on your account as part of our attempts to combat this campaign.\nWe use a number of detection methods to find abuse on GitHub, but I’m afraid I’m not at liberty to discuss our internal tooling.\n后记 整件事情看下来其实 GitHub 的处理有点离谱,仅仅是检测到账号可能存在异常活动,就在没有任何通知且不告知详细缘由的情况下封禁了账号,同时无法访问任何仓库/Issue,目前来看恢复账号也需要个至少两天,可能会耽误很多事情。\n我也就这件事情进行了反馈:\nLastly, I believe the way GitHub officially handled this situation was quite unreasonable. Our accounts were banned without any email notification, making it impossible to access repos, followers, following, stars, issues (all showing 404), and without stating a specific reason. For instance, as mentioned in the previous reply: \u0026ldquo;We recently detected suspicious activity on your account and applied restrictions out of an abundance of caution while we investigated what took place.\u0026rdquo; I think if you were to conduct an investigation, you could consider first imposing restrictions on the account (such as only allowing the repository to be pulled without any write operations on the account/repository) and notify us by email: \u0026ldquo;We have detected unusual activity and have restricted your account for safety reasons.\u0026rdquo; This would seem more reasonable and wouldn\u0026rsquo;t leave us confused. Please seriously consider the workflow for the future; this will make everyone love GitHub more. Thank you!\n他们的一些回复如下(分多封邮件进行交流,不同邮件间使用分割线分割):\nThanks for your reply and your feedback, I appreciate you taking the time to share it with me and I will make sure to share it with the relevant team.\nWe restricted your account as we had reasons to believe it may have been compromised in the aforementioned campaign. However, in your specific case, further review suggests that your personal account was unlikely to have been affected. I do apologize for the inconvenience, but hope you understand our need to prioritize account security.\nI understand that having your account restricted unexpectedly can be a frustrating experience, and I appreciate your feedback on receiving notification. I have shared your feedback internally.\n希望 GitHub 后续可以改进这个流程。\nPs:这次导致封号的违规仓库居然还是 fork 的 RoboRTS ,就连这个都跟 RM 有关,有点离谱。\n","permalink":"https://blog.zzsqwq.cn/posts/github-suspended-for-no-reason/","summary":"TL;DR 我在 2023.11.07 凌晨被 GitHub 封禁了账号,GitHub 账号被 suspended 后会在 GitHub 上完全除名(只有自建创建的组织不会消失)。\n被封禁后我首先通过 Google 查找了相关的文章。\n根据博主 @phith0n 的指引首先通过 API:https://api.github.com/users/[username]/starred 备份了自己 star 过的项目,同时通过 Can\u0026rsquo;t sign-in form 来在无法登陆的情况下发起 GitHub Support 工单来询问/请求解封/询问原因等,一般在两天内收到了回复。最终账号顺利恢复。\n我此次被封禁的原因是由于管理的组织内部有成员被盗号,在组织内创建了违法仓库,因此管理员和被盗号的成员都被封禁了,但后续都被解除了封禁。同时也有可能因为创建违反 DMCA 条款 的仓库、fork 违反 DMCA 条款的仓库、贩卖学生/教师教育包等原因被封禁。\n背景 大约在 2023.11.07 凌晨 00:30 左右,在 GitHub 上看到了一个不错的项目想要 Star,被提示没有登陆。当时我还在想:“怎么这次 session 过期的这么快?” 就当我边疑惑边重新登录后,突然收到了下图的提示我的账号「Account suspended」:\n确认无法登录后,查看邮箱没有任何相关通知。同时我查看了其他内容是否还存在,最后综合表现如下:\n没有任何邮件/信息通知被封禁及更加具体的封禁原因,只告诉违反了 ToS 个人页面(https://github.com/zzsqwq)无法访问,访问显示 404 提的相关 Issue 全部被删除(隐藏),无法找到 个人创建的所有项目,访问全部 404,也无法拉取 自己参与的项目,被除名 自己加入的组织,被除名 自己创建的组织,访问 404 简单说就是跟这个账号从来没存在过一样,除了仍可以登陆,但是显示 suspended。接下来开始尝试找办法恢复。\n恢复经过 试图查找封禁原因 首先看提示上显示违反了 Github Terms of Service,快速的看了一眼 ToS 没发现我有什么明显违规的地方。","title":"记一次 GitHub 账号突然被 suspended 的经历"},{"content":"TL;DR 本文旨在结合一系列事实总结拼多多过去的一系列恶心行为,包括不限于\n虚假宣传 砍一刀套路多 拉人助力 铺天盖地的广告 利用漏洞 希望大家抵制拼多多这种无良平台,非必要不使用拼多多。\n前言 最近看了很多拼多多令人反感的操作以及看了很多拼多多的软广,如 拼多多,让谁不爽,看到这么一个无良平台逐渐壮大实在是令人恼火,因此我觉得有必要写一篇文章来总结一下拼多多各种恶心人的操作来让大家了解这个无良平台,来看看他到底为什么让人不爽,并呼吁大家可以联合抵制这个平台。\n本文会尽量客观理性,陈述已发生的事实而不是自己的观点,同时因为我不是商家,也不是拼多多的员工,本文只是作为用户角度评判。除了对用户方面的恶心行为,还有对员工及商家的压榨,这个后面有时间再写。欢迎大家补充、批评、指正。\n一、虚假宣传 首先需要提到的就是拼多多的虚假宣传,主要是广告,相信大家都看到过,例如「为什么这些 Switch 游戏机只买 9.9 元都没人买,全部砸了算了」这种开头的,或者「你有 iPhone 13 吗,没有就打开拼多多抢一台」。铺天盖地的,无论是你看视频、还是刷QQ空间,还是刷朋友圈,总是能碰到这种广告,无非就是诱惑你点击下载拼多多,但是打开后却发现广告中说的点击就送、无门槛拿根本都是无稽之谈,要不就是限量两个,邀请最多的人才能领。下面是这类视频的合集,大家可能看到的时候都觉得尬和乐,但是却很少有人认识到这是虚假宣传,违规行为。\n根据百度百科对于虚假宣传的定义:\n虚假宣传是指在商业活动中经营者利用广告或其他方法对商品或者服务做出与实际内容不相符的虚假信息,导致客户或消费者误解的行为。\n这拼多多应该确实是符合的吧?虽然很多只是下载了 App 但是没有产生消费行为,但也可以归入其中。\n二、砍一刀套路多 套路多是指,经过第一步的虚假宣传,让你下载了 App,你以为可以很轻松的拿到免单的商品,但实际他会给你放一堆的限制,就像十年前的页游,一堆过场动画,什么「你是砍价第一名」、「还差 0.01 即可砍成功」,但你一旦继续深入,你就会发现这是个无底洞,0.01 后面是 0.001,0.001 后面是 0.0001,0.0001 后面怕你看数字太小生气,他就会让你集几万个金币或者一些其他的东西,十万个金币兑换 0.001,这样无限循环,想砍成实在难如登天。\n拼多多曾公开表示1:\n近日,“拼多多砍价,但始终差0.9%”话题受到广泛关注,去年3月,上海律师刘宇航参加了拼多多的“砍价免费拿”活动后,经多人砍价还是0.9%,在质疑数据有问题后,刘以使用虚假数据隐瞒规则已构成欺诈为由,向法院递交了起诉材料。在刘宇航随后释出的文件中得知,拼多多称是“因页面显示百分比位数有限,所以他们把一个至少小数点后有6位数以上的百分比,省略显示为0.9%,砍价页面显示的0.9%不是0.9%,而是0.9996427%。”\n当然这里也有砍成功的,不过是分价位的,你砍 100 元的红包,可能拉个七八个人就成功,如果都是新用户可能会更少,如果是砍 Switch、手机这种大件,需要砍的次数则就更多。当然砍 100 元的红包砍的多了,积累的价钱上去了,他也不会让你持续的薅,难度也是累加的。一个典型的案例可以看 超级小桀 之前的视频,如下:\n上面这个视频简单概括一下就是,小桀在直播间突发奇想带水友一起砍一部 IQOO 手机,前期很长的过场动画都在提示你,马上可以直接拿到,进度已经到达 0.00%,但是还是需要收集 10 多个金币,邀请两三个人即可,后来小桀把二维码分享出来,非常多的水友扫码砍,后来导致二维码提示被封禁,小桀又把链接分享给了群里的水友,当时在线的水友不完全统计 6-7W,至少有上千人参与,但最终也没有让那 10 多个金币归零,打电话给客服询问,客服给出理由如下:\n每个人砍都是概率砍成功,可能 100 人砍有 50 个人、80 个人砍成功,不是 100% 成功。 像这么多人砍价,系统检测到会封禁。 那我就有点疑问了,你这个东西本来就需要邀请很多人砍价才能成功,但是你人一多又要封禁,那么不邀请这么多人砍价,那么怎么成功呢?真的是「解释权归拼多多所有」。\n据小桀自己回应,直到3月17号下午2点40分左右下播,也没有砍成功,但是突然在4点40分左右莫名其妙的成功了,赠送了一张无门槛购物券可以下单此手机,随后客服回应:砍价不成功不属实,已经发放「特制」优惠券。这一通操作,实在是闻所未闻,谁也能看出来是事态发展到不可预料的地步搞了个东西出来封口的。\n实在是太像诈骗、传销了,即使这样广泛的虚假宣传,到现在也没有被整治,也还是随处可见。\n附小桀对这件事情的声明:\n三、拉人助力 拼多多最特色的行为,应该就是这个拉人助力,可能算是拉人助力的始祖了,如今算是各个软件的标配了,美团、饿了么、携程旅行、智行中也都随处可见。好处显而易见,可以提高自己活动的参与率、提高 App 的下载率、提高品牌知名度、提高用户粘性。\n具体的规则就是加速某件任务进程,免单某一件物品、领取某个红包、浇灌某个植物,你都需要「拉人助力」。顾名思义就是要分享这个链接或者二维码给他人,让他来点击助力。\n这会迫使身边的亲戚、朋友、家人都会向你发送链接助力,如果大家都用拼多多,那还好,你助力我我助力你,皆大欢喜。而如果你不用拼多多,甚至可能因为拼多多垃圾广告多,App 臃肿、漠视用户隐私等问题反感厌恶拼多多,可能会想要拒绝对方,但是直接拒绝大家两方都不好看,可能会说个客气话:「抱歉,我没下拼多多」。你可能以为可以通过这句话逃过一劫,而你没想到,拼多多会区分新用户和老用户,新用户助力的多,老用户助力的少,长时间不用的人助力也会要比那些常用者多一些。对方听到这个更开心了,因为你可以帮他加快更多的进度。这时候你可能只能不情愿的下载助力,或者和对方直说,那可能就会让两边都闹的不愉快,对方可能觉得:「只是个简单的助力而已,有什么好计较的?下载以后删掉不就好了。」,而你可能不这么认为,就会让原来稳固的关系出现裂隙,让这个社会的人际关系变得更加的脆弱,让人与人之间的交心程度变得越来越低。\n甚至更别说那种在路边突然拦住你让你帮忙助力的人,虽然我没遇到过,但是听很多人说遇到过,想想就令人恶心。\n四、铺天盖地的广告 不知从什么时候开始,拼多多的广告就到处都是了,远多于其他产品及平台的广告。\n广告分不同的类型以及投放方式:\n对于秒杀、拉人头类的广告,多出现在各种订阅号、QQ空间、小程序、小游戏广告中,内容就是上面提到的虚假宣传,例如什么「现在点击下方链接下载拼多多,即可立即 9.9 元秒杀 Switch 游戏机」。 对于百亿补贴类型的广告,多出现在 Bilibili 以及微信公众号(可能还有抖音等位置,因为我不使用,故不得而知),每次看各种UP主视频的,就会突然说起来买什么东西太贵了或者什么东西太贵了,就开始推荐拼多多的百亿补贴。除此以外,还会几乎每周固定的一次的集体刷屏,超多UP主一起在动态发,超多公众号一起发,标题都是如「苹果又跌破历史新低」这种。 这个可能是合法的,只是这种过量的宣发我认为很令人不适,容易引起反感。\n五、利用漏洞 认可白帽黑客价值、走进安全社区,打造安全团队,借助黑客视角提升自身安全能力,这已经成为了行业最佳安全实践之一。\n但是,也有少数地下或隐蔽的公司通过招募黑客,用他们掌握的黑客技术寻找并利用漏洞,为自身牟取非法利益。\n2022 年,竟有巨头公司打破底线,将白帽黑客作为武器,指向了用户。\n2023年2月28日,DarkNavy深蓝 发布了一篇名为 「DarkNavy深蓝洞察」2022年度十大漏洞与利用:最“不可赦”漏洞利用 的文章,文章指出有一个互联网厂商利用了安卓手机中的高危漏洞,在其看似合法的 App 背后,达到了:\n隐蔽安装,提升装机量 伪造提升 DAU/MAU 用户无法卸载 攻击竞争对手 App 窃取用户隐私数据 逃避隐私合规监管 等各种涉嫌违规违法目的,但并未点名该 App 是谁。\n此文一出,持续发酵,各种线索均指向了一个 App —— 拼多多。\n随着研究的深入,基本已经实锤拼多多,包括不限于各种行内安全大佬的分析2,谷歌在 Google Play 下架拼多多,并提示他为恶意软件,最终在2023年3月27号,卡巴斯基实验室的安全研究人员证实拼多多 App 包含恶意代码3。在对恶意代码的首批公开报告之一中,卡巴斯基阐述了该应用程序如何提升自身权限以破坏用户隐私和数据安全。它测试了通过中国本地应用商店分发的应用版本 —— 包含来自华为、腾讯和小米的应用市场。\n同时更令人恶心的是,「目前没有证据表明 Google Play Store 和苹果 App Store 的版本含有恶意代码,通过 Google 和苹果官方商店下载的拼多多应用是安全的。但通过第三方市场下载的 Android 用户则没有那么幸运了,鉴于拼多多有数亿用户,受影响的用户数量可能是非常惊人」,也就是说拼多多这还是定向打击、定向投毒,是看咱们国人好欺负?大家可能对于这种事情向来是不关心,能用就行可能就是大多数人奉行的宗旨,管他对我做了什么,管他有没有什么违法的事情,一味的这样只会助长拼多多这种恶心平台与 App 的气焰。\n目前拼多多已经替换了利用漏洞 App 以及解散了漏洞挖掘与利用相关的团队,不过也有消息称仍有部份人留任继续挖掘。\n被谷歌下架半个月后,拼多多平台内的恶意功能逐渐浮出水面。根据公开资料显示,近日匿名拼多多员工称,公司在 2020 年组建了一支由大约 100 名工程师和产品经理组成的团队,致力于挖掘 Android 手机漏洞,开发漏洞利用方法,将其转化为利润。\n此外,消息源称,拼多多应用的恶意功能最初只针对农村和小城镇的用户,避开北京上海之类大都市的用户,此举旨在降低被暴露的风险。通过收集用户活动的大量数据,拼多多能全面了解用户习惯、兴趣和偏好,改进其机器学习模型,提供更具有个性化的推送通知和广告,吸引用户打开应用并下单。在被曝光之后该团队于三月初被解散。\n同时,截止目前为止,网信办也没有公布任何对拼多多不法行为的追责。一个人要转头多少次,还假装视而不见。315晚会上也没有拼多多,都是些不痛不痒的事情,加起来也没拼多多恶心。法律没有惩治拼多多,反而拼多多自己在用着这些法律武器来追责那些对他「抹黑」的人,明明事实都已经摆在台面上了,还是可以嘴硬,就好像只要自己一味的否定自己做过的事情,就真的可以当作事情没发生过,谎话说多了自己都信了。\n昨日,OSCHINA 微信公众号此前报道的相关文章《某国产电商 APP 利用 Android 漏洞细节曝光:内嵌提权代码、动态下发 Dex》收到了来自拼多多主体公司的投诉,投诉类型是 “内容侵犯名誉 / 商誉 / 隐私 / 肖像”。然而那篇文章从头到尾都没有指名道姓地说是哪家公司、哪款 APP。3\n结语 可能有人会说,拼多多就那么一无是处,一点优点都没有吗?\n要说优点,还是有的,例如百亿补贴、小物件免邮、新鲜水果便宜、签到打卡浇水领各种东西、支持仅退款,相对利好消费者、用户下沉做得好,利好农村的人们。但这不是本文讨论的范围,我只是总结他的恶行,你也可以去多了解拼多多的好处,用不用还是需要自己权衡。\n即使如此,但是我仍想说,他做了好事不代表你要忘记了他的恶,如果不用实际行动去抵制它,一味的迁就它,那这样它只会觉得大家好欺负,继续肆无忌惮的做恶心的事情。希望看到文章的大家都可以在使用拼多多前想想,我是不是必须要用它才行,如果不是,那么就应该用其他平台,而不是——拼多多。\nhttps://finance.sina.com.cn/zt_d/pddhykj/\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nhttps://github.com/davinci01010/pinduoduo_backdoor_x\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nhttps://zhuanlan.zhihu.com/p/617661783\u0026#160;\u0026#x21a9;\u0026#xfe0e;\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","permalink":"https://blog.zzsqwq.cn/posts/why-should-boycott-pdd/","summary":"TL;DR 本文旨在结合一系列事实总结拼多多过去的一系列恶心行为,包括不限于\n虚假宣传 砍一刀套路多 拉人助力 铺天盖地的广告 利用漏洞 希望大家抵制拼多多这种无良平台,非必要不使用拼多多。\n前言 最近看了很多拼多多令人反感的操作以及看了很多拼多多的软广,如 拼多多,让谁不爽,看到这么一个无良平台逐渐壮大实在是令人恼火,因此我觉得有必要写一篇文章来总结一下拼多多各种恶心人的操作来让大家了解这个无良平台,来看看他到底为什么让人不爽,并呼吁大家可以联合抵制这个平台。\n本文会尽量客观理性,陈述已发生的事实而不是自己的观点,同时因为我不是商家,也不是拼多多的员工,本文只是作为用户角度评判。除了对用户方面的恶心行为,还有对员工及商家的压榨,这个后面有时间再写。欢迎大家补充、批评、指正。\n一、虚假宣传 首先需要提到的就是拼多多的虚假宣传,主要是广告,相信大家都看到过,例如「为什么这些 Switch 游戏机只买 9.9 元都没人买,全部砸了算了」这种开头的,或者「你有 iPhone 13 吗,没有就打开拼多多抢一台」。铺天盖地的,无论是你看视频、还是刷QQ空间,还是刷朋友圈,总是能碰到这种广告,无非就是诱惑你点击下载拼多多,但是打开后却发现广告中说的点击就送、无门槛拿根本都是无稽之谈,要不就是限量两个,邀请最多的人才能领。下面是这类视频的合集,大家可能看到的时候都觉得尬和乐,但是却很少有人认识到这是虚假宣传,违规行为。\n根据百度百科对于虚假宣传的定义:\n虚假宣传是指在商业活动中经营者利用广告或其他方法对商品或者服务做出与实际内容不相符的虚假信息,导致客户或消费者误解的行为。\n这拼多多应该确实是符合的吧?虽然很多只是下载了 App 但是没有产生消费行为,但也可以归入其中。\n二、砍一刀套路多 套路多是指,经过第一步的虚假宣传,让你下载了 App,你以为可以很轻松的拿到免单的商品,但实际他会给你放一堆的限制,就像十年前的页游,一堆过场动画,什么「你是砍价第一名」、「还差 0.01 即可砍成功」,但你一旦继续深入,你就会发现这是个无底洞,0.01 后面是 0.001,0.001 后面是 0.0001,0.0001 后面怕你看数字太小生气,他就会让你集几万个金币或者一些其他的东西,十万个金币兑换 0.001,这样无限循环,想砍成实在难如登天。\n拼多多曾公开表示1:\n近日,“拼多多砍价,但始终差0.9%”话题受到广泛关注,去年3月,上海律师刘宇航参加了拼多多的“砍价免费拿”活动后,经多人砍价还是0.9%,在质疑数据有问题后,刘以使用虚假数据隐瞒规则已构成欺诈为由,向法院递交了起诉材料。在刘宇航随后释出的文件中得知,拼多多称是“因页面显示百分比位数有限,所以他们把一个至少小数点后有6位数以上的百分比,省略显示为0.9%,砍价页面显示的0.9%不是0.9%,而是0.9996427%。”\n当然这里也有砍成功的,不过是分价位的,你砍 100 元的红包,可能拉个七八个人就成功,如果都是新用户可能会更少,如果是砍 Switch、手机这种大件,需要砍的次数则就更多。当然砍 100 元的红包砍的多了,积累的价钱上去了,他也不会让你持续的薅,难度也是累加的。一个典型的案例可以看 超级小桀 之前的视频,如下:\n上面这个视频简单概括一下就是,小桀在直播间突发奇想带水友一起砍一部 IQOO 手机,前期很长的过场动画都在提示你,马上可以直接拿到,进度已经到达 0.00%,但是还是需要收集 10 多个金币,邀请两三个人即可,后来小桀把二维码分享出来,非常多的水友扫码砍,后来导致二维码提示被封禁,小桀又把链接分享给了群里的水友,当时在线的水友不完全统计 6-7W,至少有上千人参与,但最终也没有让那 10 多个金币归零,打电话给客服询问,客服给出理由如下:\n每个人砍都是概率砍成功,可能 100 人砍有 50 个人、80 个人砍成功,不是 100% 成功。 像这么多人砍价,系统检测到会封禁。 那我就有点疑问了,你这个东西本来就需要邀请很多人砍价才能成功,但是你人一多又要封禁,那么不邀请这么多人砍价,那么怎么成功呢?真的是「解释权归拼多多所有」。\n据小桀自己回应,直到3月17号下午2点40分左右下播,也没有砍成功,但是突然在4点40分左右莫名其妙的成功了,赠送了一张无门槛购物券可以下单此手机,随后客服回应:砍价不成功不属实,已经发放「特制」优惠券。这一通操作,实在是闻所未闻,谁也能看出来是事态发展到不可预料的地步搞了个东西出来封口的。\n实在是太像诈骗、传销了,即使这样广泛的虚假宣传,到现在也没有被整治,也还是随处可见。\n附小桀对这件事情的声明:\n三、拉人助力 拼多多最特色的行为,应该就是这个拉人助力,可能算是拉人助力的始祖了,如今算是各个软件的标配了,美团、饿了么、携程旅行、智行中也都随处可见。好处显而易见,可以提高自己活动的参与率、提高 App 的下载率、提高品牌知名度、提高用户粘性。","title":"为什么应该抵制拼多多?"},{"content":"前言 最近想要使用自己采集与标注的数据集来训练与部署一下地平线微调过的 FCOS 网络,在询问和查看文档后发现如果想基于官方微调的模型训练,需要使用提供 HAT(Horizon Algorithm Toolkit,海图) 来进行,具体的文档可以查看:Horizon Algorithm Toolkit 文档,这是在线的版本,版本可能会比较旧,想看最新版的可以查看离线的版本,位置在 OE(Open Explorer,天工开物) 包的 doc 目录下,如下图:\n想要方便的查看离线文档可以通过 Python 来实现,在 doc 目录下执行:\npython3 -m http.server 3000 这样就可以在本地的 0.0.0.0:3000 地址开启一个 http server,随后可以在本地浏览器使用 localhost:3000 或者其他电脑浏览器使用 {ip}:3000 来访问文档。\n但是查看 文档 过后会发现,文档其实也没有那么的全面,讲的比较简单,尝试了一下中间坑还挺多的,社区里面关于这方面的帖子也不多12,因此想记录下我尝试的全流程,也可以作为对上面教程文档的补充。\n下面主要分为三部分:\n训练的环境配置。\n如何基于官方的 COCO 数据集训练?这里就是指基于 mscoco 发布的包含 80 类的数据集。\n如何基于自己的数据集进行训练?这里就是指自己建立的,自定义类别的,可能只有四五类,没有 80 类的数据集。\n下方涉及到的一些代码、脚本和模型等,可以在 Github 仓库 中找到。\n训练的环境配置 我自己环境配置如下:\nOS: Ubuntu 20.04\nDocker: 20.10.23\nNvidia Docker: 2.11.0-1\nGPU: RTX3090\nNVIDIA Driver Version: 515.65.01\nCUDA Version: 11.7\nOE Version: v2.4.2( gcc-9.3.0 For XJ3 )\n因为我的开发是基于 Ubuntu 进行,训练是 GPU 进行的,所以这里只提及关于 Ubuntu + GPU 训练的环境配置,Windows 情况下,或者只有 CPU 的情况,我也没尝试过。\n首先需要安装 Docker 以及 NVIDIA Docker,前者安装参考:Docker 安装文档,后者安装参考:NVIDIA Docker 安装文档。\n参考官方 X3 芯片文档编写启动脚本 run_docker.sh 如下:\n#!/bin/bash export version=v2.4.2 export ai_toolchain_package_path=/data/sunrise/horizon_oe_v2.4.2 export dataset_path=/data/datasets docker run -dt --runtime=nvidia -e NVIDIA_DRIVER_CAPABILITIES=compute,utility \\ -e NVIDIA_VISIBLE_DEVICES=all --shm-size=\u0026#34;15g\u0026#34; \\ --restart=always --network=host \\ -v \u0026#34;$ai_toolchain_package_path\u0026#34;:/open_explorer \\ -v \u0026#34;$dataset_path\u0026#34;:/data \\ openexplorer/ai_toolchain_centos_7_xj3:\u0026#34;${version}\u0026#34; 其中参数解释如下:\nversion 代表 Docker 镜像版本,可选版本参考:资料下载专区\nai_toolchain_package_path 代表 OE 开发包的路径,指定 OE 包中 ai_toolchain 的路径也可以,但是我建议把整个 OE 包都挂进去得了,没啥差别。\ndataset_path 代表训练需要的数据集路径,这里可以新建一个空的文件夹然后挂载进去,也可以把你所有的数据集都准备好,然后放到一个文件夹,然后挂进去,需要训练哪个后面指定哪个即可,我们这里方便起见可以选择前者(官方说如果这里指定为空可能会出问题,但是我测试发现挂载空文件夹不会有问题)。\ndocker run 部分就是启动一个 Docker 容器,其中比较重要的参数: -dt 可以让容器使用 Daemon 的方式启动一个交互式终端,可以保证容器一直存活不会 detach 后就被杀死,方便我们多次操作;--restart=always 可以在每次开机时自动重启容器,可以视自己的情况去掉或者改成 --restart=unless-stopped 等;--network=host 指定与宿主机器使用同一个网络,方便我们查看文档或者后面的网络结构。\n设置后即可打开终端,使用 bash run_docker.sh 启动容器,并使用 docker exec -it {container_id} bash 来连接容器进行操作,其中 container_id 可以通过 docker ps 或者上述脚本的返回值查看。\n进入后可使用 nvidia-smi 验证一下,出现下方的信息即代表成功:\n环境配置到此结束,终于可以开始训练和部署网络了。\n训练 COCO 数据集并进行部署 数据准备 下方的操作均在上方启动的容器中进行,首先需要先 docker exec 进入容器中。\n其中准备 COCO 数据集部分参考 官方文档部分,首先进入 /data 目录,然后新建一个文件夹 mscoco,下载数据集、解压即可。\n# 进入之前挂载的 /data 目录 cd /data # 创建一个目录来存储数据集 mkdir mscoco # 下载 train2017.zip,即训练数据集 wget -c http://images.cocodataset.org/zips/train2017.zip # 下载 val2017.zip,即验证数据集 wget -c http://images.cocodataset.org/zips/val2017.zip # 下载 annotations_trainval2017.zip 即对应标签 wget -c http://images.cocodataset.org/annotations/annotations_trainval2017.zip # 解压 unzip train2017.zip unzip val2017.zip unzip annotations_trainval2017.zip 随后进入 /open_explorer/horizon_model_train_samples 目录,如果这里你和我之前一样是挂载的整个 OE 包,那这个路径可能会长一些,例如我这里是 /open_explorer/ddk/samples/ai_toolchain/horizon_model_train_samples。\n将数据集打包成 lmdb 格式,注意下方的 /data/mscoco 路径是我们之前存放数据集的路径:\n# 转换训练集 python3 tools/datasets/mscoco_packer.py --src-data-dir /data/mscoco/ --target-data-dir /data/mscoco --split-name train --pack-type lmdb # 转换验证集 python3 tools/datasets/mscoco_packer.py --src-data-dir /data/mscoco/ --target-data-dir /data/mscoco --split-name val --pack-type lmdb 运行完即打包成功,/data/mscoco 目录下会多出来 train_lmdb 和 val_lmdb 两个文件夹,即打包之后的训练数据集和验证数据集,也是网络最终读取的数据集。\n修改配置文件 地平线提供的 HAT 工具链是一个类 mmdetion 的东西,模型定义、训练、验证都流程都定义在一个 config.py 文件中,官方提供的所有配置文件可以在 configs 目录下找到,FCOS 对应的就是 configs/detection/fcos 目录下的配置文件,方便起见,我们这里只考虑 fcos_efficientnetb0_mscoco.py ,关于配置的进一步讲解,可见官方文档:config 文件介绍。\n在修改之前,最好先备份一下原件,可以作为对比,也方便回溯:\ncp fcos_efficientnetb0_mscoco.py fcos_efficientnetb0_mscoco_back.py 要改的点有三个:\ndevice_ids:这里代表的是你使用的 GPU 序号,如果只有一个 GPU 就只保留 [0],两个就是 [0, 1],以此类推。 所有跟 ./tmp_data 有关的位置,这里相关的都是指定的数据集位置,官方举例是将数据集都放在了同 configs 同目录的 tmp_data 目录,但是我们放在了 /data 目录,因此要将所有的 ./tmp_data 都改成 /data float_trainer:这个参数是个 Dict,里面包含了一个 num_epochs ,代表我们训练多少轮,这里默认是 300,可以根据自己需求调整,例如 5、10、100 等。 开始训练! 训练很简单,一行命令即可:\n# 进入 horizon_model_train_samples 目录 cd /open_explorer/ddk/samples/ai_toolchain/horizon_model_train_samples # 开始训练 python3 tools/train.py --step float --config configs/detection/fcos/fcos_efficientnetb0_mscoco.py 如果不出意外,已经开始训练了,正常如下图所示:\n顺便说一下,这里推荐配合 tmux 工具来训练,可以让 session 在后台运行,防止意外中断,顺附一个 tmux 教程:Tmux 使用教程。\n模型转换 训练的时间比较长,主要取决于数据集的大小,如果是 mscoco 这种大型数据集,一个 epoch 就要好久才行。\n这里我训练了十轮就结束了,随后进入 tmp_models 目录,找到我们训练好的权重文件,如下图,这里的存放位置主要和配置文件中的 task_name 与 ckpt_dir 有关,可以按需修改:\n接下来就是将权重文件导出成 ONNX 模型:\npython3 tools/export_onnx.py --config configs/detection/fcos/fcos_efficientnetb0_mscoco.py --ckpt tmp_models/fcos_efficientnetb0_mscoco/float-checkpoint-best.pth.tar --onnx-name fcos.onnx 如上命令,将训练得到的 best 权重文件(float-checkpoint-best.pth.tar)导出成了 fcos.onnx 模型文件,这里也可以选择其他的权重,指定对模型路径即可。\n接下来是使用地平线的工具链对 ONNX 模型进行量化,以便我们后面上板推理:\n第一步,先移动一下得到的权重文件,方便后面的查找:\n# 进入 horizon_model_train_samples 目录 cd /open_explorer/ddk/samples/ai_toolchain/horizon_model_train_samples # 建立文件夹 mkdir -p ../horizon_model_convert_sample/08_customs # 移动 onnx 模型过去 cp ./fcos.onnx ../horizon_model_convert_sample/08_customs 接下来就是那套标准的转换流程,可以参考官方教程:6.3 快速体验,还有大佬的指南:一文带你轻松走出模型部署新手村。\n主要是涉及模型地址和数据集地址的时候需要改成我们对应的即可,其他的都默认就行,接下来给出我的几个脚本及精简后的转换配置文件:\n01_check.sh # 01_check.sh set -e -v cd $(dirname $0) model_type=\u0026#34;onnx\u0026#34; onnx_model=\u0026#34;../../../08_customs/fcos.onnx\u0026#34; march=\u0026#34;bernoulli2\u0026#34; hb_mapper checker --model-type ${model_type} \\ --model ${onnx_model} \\ --march ${march} 02_preprocess.sh # 02_preprocess.sh set -e -v cd $(dirname $0) || exit python3 ../../../data_preprocess.py \\ --src_dir /data/mscoco/train2017 \\ --dst_dir ./calibration_data_yuv_f32 \\ --cal_img_num 50 \\ --pic_ext .yuv \\ --read_mode opencv \\ --saved_data_type float32 fcos_efficientnetb0_config.yaml # fcos_efficientnetb0_config.yaml model_parameters: onnx_model: \u0026#39;../../../08_customs/fcos.onnx\u0026#39; march: \u0026#34;bernoulli2\u0026#34; layer_out_dump: False working_dir: \u0026#39;fcos_test\u0026#39; output_model_file_prefix: \u0026#39;fcos_test\u0026#39; input_parameters: input_name: \u0026#34;\u0026#34; input_type_rt: \u0026#39;nv12\u0026#39; input_type_train: \u0026#39;yuv444\u0026#39; input_layout_train: \u0026#39;NCHW\u0026#39; input_shape: \u0026#39;\u0026#39; norm_type: \u0026#39;data_mean_and_scale\u0026#39; mean_value: 128.0 scale_value: 0.0078125 calibration_parameters: cal_data_dir: \u0026#39;./calibration_data_yuv_f32_qyun\u0026#39; cal_data_type: \u0026#39;float32\u0026#39; calibration_type: \u0026#39;max\u0026#39; max_percentile: 0.99996 compiler_parameters: compile_mode: \u0026#39;latency\u0026#39; debug: False optimize_level: \u0026#39;O3\u0026#39; 这里理论上只需要执行完 03_build.sh 脚本转换即结束,不出意外在同目录下会生成 fcos_test 目录,已经在其中可找到 fcos.bin ,这即是我们后续上板推理需要的模型文件。\n模型推理 这里 Python 推理我参考了 X3M 板子上 /app/ai_inference/02_usb_camera_sample/usb_camera_fcos.py 目录下的推理脚本,直接上代码:\n#!/usr/bin/env python3 import os from hobot_dnn import pyeasy_dnn as dnn from hobot_vio import libsrcampy as srcampy import numpy as np import cv2 import colorsys from time import time # detection model class names def get_classes(): return np.array([\u0026#34;person\u0026#34;, \u0026#34;bicycle\u0026#34;, \u0026#34;car\u0026#34;, \u0026#34;motorcycle\u0026#34;, \u0026#34;airplane\u0026#34;, \u0026#34;bus\u0026#34;, \u0026#34;train\u0026#34;, \u0026#34;truck\u0026#34;, \u0026#34;boat\u0026#34;, \u0026#34;traffic light\u0026#34;, \u0026#34;fire hydrant\u0026#34;, \u0026#34;stop sign\u0026#34;, \u0026#34;parking meter\u0026#34;, \u0026#34;bench\u0026#34;, \u0026#34;bird\u0026#34;, \u0026#34;cat\u0026#34;, \u0026#34;dog\u0026#34;, \u0026#34;horse\u0026#34;, \u0026#34;sheep\u0026#34;, \u0026#34;cow\u0026#34;, \u0026#34;elephant\u0026#34;, \u0026#34;bear\u0026#34;, \u0026#34;zebra\u0026#34;, \u0026#34;giraffe\u0026#34;, \u0026#34;backpack\u0026#34;, \u0026#34;umbrella\u0026#34;, \u0026#34;handbag\u0026#34;, \u0026#34;tie\u0026#34;, \u0026#34;suitcase\u0026#34;, \u0026#34;frisbee\u0026#34;, \u0026#34;skis\u0026#34;, \u0026#34;snowboard\u0026#34;, \u0026#34;sports ball\u0026#34;, \u0026#34;kite\u0026#34;, \u0026#34;baseball bat\u0026#34;, \u0026#34;baseball glove\u0026#34;, \u0026#34;skateboard\u0026#34;, \u0026#34;surfboard\u0026#34;, \u0026#34;tennis racket\u0026#34;, \u0026#34;bottle\u0026#34;, \u0026#34;wine glass\u0026#34;, \u0026#34;cup\u0026#34;, \u0026#34;fork\u0026#34;, \u0026#34;knife\u0026#34;, \u0026#34;spoon\u0026#34;, \u0026#34;bowl\u0026#34;, \u0026#34;banana\u0026#34;, \u0026#34;apple\u0026#34;, \u0026#34;sandwich\u0026#34;, \u0026#34;orange\u0026#34;, \u0026#34;broccoli\u0026#34;, \u0026#34;carrot\u0026#34;, \u0026#34;hot dog\u0026#34;, \u0026#34;pizza\u0026#34;, \u0026#34;donut\u0026#34;, \u0026#34;cake\u0026#34;, \u0026#34;chair\u0026#34;, \u0026#34;couch\u0026#34;, \u0026#34;potted plant\u0026#34;, \u0026#34;bed\u0026#34;, \u0026#34;dining table\u0026#34;, \u0026#34;toilet\u0026#34;, \u0026#34;tv\u0026#34;, \u0026#34;laptop\u0026#34;, \u0026#34;mouse\u0026#34;, \u0026#34;remote\u0026#34;, \u0026#34;keyboard\u0026#34;, \u0026#34;cell phone\u0026#34;, \u0026#34;microwave\u0026#34;, \u0026#34;oven\u0026#34;, \u0026#34;toaster\u0026#34;, \u0026#34;sink\u0026#34;, \u0026#34;refrigerator\u0026#34;, \u0026#34;book\u0026#34;, \u0026#34;clock\u0026#34;, \u0026#34;vase\u0026#34;, \u0026#34;scissors\u0026#34;, \u0026#34;teddy bear\u0026#34;, \u0026#34;hair drier\u0026#34;, \u0026#34;toothbrush\u0026#34;]) # return np.array([\u0026#34;tissue\u0026#34;, \u0026#34;sock\u0026#34;, \u0026#34;shoe\u0026#34;, \u0026#34;cable\u0026#34;, \u0026#34;bin\u0026#34;]) # bgr格式图片转换成 NV12格式 def bgr2nv12_opencv(image): height, width = image.shape[0], image.shape[1] area = height * width yuv420p = cv2.cvtColor( image, cv2.COLOR_BGR2YUV_I420).reshape((area * 3 // 2,)) y = yuv420p[:area] uv_planar = yuv420p[area:].reshape((2, area // 4)) uv_packed = uv_planar.transpose((1, 0)).reshape((area // 2,)) nv12 = np.zeros_like(yuv420p) nv12[:height * width] = y nv12[height * width:] = uv_packed return nv12 def postprocess(model_output, model_hw_shape, origin_image=None, origin_img_shape=None, score_threshold=0.5, nms_threshold=0.6, dump_image=False): input_height = model_hw_shape[0] input_width = model_hw_shape[1] if origin_image is not None: origin_image_shape = origin_image.shape[0:2] else: origin_image_shape = origin_img_shape prediction_bbox = decode(outputs=model_output, score_threshold=score_threshold, origin_shape=origin_image_shape, input_size=512) prediction_bbox = nms(prediction_bbox, iou_threshold=nms_threshold) prediction_bbox = np.array(prediction_bbox) topk = min(prediction_bbox.shape[0], 1000) if topk != 0: idx = np.argpartition(prediction_bbox[..., 4], -topk)[-topk:] prediction_bbox = prediction_bbox[idx] if dump_image and origin_image is not None: draw_bboxs(origin_image, prediction_bbox) return prediction_bbox def draw_bboxs(image, bboxes, gt_classes_index=None, classes=get_classes()): \u0026#34;\u0026#34;\u0026#34;draw the bboxes in the original image \u0026#34;\u0026#34;\u0026#34; num_classes = len(classes) image_h, image_w, channel = image.shape hsv_tuples = [(1.0 * x / num_classes, 1., 1.) for x in range(num_classes)] colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples)) colors = list( map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)), colors)) fontScale = 0.5 bbox_thick = int(0.6 * (image_h + image_w) / 600) for i, bbox in enumerate(bboxes): coor = np.array(bbox[:4], dtype=np.int32) if gt_classes_index == None: class_index = int(bbox[5]) score = bbox[4] else: class_index = gt_classes_index[i] score = 1 bbox_color = colors[class_index] c1, c2 = (coor[0], coor[1]), (coor[2], coor[3]) cv2.rectangle(image, c1, c2, bbox_color, bbox_thick) classes_name = classes[class_index] bbox_mess = \u0026#39;%s: %.2f\u0026#39; % (classes_name, score) t_size = cv2.getTextSize(bbox_mess, 0, fontScale, thickness=bbox_thick // 2)[0] cv2.rectangle(image, c1, (c1[0] + t_size[0], c1[1] - t_size[1] - 3), bbox_color, -1) cv2.putText(image, bbox_mess, (c1[0], c1[1] - 2), cv2.FONT_HERSHEY_SIMPLEX, fontScale, (0, 0, 0), bbox_thick // 2, lineType=cv2.LINE_AA) print(\u0026#34;{} is in the picture with confidence:{:.4f}\u0026#34;.format( classes_name, score)) # cv2.imwrite(\u0026#34;demo.jpg\u0026#34;, image) return image def decode(outputs, score_threshold, origin_shape, input_size=512): def _distance2bbox(points, distance): x1 = points[..., 0] - distance[..., 0] y1 = points[..., 1] - distance[..., 1] x2 = points[..., 0] + distance[..., 2] y2 = points[..., 1] + distance[..., 3] return np.stack([x1, y1, x2, y2], -1) def _scores(cls, ce): cls = 1 / (1 + np.exp(-cls)) ce = 1 / (1 + np.exp(-ce)) return np.sqrt(ce * cls) def _bbox(bbox, stride, origin_shape, input_size): # l t r b | h, w = t, r h, w = bbox.shape[1:3] yv, xv = np.meshgrid(np.arange(h), np.arange(w)) xy = (np.stack((yv, xv), 2) + 0.5) * stride bbox = _distance2bbox(xy, bbox) # opencv read, shape[1] is w, shape[0] is h scale_w = origin_shape[1] / input_size scale_h = origin_shape[0] / input_size scale = max(origin_shape[0], origin_shape[1]) / input_size # origin img is pad resized # bbox = bbox * scale # origin img is resized bbox = bbox * [scale_w, scale_h, scale_w, scale_h] return bbox bboxes = list() strides = [8, 16, 32, 64, 128] # 各个 stride 找符合的模型 for i in range(len(strides)): cls = outputs[i].buffer bbox = outputs[i + 5].buffer ce = outputs[i + 10].buffer scores = _scores(cls, ce) classes = np.argmax(scores, axis=-1) classes = np.reshape(classes, [-1, 1]) max_score = np.max(scores, axis=-1) max_score = np.reshape(max_score, [-1, 1]) bbox = _bbox(bbox, strides[i], origin_shape, input_size) bbox = np.reshape(bbox, [-1, 4]) pred_bbox = np.concatenate([bbox, max_score, classes], axis=1) index = pred_bbox[..., 4] \u0026gt; score_threshold pred_bbox = pred_bbox[index] bboxes.append(pred_bbox) return np.concatenate(bboxes) def nms(bboxes, iou_threshold, sigma=0.3, method=\u0026#39;nms\u0026#39;): def bboxes_iou(boxes1, boxes2): boxes1 = np.array(boxes1) boxes2 = np.array(boxes2) boxes1_area = (boxes1[..., 2] - boxes1[..., 0]) * \\ (boxes1[..., 3] - boxes1[..., 1]) boxes2_area = (boxes2[..., 2] - boxes2[..., 0]) * \\ (boxes2[..., 3] - boxes2[..., 1]) left_up = np.maximum(boxes1[..., :2], boxes2[..., :2]) right_down = np.minimum(boxes1[..., 2:], boxes2[..., 2:]) inter_section = np.maximum(right_down - left_up, 0.0) inter_area = inter_section[..., 0] * inter_section[..., 1] union_area = boxes1_area + boxes2_area - inter_area ious = np.maximum(1.0 * inter_area / union_area, np.finfo(np.float32).eps) return ious classes_in_img = list(set(bboxes[:, 5])) best_bboxes = [] for cls in classes_in_img: cls_mask = (bboxes[:, 5] == cls) cls_bboxes = bboxes[cls_mask] while len(cls_bboxes) \u0026gt; 0: max_ind = np.argmax(cls_bboxes[:, 4]) best_bbox = cls_bboxes[max_ind] best_bboxes.append(best_bbox) cls_bboxes = np.concatenate( [cls_bboxes[:max_ind], cls_bboxes[max_ind + 1:]]) iou = bboxes_iou(best_bbox[np.newaxis, :4], cls_bboxes[:, :4]) weight = np.ones((len(iou),), dtype=np.float32) assert method in [\u0026#39;nms\u0026#39;, \u0026#39;soft-nms\u0026#39;] if method == \u0026#39;nms\u0026#39;: iou_mask = iou \u0026gt; iou_threshold weight[iou_mask] = 0.0 if method == \u0026#39;soft-nms\u0026#39;: weight = np.exp(-(1.0 * iou ** 2 / sigma)) cls_bboxes[:, 4] = cls_bboxes[:, 4] * weight score_mask = cls_bboxes[:, 4] \u0026gt; 0. cls_bboxes = cls_bboxes[score_mask] return best_bboxes def print_properties(pro): print(\u0026#34;tensor type:\u0026#34;, pro.tensor_type) print(\u0026#34;data type:\u0026#34;, pro.dtype) print(\u0026#34;layout:\u0026#34;, pro.layout) print(\u0026#34;shape:\u0026#34;, pro.shape) if __name__ == \u0026#39;__main__\u0026#39;: models = dnn.load(\u0026#39;./models/fcos.bin\u0026#39;) # 打印输入 tensor 的属性 print_properties(models[0].inputs[0].properties) # 打印输出 tensor 的属性 print(len(models[0].outputs)) for output in models[0].outputs: print_properties(output.properties) frame = cv2.imread(\u0026#34;./kite.jpg\u0026#34;) if frame is None: print(\u0026#34;Image is not exist.\u0026#34;) height, width = frame.shape[:2] print(\u0026#34;height: \u0026#34;, height, \u0026#34;width: \u0026#34;, width) # 把图片缩放到模型的输入尺寸 # 获取算法模型的输入tensor 的尺寸 h, w = models[0].inputs[0].properties.shape[2], models[0].inputs[0].properties.shape[3] des_dim = (w, h) resized_data = cv2.resize(frame, des_dim, interpolation=cv2.INTER_AREA) nv12_data = bgr2nv12_opencv(resized_data) # Forward outputs = models[0].forward(nv12_data) # Do post process input_shape = (h, w) prediction_bbox = postprocess( outputs, input_shape, origin_img_shape=(height, width)) if frame.shape[0] != height or frame.shape[1] != width: frame = cv2.resize(frame, (width, height), interpolation=cv2.INTER_AREA) # Draw bboxs box_bgr = draw_bboxs(frame, prediction_bbox) cv2.imwrite(\u0026#34;kite_with_bbox.jpg\u0026#34;, box_bgr) 其实流程还是蛮简单的,就是 加载模型 -\u0026gt; 读取照片 -\u0026gt; Resize 照片到模型推理尺寸 -\u0026gt; 转化为 NV12 输入格式 -\u0026gt; 拿到输出 outputs -\u0026gt; 对数据集进行后处理得到 bbox 与 classes 等数据 -\u0026gt; Resize 照片到原尺寸绘制框 -\u0026gt; 写照片。\n大家拿脚本推理的时候,只需要改变 models 和读取照片的位置即可,这里我采用的示例图片是在模型转化后测试推理使用的,可以在 OE 包的如下路径找到 ai_toolchain/horizon_model_convert_sample/01_common/test_data/det_images/kite.jpg。\n接下来就是运行脚本进行推理,得到的推理结果如下:\n为什么结果是这样的,起初我认为是我推理脚本写错了,因此我直接将权重替换为官方的权重,得到的结果如下:\n很显然,这次的推理是正确的,也就是说明,脚本是没问题,只是权重出了问题,因此我又仔细检查了训练和模型转换的各个步骤,但都没有发现问题。同时,使用官方提供的 mapper 目录下原 onnx 进行转换后,也是没有问题的。那么问题在哪里呢?\n查找问题 因为通过上面的排除可以确定,转化这个过程是没什么问题的,那也就只能是模型定义和训练中出现的问题,但是上面的效果又明显不是训练过拟合或者欠拟合导致的,因为框的位置是大致对的,就是太多了,而且太小了,因此我怀疑是模型上出了问题,可能是有节点不一致。\n确定了方向,接下来我首先对官方原 onnx 模型文件和我自己训练得到的 onnx 模型使用了 01_checker.sh 脚本来进行检查,因为他会输出模型中的各个层,对比结果如下:\n左侧是我自己训练得到的模型,右侧是我官方提供的模型,可以发现,两者存在差异,其实就是官方模型相比于训练得到的模型会多了几个 Mul 节点。\n接下来进一步使用 netron 工具对两个模型进行对比,有区别的对比结果如下图所示:\n左侧为自己训练的模型,右侧为官方模型。可以看到只有 bbox 信息(对于 FCOS 为(l, t, r, b)四元组)在输出时两个模型有区别,多了一步 Relu 激活函数和 Mul 节点,其他的经过对比没有区别。\n同时观察发现,这里 Mul 节点对应的数值,其实是对应的 stride(这个大家可以使用 netron 去看看)\n知道了问题所在,解决方案就有了,只需要改动下面这一行即可:\n# Decode 函数中获取数据的部分 # 各个 stride 找符合的模型 for i in range(len(strides)): cls = outputs[i].buffer bbox = outputs[i + 5].buffer * strides[i] # modified ce = outputs[i + 10].buffer scores = _scores(cls, ce) 很好理解,对 bbox 获得的原始数据乘了 strides[i],这里我没有处理 Relu 函数,因为即使是负数,OpenCV 绘制也是不会出问题的。\n再次运行获得的推理图如下,这次正常了:\n至此,训练 mscoco 数据集模型并进行部署就算结束了,接下来我们看看如何来处理自己得到的数据集。\n训练自采集数据集 对于自采集数据集,最可能是数据处理打包、以及配置文件的配置这两部分存在问题,剩下的模型检查、校准数据准备、模型转化、以及上板推理部分可以说是根本没区别,所以就着重讲一下数据准备和配置部分。\n数据准备 首先数据准备要准备 COCO JSON 格式,他是跟通用 JSON 格式也是有区别的,这个就不详述了。\n然后方便起见,可以复用官方的 mscoco_packer.py 脚本,我们把数据集也存为 train2017、val2017 和 annotations 三个文件夹,例如存在放在 /data/selfcoco 目录下,类似于下面:\n[root@Z690-P selfcoco]# tree . ├── annotations │ ├── instances_train2017.json # 训练集的 label │ └── instances_val2017.json # 验证集的 label ├── train2017 # 训练集照片 └── val2017 # 验证集照片 这时候如果我们按照之前的操作,直接使用 mscoco_packer.py 脚本进行打包,会报错如下:\n报错大意就是访问了字典一个不存在的键,直接查看报错的位置,位于 /usr/local/lib/python3.6/site-packages/hat/data/datasets/mscoco.py,查看后发现 COCO_LABLE_TO_LABLE 这个字典是一个类别的映射,因为 mscoco 数据集类别包含 80 类,按顺序来是 [0, 80),但是 mscoco 数据集原数据集类别序号范围为 [1, 90],但是其中只有 80 个类别序号,所以需要做一个 [1, 90] -\u0026gt; [0, 80) 的类别映射,但是如果我们自制的数据集没有这个类别映射的需求,就不需要映射,把涉及到这个 Dict 的两行都去掉即可。\nBtw:🤣 这里的 COCO_LABLE_TO_LABLE 是不是拼错了,要拼 LABEL 的?\n# 229 行 # anno[0, 4] = COCO_LABLE_TO_LABLE[tar[\u0026#34;category_id\u0026#34;]] anno[0, 4] = tar[\u0026#34;category_id\u0026#34;] # 327 行 # np.array([[COCO_LABLE_TO_LABLE[tar[\u0026#34;category_id\u0026#34;]]]]) np.array([[tar[\u0026#34;category_id\u0026#34;]]]) 随后打包即可\n# 转换训练集 python3 tools/datasets/mscoco_packer.py --src-data-dir /data/selfcoco --target-data-dir /data/selfcoco --split-name train --pack-type lmdb # 转换验证集 python3 tools/datasets/mscoco_packer.py --src-data-dir /data/selfcoco --target-data-dir /data/selfcoco --split-name val --pack-type lmdb 配置文件修改 配置文件除了之前提到的三处需要修改,配置文件中还需要修改与类别相关的参数,大概有如下几个:\nnum_classes:这里就是一个全局变量类别数,例如我这里有五类 [0, 5),那改为 5 即可。 model:model 参数中还有很多涉及到 80 的,经过我查看源码后,发现这些 80 的位置都应该改成 num_classes 参数才可以,例如 model 中的 loss_cls 参数,其中的 num_classes 参数值 80+1 就需要改为 num_classes + 1 ,post_process 参数中的 num_classes 参数值 80 也应该改为 num_classes,这里我认为是官方的疏忽,应该是忘记改了。 修改完后就可以按之前的方法进行训练了:\n# 进入 horizon_model_train_samples 目录 cd /open_explorer/ddk/samples/ai_toolchain/horizon_model_train_samples # 开始训练 python3 tools/train.py --step float --config configs/detection/fcos/fcos_efficientnetb0_mscoco.py 校准数据准备 这里预处理的数据也应该选择我们训练的数据子集,需要修改一下,剩下的都不需要变:\n# 02_preprocess.sh set -e -v cd $(dirname $0) || exit python3 ../../../data_preprocess.py \\ --src_dir /data/selfcoco/train2017 \\ # 重要 --dst_dir ./calibration_data_yuv_f32 \\ --cal_img_num 50 \\ --pic_ext .yuv \\ --read_mode opencv \\ --saved_data_type float32 推理代码修改 这里需要修改 get_classes 函数返回的类别名,改成自己对应的类别 List.\n推理得到结果如下:\n可以看到,识别可以正常的工作(因为我选的训练数据集有点捞,所以过拟合比较严重,就选了一张凑合能看的图,大家见谅)。\n后言 这样我们就完成了 FCOS 网络的训练和部署,但是基于 Python 的推理可能有点慢,大家可以参考 ai_benchmark 等部分进行 C++ 推理,主要关键就是 PostProcess 后处理部分,不过之前 开发者直播KE——AI板端部署实践 张老师已经讲过一部分 API,如果大家有兴趣,我后面也可以给大家出个帖子讲讲 🤗。\n探索的这几天,给我的感觉是,地平线做了很多,写了很多有用的工具、包,但是文档还是不够完善,而且文档有些混乱,版本比较混乱,位置比较混乱、等等,容易找不到、无从下手等等。\n例如对于 FCOS 这部分的文档就很欠缺,对于 FCOS 训练配置的各个选项的详解,大家看到时候可能会有很多问题,例如:\n如何使用 CPU 进行训练而不是 GPU? 如何基于已有的模型进行迁移训练?中断训练后可以再继续进行吗? 可以 freeze 一部分参数进行 fine-tuning 吗? 训练时有数据增强吗?如果不需要可以去掉吗? 不过现在也是在慢慢完善,不断进步,希望可以把这些好用的东西都能让大家快点方便的用起来。\n文中涉及到的一些代码、脚本和模型等,可以在 Github 仓库 中找到。\n文章同步发布在我的博客:https://blog.zzsqwq.cn\n如何用工具链HAT训练fcos自定义数据集\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n在OE包中训练focs模型\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","permalink":"https://blog.zzsqwq.cn/posts/hat-train-fcos/","summary":"前言 最近想要使用自己采集与标注的数据集来训练与部署一下地平线微调过的 FCOS 网络,在询问和查看文档后发现如果想基于官方微调的模型训练,需要使用提供 HAT(Horizon Algorithm Toolkit,海图) 来进行,具体的文档可以查看:Horizon Algorithm Toolkit 文档,这是在线的版本,版本可能会比较旧,想看最新版的可以查看离线的版本,位置在 OE(Open Explorer,天工开物) 包的 doc 目录下,如下图:\n想要方便的查看离线文档可以通过 Python 来实现,在 doc 目录下执行:\npython3 -m http.server 3000 这样就可以在本地的 0.0.0.0:3000 地址开启一个 http server,随后可以在本地浏览器使用 localhost:3000 或者其他电脑浏览器使用 {ip}:3000 来访问文档。\n但是查看 文档 过后会发现,文档其实也没有那么的全面,讲的比较简单,尝试了一下中间坑还挺多的,社区里面关于这方面的帖子也不多12,因此想记录下我尝试的全流程,也可以作为对上面教程文档的补充。\n下面主要分为三部分:\n训练的环境配置。\n如何基于官方的 COCO 数据集训练?这里就是指基于 mscoco 发布的包含 80 类的数据集。\n如何基于自己的数据集进行训练?这里就是指自己建立的,自定义类别的,可能只有四五类,没有 80 类的数据集。\n下方涉及到的一些代码、脚本和模型等,可以在 Github 仓库 中找到。\n训练的环境配置 我自己环境配置如下:\nOS: Ubuntu 20.04\nDocker: 20.10.23\nNvidia Docker: 2.11.0-1\nGPU: RTX3090\nNVIDIA Driver Version: 515.65.01\nCUDA Version: 11.","title":"基于地平线 HAT 训练与部署 FCOS 全流程"},{"content":"2022 依旧是被疫情伴随的一年,时间正着看总是要比回看慢很多,现在回头看过往一年似乎一瞬间就过去了。\n今年共发了 11 篇文章,其中还包含了两篇碎碎念,还是没有达到月更,新的一年希望可以。2022 年对我来说变化很大,算是暂时摆脱了学生生活,体验了社畜的感觉,打卡了北上广深中的北和深。\n接下来按月份盘点一些值得纪念的事情吧。\n一月:\n这一月大多是在学校里度过的,封校了很长时间,封校期间报名了送餐志愿者,每天都负责给大家配送三餐,有点累,但是感觉能听到大家感谢的声音以及幸福的笑容还是很值得的,我感觉我一直还挺乐于助人的,帮助别人其实还挺快乐的。值得一提的是,因为之前总喜欢续费超级会员,疫情期间还建了一个宿舍群,送餐期间也兼职在群里传达各种信息,虽然是个吃力不讨好的活,还因为一些过激的言论被挂到知乎说是官僚主义。\n二月:\n二月换了手机(iPhone 13),加入了果粉的队列,并在心中种下了苹果全家桶的种子。还和家人一起去了青岛的海洋馆玩,和从未见过的网友学弟面了基。\n三月:\n三月报名参加了 RMUS 2022 ,同时也在备赛 RMUA 2022 和准备大创的中期检查。搭建了一个新的 RMUA 场地。\n四月:\n移植了一个学术风的 Hexo 主题,搞了一个自己的学术主页,计划用于后面的申请夏令营等。\n五月:\n带队参加了 RMUA 2022,也担任了其中的赛事志愿者。今年的分组不错,可惜还是因为各种原因惨败了,很难受的一个月。回来还被隔离了七天,隔离的时候也无心学习,后面有考试和各种大作业的检查,这段时间是一年中最难受的时候。\n六月:\n六月是考试月,各种考试、各种大作业、各种 DDL,压的人喘不过气来。\n在 6月12日,基地也搬了新的场地,大二上学期刚加入基地的时候,基地也是新搬场地,现在,基地又新搬了场地,我也该退休了。\n七月:\n六月的结束也意味着学期的结束,假期的开始。七月学长邀请我去他公司实习,我欣然答应,于是我们就在学期结束后一起飞到了深圳,开始了社畜生活。在深圳的生活很愉快,也有了自己可以支配的收入,不再依赖于家里面的生活费了,也可以攒些小钱买自己想买的东西,这种感觉很棒。同时这个月还入手了 Airpods 3,空间音频给人的感觉很震撼。\n八月:\n八月继续社畜,做了社畜以后有了比学生生活期间更多的活动,也吃了更多的好吃的,成了KFC、麦当劳、海底捞、肉蟹煲的常客,每天都稳定点两次外卖。这个月还看了《请回答1988》的解说,真的很好看,是令人暖心的剧集。\n九月:\n九月要开学了,但是因为大四上学期已经没什么课了,而且深圳的疫情非常严重,没有返校。本月最重要的是我成了一名铲屎官(猫屎真的好臭😷),已经是人生赢家了,Siri 给他起名为卓卓。\n同时九月也是保研名单公布和保研结束一段时间,再三考虑后决定放弃了保研名额,跟学长一起创业,先在港中文做 RA,后面或许可以去那里读 Ph.D,想出去看看。\n这个月还因为要做 iOS 开发公司给配了 Mac,现在已经拥有 iPhone、iPad、Mac、Airpods,距离 Apple 全家桶只有一步之遥。\n哦对了,这个月还搬了新的住所,因为人逐渐变多了,之前的屋子已经住不下了。九月,真是繁忙的一月。\n十月:\n这个月初入手了 Apple Watch,补齐了个人设备的最后一块拼图算是。iMac 这种没有算进来,因为 iOS、iPadOS、MacOS、WatchOS 四个系统已经集齐了,苹果生态给人的感觉真的很不错。\n有了 Watch 以后,借着新鲜感锻炼了一段时间,但是体重不降反增了,于是动力没了,又回到了肥宅的生活😁。\n同时这个月还和乐乐和雷宝一起去了深圳的欢乐谷游玩,体验了失重的感觉,下次不敢了。\n十一月:平淡的一个月,上班、吃吃吃、玩玩玩。卓卓越来越好看了。\n十二月:\n学长从 HK 带回来了最新版的 Apple TV,苹果生态又添一员。现在的联动已经非常棒了,手机可以直接推流到 Homepod、电视、Mac、耳机等。\n因为疫情放开了,我也体验了一次阳性的感觉,不过只高烧了一天就好了,也没感觉有什么后遗症,同居的六个人已经阳了四个,希望不会短期内再次感染🙏。这个月还和学长一起去了趟北京,不过只住了一天就回来了。\n这个月也抽时间购买了 FirstUI-uniapp 框架,把之前发单小程序的界面重构了一下,算是一步步的把之前的屎山代码给救了回来。因为在公司也担任了 Code Viewer 的角色,越发感觉代码风格对编程很重要,一个好的代码规范能够提升编程的效率,无论是自己还是团队,学编程语言应该必学代码规范。\n总的来说,今年要比去年精彩的多,可能是因为了保研结束了,当了社畜,没有考研的压力,有了很多玩乐的时间,也有了可以自己支配的收入,虽然不是很多,但是生活和娱乐已经够用。\n不过当了社畜,算是脱离了象牙塔进入了社会,也听到了各种各样在学校听不见的声音,引发了蛮多思考🤔。\n同时新的一年也看了更多的书、学到了很多新的知识,Modern C++、Rust、Swift、SwiftUI、Vue3 等等,拓宽了自己知识面。无限进步,无论什么时候都要坚持读书,我感觉读书仍是目前收益非常高的一个选择,即使读一些很久远的书,也能从中获得各种各样的启发,希望新的一年我也可以坚持不懈的读书!\n","permalink":"https://blog.zzsqwq.cn/posts/summary-2022/","summary":"2022 依旧是被疫情伴随的一年,时间正着看总是要比回看慢很多,现在回头看过往一年似乎一瞬间就过去了。\n今年共发了 11 篇文章,其中还包含了两篇碎碎念,还是没有达到月更,新的一年希望可以。2022 年对我来说变化很大,算是暂时摆脱了学生生活,体验了社畜的感觉,打卡了北上广深中的北和深。\n接下来按月份盘点一些值得纪念的事情吧。\n一月:\n这一月大多是在学校里度过的,封校了很长时间,封校期间报名了送餐志愿者,每天都负责给大家配送三餐,有点累,但是感觉能听到大家感谢的声音以及幸福的笑容还是很值得的,我感觉我一直还挺乐于助人的,帮助别人其实还挺快乐的。值得一提的是,因为之前总喜欢续费超级会员,疫情期间还建了一个宿舍群,送餐期间也兼职在群里传达各种信息,虽然是个吃力不讨好的活,还因为一些过激的言论被挂到知乎说是官僚主义。\n二月:\n二月换了手机(iPhone 13),加入了果粉的队列,并在心中种下了苹果全家桶的种子。还和家人一起去了青岛的海洋馆玩,和从未见过的网友学弟面了基。\n三月:\n三月报名参加了 RMUS 2022 ,同时也在备赛 RMUA 2022 和准备大创的中期检查。搭建了一个新的 RMUA 场地。\n四月:\n移植了一个学术风的 Hexo 主题,搞了一个自己的学术主页,计划用于后面的申请夏令营等。\n五月:\n带队参加了 RMUA 2022,也担任了其中的赛事志愿者。今年的分组不错,可惜还是因为各种原因惨败了,很难受的一个月。回来还被隔离了七天,隔离的时候也无心学习,后面有考试和各种大作业的检查,这段时间是一年中最难受的时候。\n六月:\n六月是考试月,各种考试、各种大作业、各种 DDL,压的人喘不过气来。\n在 6月12日,基地也搬了新的场地,大二上学期刚加入基地的时候,基地也是新搬场地,现在,基地又新搬了场地,我也该退休了。\n七月:\n六月的结束也意味着学期的结束,假期的开始。七月学长邀请我去他公司实习,我欣然答应,于是我们就在学期结束后一起飞到了深圳,开始了社畜生活。在深圳的生活很愉快,也有了自己可以支配的收入,不再依赖于家里面的生活费了,也可以攒些小钱买自己想买的东西,这种感觉很棒。同时这个月还入手了 Airpods 3,空间音频给人的感觉很震撼。\n八月:\n八月继续社畜,做了社畜以后有了比学生生活期间更多的活动,也吃了更多的好吃的,成了KFC、麦当劳、海底捞、肉蟹煲的常客,每天都稳定点两次外卖。这个月还看了《请回答1988》的解说,真的很好看,是令人暖心的剧集。\n九月:\n九月要开学了,但是因为大四上学期已经没什么课了,而且深圳的疫情非常严重,没有返校。本月最重要的是我成了一名铲屎官(猫屎真的好臭😷),已经是人生赢家了,Siri 给他起名为卓卓。\n同时九月也是保研名单公布和保研结束一段时间,再三考虑后决定放弃了保研名额,跟学长一起创业,先在港中文做 RA,后面或许可以去那里读 Ph.D,想出去看看。\n这个月还因为要做 iOS 开发公司给配了 Mac,现在已经拥有 iPhone、iPad、Mac、Airpods,距离 Apple 全家桶只有一步之遥。\n哦对了,这个月还搬了新的住所,因为人逐渐变多了,之前的屋子已经住不下了。九月,真是繁忙的一月。\n十月:\n这个月初入手了 Apple Watch,补齐了个人设备的最后一块拼图算是。iMac 这种没有算进来,因为 iOS、iPadOS、MacOS、WatchOS 四个系统已经集齐了,苹果生态给人的感觉真的很不错。\n有了 Watch 以后,借着新鲜感锻炼了一段时间,但是体重不降反增了,于是动力没了,又回到了肥宅的生活😁。\n同时这个月还和乐乐和雷宝一起去了深圳的欢乐谷游玩,体验了失重的感觉,下次不敢了。\n十一月:平淡的一个月,上班、吃吃吃、玩玩玩。卓卓越来越好看了。\n十二月:\n学长从 HK 带回来了最新版的 Apple TV,苹果生态又添一员。现在的联动已经非常棒了,手机可以直接推流到 Homepod、电视、Mac、耳机等。","title":"2022 年度总结"},{"content":"前言 最近同居的学长从香港带了个最新版的 Apple TV 回来,但是 Apple TV 在国内用不了,必须要代理才可以,所以考虑到了路由器代理的方案。但是现在家里在用的路由器是 Redmi AX3000,没法刷固件,也不想再买个 R2S 这种软路由了,因此就计划将公司之前用完的 香橙派(OrangePi) 4 LTS 利用一下。它的芯片是 RK3399,用来做路由器绰绰有余,不用可惜了。\n为什么是旁路由? 不熟悉旁路由的同学可以看篇指南:从听说到上手,人人都能看懂的旁路由入门指南\n找了一些常见的固件,貌似只有针对于 OrangePi R1 和 OrangePi R1 Plus 编译的软路由固件,并且讯龙官方也有放出针对这两个板子的 Openwrt 固件1,可以说是就是为软路由而生,价格也比较便宜,200 左右,性能和 R2S 差别不大。\n试了一下在 4 LTS 上跑 R1 和 R1 Plus 的固件2,都无法正常点亮,可能可以自己编译一个对应架构的 OpenWrt,但是有点麻烦,还是没尝试。\n考虑到 4 LTS 上可以使用 Docker,因此可以在上面用 Docker 跑一个 OpenWrt 然后做旁路由,到时候只需要把 Apple TV 或者路由器的网关和 DNS 改一下就可以,因此最终选择使用旁路由方案。\n具体方案 这里直接参考了小苏的教程:https://mlapp.cn/376.html,写的很清晰,而且很好的考虑了没有基础的同学,赞一个!\n里面写的很详细,但是需要注意的是,因为香橙派4 LTS是 ARMv8 架构的,但是直接拉教程里面的默认 latest 镜像是 ARMv7 的,因此需要指定一下镜像的版本,具体的镜像版本可以看 Docker Hub 中的介绍。\ndocker pull registry.cn-shanghai.aliyuncs.com/suling/openwrt:armv8 --- docker run --restart always --name openwrt -d --network macnet --privileged registry.cn-shanghai.aliyuncs.com/suling/openwrt:armv8 /sbin/init 除此以外,根据它的指导来基本就不会有问题,其中如果需要给路由器下所有设备代理就把路由器的网关和 DNS 改为旁路由的 IP,如果是单独给某个设备(例如只给 Apple TV 终端),就可以只给单个设备设置 DNS 和 网关。\nUDP 代理 我们想在 Apple TV 上联机玩狂野飙车8,启动多人对战一直报加入服务器错误,观察了一下发现应该是 UDP 流量没有被代理到,因此开启了 OpenClash 的 TUN 模式,开启以后发现更糟了,直接无法上网。搜了一下发现已经有对应的 Issue,疑似是旁路由和 OpenClash 防火墙设置有冲突,删掉对应的规则即可。\n顺便说一句 Apple TV 真的有点香,这个价位,这个性能。\nhttps://openwrt.org/toh/xunlong/orange_pi_r1_plus\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nhttps://github.com/SuLingGG/OpenWrt-Rpi\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","permalink":"https://blog.zzsqwq.cn/posts/orangepi4-lts-with-openwrt/","summary":"前言 最近同居的学长从香港带了个最新版的 Apple TV 回来,但是 Apple TV 在国内用不了,必须要代理才可以,所以考虑到了路由器代理的方案。但是现在家里在用的路由器是 Redmi AX3000,没法刷固件,也不想再买个 R2S 这种软路由了,因此就计划将公司之前用完的 香橙派(OrangePi) 4 LTS 利用一下。它的芯片是 RK3399,用来做路由器绰绰有余,不用可惜了。\n为什么是旁路由? 不熟悉旁路由的同学可以看篇指南:从听说到上手,人人都能看懂的旁路由入门指南\n找了一些常见的固件,貌似只有针对于 OrangePi R1 和 OrangePi R1 Plus 编译的软路由固件,并且讯龙官方也有放出针对这两个板子的 Openwrt 固件1,可以说是就是为软路由而生,价格也比较便宜,200 左右,性能和 R2S 差别不大。\n试了一下在 4 LTS 上跑 R1 和 R1 Plus 的固件2,都无法正常点亮,可能可以自己编译一个对应架构的 OpenWrt,但是有点麻烦,还是没尝试。\n考虑到 4 LTS 上可以使用 Docker,因此可以在上面用 Docker 跑一个 OpenWrt 然后做旁路由,到时候只需要把 Apple TV 或者路由器的网关和 DNS 改一下就可以,因此最终选择使用旁路由方案。\n具体方案 这里直接参考了小苏的教程:https://mlapp.cn/376.html,写的很清晰,而且很好的考虑了没有基础的同学,赞一个!\n里面写的很详细,但是需要注意的是,因为香橙派4 LTS是 ARMv8 架构的,但是直接拉教程里面的默认 latest 镜像是 ARMv7 的,因此需要指定一下镜像的版本,具体的镜像版本可以看 Docker Hub 中的介绍。\ndocker pull registry.","title":"使用 OrangePi 4 LTS 做旁路由"},{"content":"前言 本文包含一些在使用 C++ 类时的注意事项,可避免一些常见问题,并能让你在写代码时更加自信。\n因为目前我使用的是 C++ 17,所以仅保证以下内容在 C++ 17 中正确。\n构造函数 对于单个参数的构造函数,推荐添加 explicit 关键字,防止隐式转换错误调用构造函数。 class DemoClass { explicit DemoClass(int test) { this-\u0026gt;test_ = test; } } 显式声明有参构造函数后,编译器不会自动生成无参构造函数,若需要,请添加 DemoClass() = default; class DemoClass { explicit DemoClass(int test) { this-\u0026gt;test_ = test; } DemoClass() = default; } 若子类中没有显式调用父类的构造函数,子类会默认调用父类的无参构造函数,如果父类没有无参构造函数,会报错。 析构函数 基类析构函数应该声明为 virtual,这样可以防止子类无法正确的析构。 由于基类析构函数为 virtual,派生类的析构函数应该显式的 override。 class DemoClass { virtual ~DemoClass() = default; } class ChildClass: public DemoClass { ~ChildClass() override { xxx; } } 成员变量默认值 对于类或局部作用域中未明确指定默认值的成员变量,其值遵循以下规则:\n对于原生类型(primitive types),即 int、float、int*、string* 等,默认值为随机的脏数据。 对于对象(objects),例如自定义类、或 std::string 等,会调用默认(无参)构造函数,若没有默认(无参)构造函数,则报错。 对于引用(reference)类型,例如 std::string\u0026amp;,必须赋初始值或在构造函数中初始化,若为初始化,则报错。 float age; // 脏数据、随机值(无意义),此时访问会出现未定义行为 int *ptr; // 脏数据、随机值(无意义),此时访问会出现未定义行为 string name; // 调用默认构造函数,对于 std::string 来说为空字符串 \u0026#34;\u0026#34; DemoClass demo; // 若 DemoClass 存在无参构造函数,则调用,否则编译错误 string *pname; // 脏数据、随机值(无意义),此时访问会出现未定义行为 string \u0026amp;rname; // 编译错误,必须显式初始化 const string \u0026amp;crname; // 同上,编译错误 成员变量初始化方式 初始化成员变量一般而言有四种方式,一般而言第二种和第四种方式为等价的,不过在下面我们会看到一种例外:\nclass DemoClass { int a = 1; // (1) 通过 a == 1 int a{1}; // (2) 通过 a == 1 int a(1); // (3) 报错,只能用于对对象的初始化 int a = {1}; // (4)通过 a == 1 } 总体而言,推荐使用第二种方式,更加通用、现代、安全。\n只不过在使用存在以 std::initializer_list 为参数做初始化的对象时,推荐使用第三种方式,第二种方式会导致非常贪婪的构造调用,详情可见:Item 7:区别使用()和{}创建对象 - Effective Modern C++\n同时,对于某些对象,例如 std::vector,第二种方式与第三种方式存在区别,此时要根据使用意图区别调用:\nstd::vector vec(10, 20); // vec 包含 10 个元素,值均为 20 std::vector vec{10, 20}; // vec 包含 10, 20 两个元素 此外,在 C++17 之前,在搭配使用 auto 和 {} 时会产生奇怪的行为,同时在这里带 = 和不带 = 的 {} 会出现差别:\nauto a{1}; // C++17 之前 a 为 std::initializer_list\u0026lt;int\u0026gt;,之后为 int auto a = {1}; // a 为 std::initializer_list\u0026lt;int\u0026gt; auto a = 1; // a 为 int auto a{1, 2}; // 报错! auto a = {1, 2}; // a 为 std::initializer_list\u0026lt;int\u0026gt; 更进一步 为什么推荐使用第二种方式?\nC++11 引入了 {} 这种称为统一初始化(uniform initialization)的语法来整合那些混乱且不适于所有情景的初始化语法。\n为什么叫统一初始化?看以下几个例子:\nclass DemoClass{ … private: int x{ 0 }; //没问题,x初始值为0 int y = 0; //也可以 int z(0); //错误! } 这里,z 为一个原生类型,而不是对象,无法使用 () 来对其初始化。\n而 = 也不是总是可用的,不可赋值拷贝构造的对象(例如std::atomic——见Item40)可以使用花括号初始化或者小括号初始化,但是不能使用 = 初始化:\nstd::atomic\u0026lt;int\u0026gt; ai1{ 0 }; //没问题 std::atomic\u0026lt;int\u0026gt; ai2(0); //没问题 std::atomic\u0026lt;int\u0026gt; ai3 = 0; //错误! 因此我们很容易理解为什么 {} 初始化又叫统一初始化,在 C++ 中这三种方式都被指派为初始化表达式(而不是什么函数声明或者拷贝构造),但是只有 {} 任何地方都能被使用。\n参考资料及拓展阅读资料 How do C++ class members get initialized if I don\u0026rsquo;t do it explicitly?\nWhy does auto x{3} deduce an initializer_list?\nmariusbancila.ro\nhttps://cntransgroup.github.io/EffectiveModernCppChinese/3.MovingToModernCpp/item7.html\n","permalink":"https://blog.zzsqwq.cn/posts/cxx-class-skills/","summary":"前言 本文包含一些在使用 C++ 类时的注意事项,可避免一些常见问题,并能让你在写代码时更加自信。\n因为目前我使用的是 C++ 17,所以仅保证以下内容在 C++ 17 中正确。\n构造函数 对于单个参数的构造函数,推荐添加 explicit 关键字,防止隐式转换错误调用构造函数。 class DemoClass { explicit DemoClass(int test) { this-\u0026gt;test_ = test; } } 显式声明有参构造函数后,编译器不会自动生成无参构造函数,若需要,请添加 DemoClass() = default; class DemoClass { explicit DemoClass(int test) { this-\u0026gt;test_ = test; } DemoClass() = default; } 若子类中没有显式调用父类的构造函数,子类会默认调用父类的无参构造函数,如果父类没有无参构造函数,会报错。 析构函数 基类析构函数应该声明为 virtual,这样可以防止子类无法正确的析构。 由于基类析构函数为 virtual,派生类的析构函数应该显式的 override。 class DemoClass { virtual ~DemoClass() = default; } class ChildClass: public DemoClass { ~ChildClass() override { xxx; } } 成员变量默认值 对于类或局部作用域中未明确指定默认值的成员变量,其值遵循以下规则:","title":"C++ 类使用注意事项"},{"content":"楔子 昨天听了学弟们关于博客搭建的一些教程,在听的过程中,也想起了我之前对于博客的种种尝试,发现整体的趋势就是,简约再简约。\n这引发了我对我过去几年的审视,感觉自己的审美一直在变化,对于美的认识和感受也是一直在变的,故写此文来记一些我对美认识的思考。\n简约是我最终的归宿 遥记得我还在小学和初中时,非常迷恋 QQ飞车 这款游戏,这款游戏里面有一个虚拟人物,人物可以搭配各种装饰,包括但不限于上衣、裤子、发型、发饰、翅膀等,起初我是喜欢要多花哨有多花哨造型,各种发饰、翅膀、脸部特效搞的飞起,现在想起来真是非常搞笑,而且喜欢五颜六色的,当时觉得,真的是太好看了。\n但是过了一段时间,就开始感觉不对劲了,这么花哨,这么丑,这怎么可能是我当时亲手选择的造型。后来就逐渐向简约范靠拢,装饰越简单,色调越单一越喜欢。\n下面的几张图大致可以窥见这个过程:\n而长大后,对于 Blog 的搭建貌似也是这个过程。一开始喜欢相对花哨的,包括各种炫酷的背景、动效等,因此一开始选择了高定制度、有各种花哨特效的 Hexo 框架,不过当时已经在飞车中喜欢上了简约风格,因此主题也选择了 Hexo 中相对简洁的 NexT 主题。\n后来发现 Hexo 实在操作过程有些过于繁杂,从操作的意义上来说,他无法做到足够的简洁、简约和高效。\n故而我选择了操作更加方便(例如发表博文、操作主题元素)更加方便的动态博客——Typecho。\n起初,我选择延续了在 Hexo 上的 NexT 主题,后来发现了更加符合我审美的 Handsome 主题,第一眼就是非常喜欢,后来忍痛买了主题,用了一段时间后,又逐渐觉得主题没有那么好看,有些看腻了,而且动态博客的升级、安装插件,也是十分繁杂。\n最后,偶然之下,发现了现在在使用的 Hugo 框架,它生成迅速、无需升级、也有着很多简约风的主题,完美符合我的需求,果断迁移了过来,具体流程可见:记一次博客迁移记录 - Zs\u0026rsquo;s Blog ,一直用到现在,还是对这个框架和主题算是相对满意的。\n总体而言,无论是操作还是页面,都是越来越简约、统一了。不知道未来,我会不会觉得这个也不够简约和统一,再去找寻其他的框架呢。\n各种产品的变迁 除了上面我自己对美认识的变化,我觉得整个社会对美的认识也是存在变化的。\n往大了讲,是各种建筑、各种设施外观的变化。\n往小了讲,我们用的手机、手机上的软件(例如 QQ、微信),他们的外观每年都在迭代,可能每次变化时有人吐槽有人叫好,但是整体而言,至少对我来说,他是整体都是越来越好看的,虽然逐渐变得臃肿,但是 UI 确实是“实打实”的在进步。下图是 QQ 的变化(左侧是网友仿的一个老版 QQ 界面1,右图是最新版 Mac QQ),可见一二:\n那就引发了我一个思考,大家对于美的认识是被塑造了呢,还是说这个东西就是客观上的变好看了,美毕竟是一个比较主观的东西。\n如果他是主观上变好看了,那么他是真的好看了吗?而且为什么可以做到如此的统一,让大多数人都觉得变好看了。\n如果他是客观上变好看了,那么到底是什么因素的存在让人觉得他好看呢?\n我觉得美这个东西,很不像生活中常见的发展规律,例如芯片的研发,需要数学、物理、化学等学科实际理论的支持。\n2001 年的人是没有办法设计出 Apple M2 的芯片的,因为受到了各种硬件的制约。而 2001 年的设计师有没有可能设计出最新版 Mac QQ 这样的界面呢,如果不能,是什么制约着它呢?如果能,为什么没有出现这种设计,是因为当时大家觉得他不好看吗?\n因为我不是学设计和美术等专业的,并且这种很很直觉的东西我不知道该怎么去搜索,因此想在这里和大家探讨一下。如果有已经相对成熟的理论,还请大家能够告知与我,解答困扰我好久的疑问。\nAI 绘图 看网上有人调侃说,愿意称 2022 年为 AI 绘图元年。\n今年确实是突然涌现出非常多的 AI 绘图模型,并且画的还都是有模有样。这也让我想起来之前在 2021年6月 参加过学院的一个 01 学术沙龙2,主题为 “计算 + 艺术 = ∞”。当时在会上和老师们探讨过,是否机器可以理解作品中美的元素,能够理解作品中美的模式?当时大家都是各有各的看法,我个人是持乐观态度的。我觉得美的元素和美的模式,可能是客观存在的,机器人能够让一幅画符合某个模式,来让人觉得这幅画美。\n但是,机器人能否创作出独创性作品,而不是学习、融合之前元素内容,这个还不好说。会不会,这世界上艺术(画作)美的元素、或者美的模式存在是确定的、种类也是确定的,这样如果机器人全部学习到,岂不是可以看作是拿到了整个解空间的基向量,可以创作出任意风格、任意元素的内容了。\n希望不会是这样。\nhttps://www.cnblogs.com/zym/archive/2013/03/01/2939441.html\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nhttps://jsj.nwpu.edu.cn/info/1598/9734.htm\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","permalink":"https://blog.zzsqwq.cn/posts/beauty-think/","summary":"楔子 昨天听了学弟们关于博客搭建的一些教程,在听的过程中,也想起了我之前对于博客的种种尝试,发现整体的趋势就是,简约再简约。\n这引发了我对我过去几年的审视,感觉自己的审美一直在变化,对于美的认识和感受也是一直在变的,故写此文来记一些我对美认识的思考。\n简约是我最终的归宿 遥记得我还在小学和初中时,非常迷恋 QQ飞车 这款游戏,这款游戏里面有一个虚拟人物,人物可以搭配各种装饰,包括但不限于上衣、裤子、发型、发饰、翅膀等,起初我是喜欢要多花哨有多花哨造型,各种发饰、翅膀、脸部特效搞的飞起,现在想起来真是非常搞笑,而且喜欢五颜六色的,当时觉得,真的是太好看了。\n但是过了一段时间,就开始感觉不对劲了,这么花哨,这么丑,这怎么可能是我当时亲手选择的造型。后来就逐渐向简约范靠拢,装饰越简单,色调越单一越喜欢。\n下面的几张图大致可以窥见这个过程:\n而长大后,对于 Blog 的搭建貌似也是这个过程。一开始喜欢相对花哨的,包括各种炫酷的背景、动效等,因此一开始选择了高定制度、有各种花哨特效的 Hexo 框架,不过当时已经在飞车中喜欢上了简约风格,因此主题也选择了 Hexo 中相对简洁的 NexT 主题。\n后来发现 Hexo 实在操作过程有些过于繁杂,从操作的意义上来说,他无法做到足够的简洁、简约和高效。\n故而我选择了操作更加方便(例如发表博文、操作主题元素)更加方便的动态博客——Typecho。\n起初,我选择延续了在 Hexo 上的 NexT 主题,后来发现了更加符合我审美的 Handsome 主题,第一眼就是非常喜欢,后来忍痛买了主题,用了一段时间后,又逐渐觉得主题没有那么好看,有些看腻了,而且动态博客的升级、安装插件,也是十分繁杂。\n最后,偶然之下,发现了现在在使用的 Hugo 框架,它生成迅速、无需升级、也有着很多简约风的主题,完美符合我的需求,果断迁移了过来,具体流程可见:记一次博客迁移记录 - Zs\u0026rsquo;s Blog ,一直用到现在,还是对这个框架和主题算是相对满意的。\n总体而言,无论是操作还是页面,都是越来越简约、统一了。不知道未来,我会不会觉得这个也不够简约和统一,再去找寻其他的框架呢。\n各种产品的变迁 除了上面我自己对美认识的变化,我觉得整个社会对美的认识也是存在变化的。\n往大了讲,是各种建筑、各种设施外观的变化。\n往小了讲,我们用的手机、手机上的软件(例如 QQ、微信),他们的外观每年都在迭代,可能每次变化时有人吐槽有人叫好,但是整体而言,至少对我来说,他是整体都是越来越好看的,虽然逐渐变得臃肿,但是 UI 确实是“实打实”的在进步。下图是 QQ 的变化(左侧是网友仿的一个老版 QQ 界面1,右图是最新版 Mac QQ),可见一二:\n那就引发了我一个思考,大家对于美的认识是被塑造了呢,还是说这个东西就是客观上的变好看了,美毕竟是一个比较主观的东西。\n如果他是主观上变好看了,那么他是真的好看了吗?而且为什么可以做到如此的统一,让大多数人都觉得变好看了。\n如果他是客观上变好看了,那么到底是什么因素的存在让人觉得他好看呢?\n我觉得美这个东西,很不像生活中常见的发展规律,例如芯片的研发,需要数学、物理、化学等学科实际理论的支持。\n2001 年的人是没有办法设计出 Apple M2 的芯片的,因为受到了各种硬件的制约。而 2001 年的设计师有没有可能设计出最新版 Mac QQ 这样的界面呢,如果不能,是什么制约着它呢?如果能,为什么没有出现这种设计,是因为当时大家觉得他不好看吗?\n因为我不是学设计和美术等专业的,并且这种很很直觉的东西我不知道该怎么去搜索,因此想在这里和大家探讨一下。如果有已经相对成熟的理论,还请大家能够告知与我,解答困扰我好久的疑问。\nAI 绘图 看网上有人调侃说,愿意称 2022 年为 AI 绘图元年。","title":"关于美的一些思考"},{"content":"前言 我们使用搜索引擎可能是为了搜集信息、或者是解决一些问题。但如果不能正确的使用搜索引擎,使用关键字等,可能搜到的答案就与问题相关不大,或者与我们的问题相差甚远。\n这篇文章意在分享我个人在学习、工作中使用搜索引擎的一些技巧与思考,可能后续会不断的更新,如有纰漏,还请大家指正。\n应该使用什么搜索平台? 想要提高搜索的效率,选择一个好的搜索引擎或者内容平台颇为重要。\n下面列举的是我平时会使用的一些平台,列出的顺序代表了我个人对于他们的推荐程度:\n通用搜索引擎:Google、Bing、DuckDuckGo、Baidu 编程相关问题:Stack Overflow、Github Issue、segmentfault、稀土掘金、腾讯云开发者社区、CSDN、华为云开发者社区 日常问题:V2EX 第一类为通用搜索引擎,例如 为什么最近头发掉的更多了? 在其上可以搜索任何问题,其中 Google 的使用门槛相对较高,而 Bing 针对国内用户来说是一个相对不错的选择,不建议常用 Baidu,因为其上广告非常多,有用信息密度相对较小。\n第二类为编程相关问题,例如 CMake 为什么报错了? 其中 Stack Overflow、Github 虽均为国外的平台,但是国内是可以访问的,不过在 Baidu 搜索引擎中词条相对靠后,同时也需要使用英文来进行问题检索。(Btw,Stack 系列还有例如 Stack Exchange 平台,它的模式与前者相同,但是更偏日常一些。)除此以外,后面的平台均为国内平台,所列是我平时常见的一些,整体而言,前面的文章质量普遍会比后面的高一些,其中腾讯云开发者社区、CSDN、华为云开发者社区三者内容重叠度较高。\n第三类为日常问题,例如 Mac 上有什么好用的 App ?可以在 V2EX 上寻找答案,当然,它也是包罗万象的,只不过我常用它来解决日常各类小问题。\n如何正确的知道问题所在? 我们遇到一个问题,要首先能够定位这个问题的关键。\n例如编译中出错了,可能有很多 log,你必须能够精确定位到到底哪一条 log 才是这次编译出错的关键,进而才能解决这个问题。\n以 CMake 为例,编译时报错 log 一般为红色,警告 log 一般为黄色,普通 log 一般为白色。得益于这种等级/颜色分明的 log ,我们可以快速的定位报错。我们日常编程中,为了便于 Debug,最好也遵循这个规范,例如在 C++ 中打印错误 log 时推荐使用 std::stderr 而不是 std::stdout 。\n见过很多身边的同学遇到了报错,就一股脑粘贴所有的报错 log,然后贴到搜索引擎中,发现相关的错误基本没有。这就是没有其中错误的关键,报错时的 log 可能 100 行只有 10 行是关键的,甚至只有一行是关键的,例如 100 行 log 中只有 未定义的引用(undefined reference to \u0026lsquo;xxx\u0026rsquo;) 这一句是最关键的。\n搜索不到怎么办? 即使你选择了正确的平台,筛选出了关键的报错信息,你可能仍然无法搜索到对应的问题,这怎么办呢?\n首先,你可能需要转换一下语言,例如之前问题采用中文,你应该将其翻译成英文再重新搜索,记得翻译时要保证专有名词的正确性。\n如果还是不行,这个时候我认为应该首先静下心来思考一下这是属于什么问题,是这个程序特有的问题,还是这个程序使用的某个库或部件导致的问题?你可能需要仔细思考来进一步提取错误(问题)中的关键所在,使用提取的关键字继续搜索或者去查对应的程序或者库的 Q\u0026amp;A ,如果还是无法找到,就应该去看相应部分的文档,去 RTFM(Read The Fantastic Manual)。\n最后的最后,还是无法找到的话,那你就应该考虑去对应程序、库或部件的 Github Issue 或者论坛、或非定向的 Stack Overflow 等平台提交问题,在提问之前,你最好仔细阅读过 提问的智慧1,不然可能无法获得到热情、友善的回复。\n上图所示是我之前 有关 Microsoft Edge 的一个提问 ,应该可以算是一个相对正确的示范。\n最好积累一个错误文档 感觉这个的作用有点类似于高中时候老师们推崇的错题本了,虽然我一直觉得没啥用,也几乎没有照做过。\n但是在平常解决问题时我确实是会遇到,上次明明遇到过类似的问题,我也解决了,但是再遇到又忘了如何解决了。可能是因为随着年纪的增大记性越来越差了🤣,不过如果大家不嫌麻烦可以养成每次遇错都能记录一下,估计坚持下来会非常的有用(虽然我自己都没做到)。\nEnglish version: http://www.catb.org/~esr/faqs/smart-questions.html\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","permalink":"https://blog.zzsqwq.cn/posts/how-to-search/","summary":"前言 我们使用搜索引擎可能是为了搜集信息、或者是解决一些问题。但如果不能正确的使用搜索引擎,使用关键字等,可能搜到的答案就与问题相关不大,或者与我们的问题相差甚远。\n这篇文章意在分享我个人在学习、工作中使用搜索引擎的一些技巧与思考,可能后续会不断的更新,如有纰漏,还请大家指正。\n应该使用什么搜索平台? 想要提高搜索的效率,选择一个好的搜索引擎或者内容平台颇为重要。\n下面列举的是我平时会使用的一些平台,列出的顺序代表了我个人对于他们的推荐程度:\n通用搜索引擎:Google、Bing、DuckDuckGo、Baidu 编程相关问题:Stack Overflow、Github Issue、segmentfault、稀土掘金、腾讯云开发者社区、CSDN、华为云开发者社区 日常问题:V2EX 第一类为通用搜索引擎,例如 为什么最近头发掉的更多了? 在其上可以搜索任何问题,其中 Google 的使用门槛相对较高,而 Bing 针对国内用户来说是一个相对不错的选择,不建议常用 Baidu,因为其上广告非常多,有用信息密度相对较小。\n第二类为编程相关问题,例如 CMake 为什么报错了? 其中 Stack Overflow、Github 虽均为国外的平台,但是国内是可以访问的,不过在 Baidu 搜索引擎中词条相对靠后,同时也需要使用英文来进行问题检索。(Btw,Stack 系列还有例如 Stack Exchange 平台,它的模式与前者相同,但是更偏日常一些。)除此以外,后面的平台均为国内平台,所列是我平时常见的一些,整体而言,前面的文章质量普遍会比后面的高一些,其中腾讯云开发者社区、CSDN、华为云开发者社区三者内容重叠度较高。\n第三类为日常问题,例如 Mac 上有什么好用的 App ?可以在 V2EX 上寻找答案,当然,它也是包罗万象的,只不过我常用它来解决日常各类小问题。\n如何正确的知道问题所在? 我们遇到一个问题,要首先能够定位这个问题的关键。\n例如编译中出错了,可能有很多 log,你必须能够精确定位到到底哪一条 log 才是这次编译出错的关键,进而才能解决这个问题。\n以 CMake 为例,编译时报错 log 一般为红色,警告 log 一般为黄色,普通 log 一般为白色。得益于这种等级/颜色分明的 log ,我们可以快速的定位报错。我们日常编程中,为了便于 Debug,最好也遵循这个规范,例如在 C++ 中打印错误 log 时推荐使用 std::stderr 而不是 std::stdout 。\n见过很多身边的同学遇到了报错,就一股脑粘贴所有的报错 log,然后贴到搜索引擎中,发现相关的错误基本没有。这就是没有其中错误的关键,报错时的 log 可能 100 行只有 10 行是关键的,甚至只有一行是关键的,例如 100 行 log 中只有 未定义的引用(undefined reference to \u0026lsquo;xxx\u0026rsquo;) 这一句是最关键的。","title":"如何善用搜索引擎?"},{"content":"为什么要使用条件变量? 前言 最近看了很多与线程有关的 C++ 新特性,条件变量是见的比较多的一个特性。\n看的时候我发现,想要理解一个新的特性,关键的要看它的引入到底解决了哪些问题,没有什么特性我们要实现相同的功能要怎么做?\n以我的理解来看,条件变量是一个线程间互相同步与通知的手段,他通过主动唤醒的方式减小了各个线程的开销,取代了简单但是消耗较大的一直被动循环检验与等待。\n没有条件变量我们如何实现相同的需求? 这里采用现代C++教程1 中关于条件变量的一个例子作为基础:\n不使用条件变量版本 #include \u0026lt;queue\u0026gt; #include \u0026lt;chrono\u0026gt; #include \u0026lt;mutex\u0026gt; #include \u0026lt;thread\u0026gt; #include \u0026lt;iostream\u0026gt; #include \u0026lt;condition_variable\u0026gt; int main() { std::queue\u0026lt;int\u0026gt; produced_nums; std::mutex mtx; // 生产者 auto producer = [\u0026amp;]() { for (int i = 0; ; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(900)); std::unique_lock\u0026lt;std::mutex\u0026gt; lock(mtx); std::cout \u0026lt;\u0026lt; \u0026#34;producing \u0026#34; \u0026lt;\u0026lt; i \u0026lt;\u0026lt; std::endl; produced_nums.push(i); } }; // 消费者 auto consumer = [\u0026amp;]() { while (true) { { std::unique_lock\u0026lt;std::mutex\u0026gt; lock(mtx); if(produced_nums.empty()) continue; } std::unique_lock\u0026lt;std::mutex\u0026gt; lock(mtx); // 短暂取消锁,使得生产者有机会在消费者消费空前继续生产 lock.unlock(); // 消费者慢于生产者 std::this_thread::sleep_for(std::chrono::milliseconds(1000)); lock.lock(); while (!produced_nums.empty()) { std::cout \u0026lt;\u0026lt; \u0026#34;consuming \u0026#34; \u0026lt;\u0026lt; produced_nums.front() \u0026lt;\u0026lt; std::endl; produced_nums.pop(); } } }; // 分别在不同的线程中运行 std::thread p(producer); std::thread cs[2]; for (int i = 0; i \u0026lt; 2; ++i) { cs[i] = std::thread(consumer); } p.join(); for (int i = 0; i \u0026lt; 2; ++i) { cs[i].join(); } return 0; } 使用条件变量版本 #include \u0026lt;queue\u0026gt; #include \u0026lt;chrono\u0026gt; #include \u0026lt;mutex\u0026gt; #include \u0026lt;thread\u0026gt; #include \u0026lt;iostream\u0026gt; #include \u0026lt;condition_variable\u0026gt; int main() { std::queue\u0026lt;int\u0026gt; produced_nums; std::mutex mtx; std::condition_variable cv; bool notified = false; // 通知信号 // 生产者 auto producer = [\u0026amp;]() { for (int i = 0; ; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(900)); std::unique_lock\u0026lt;std::mutex\u0026gt; lock(mtx); std::cout \u0026lt;\u0026lt; \u0026#34;producing \u0026#34; \u0026lt;\u0026lt; i \u0026lt;\u0026lt; std::endl; produced_nums.push(i); notified = true; cv.notify_all(); // 此处也可以使用 notify_one } }; // 消费者 auto consumer = [\u0026amp;]() { while (true) { std::unique_lock\u0026lt;std::mutex\u0026gt; lock(mtx); while (!notified) { // 避免虚假唤醒 cv.wait(lock); } // 短暂取消锁,使得生产者有机会在消费者消费空前继续生产 lock.unlock(); // 消费者慢于生产者 std::this_thread::sleep_for(std::chrono::milliseconds(1000)); lock.lock(); while (!produced_nums.empty()) { std::cout \u0026lt;\u0026lt; \u0026#34;consuming \u0026#34; \u0026lt;\u0026lt; produced_nums.front() \u0026lt;\u0026lt; std::endl; produced_nums.pop(); } notified = false; } }; // 分别在不同的线程中运行 std::thread p(producer); std::thread cs[2]; for (int i = 0; i \u0026lt; 2; ++i) { cs[i] = std::thread(consumer); } p.join(); for (int i = 0; i \u0026lt; 2; ++i) { cs[i].join(); } return 0; } 这两段代码在效果上是等效的,都是一个生产者两个消费者。\n前者使用了 while 循环来一直检查是否可以消费,后者使用了 cv.wait(lock) 条件变量来实现阻塞等待可消费的提醒。\n可以发现在这个例子里,前者是主动的去检查是否可以消费,后者是被动的被提醒可以消费,而主动则代表着需要一直询问查询,主动的 while 循环检查始终在重复如下流程:\n而这个上锁、检查、释放锁的过程就是非常冗余、消耗资源、效率低下的,而条件变量解决了这个问题,条件变量做的事:\n这里需要注意的一点是,在条件变量调用 wait() 时,做了两件事,一个是阻塞线程等待其他线程唤醒、另一个是释放锁,只有这样才会让别的线程有机会获得锁,而被唤醒后又会自动上锁。\n为什么要和 mutex 与 lock 一起用? 我们常见的搭配就是 condition_variable、mutex、unique_lock 一起使用,那么为什么要这么做呢?\n一个比较常见的说法是,在调用 wait() 函数与线程真正的阻塞等待状态是存在一定时间差的,那么就会存在唤醒丢失的问题,一种情况如下:\n线程A: ------- 调用 wait() 函数 ------- 进入等待状态 ------ 线程B: -------------------------唤醒A------------------- 而我们希望的是:\n线程A: ------- 调用 wait() 函数 ------- 进入等待状态 ------ 线程B: -------------------------------------------唤醒A- 我们总是要确保,在线程 A 真正进入等待状态后再进行唤醒,因此这里需要一个 lock 来保证我们对于一个线程空闲/等待的改变是原子性的,也就是不应该被其他线程中途干扰。\n为什么使用 unique_lock 而不使用 scoped_lock 或 lock_guard 首先三个函数都是 RAII 的锁管理函数,可以有效解决 lock 后忘记 unlock 的情形,而目前在 C++17 后推荐统一使用 scoped_lock 而不是 lock_guard。\n而使用 unique_lock 是因为我们在使用条件变量时,需要在条件变量 wait 时解除 lock,只有 unique_lock 能够满足这个条件,实现自己更细粒度的锁区间的划分。\n什么是虚假唤醒? 可以注意到在第一部分代码中有这么一段:\nauto consumer = [\u0026amp;]() { while (true) { std::unique_lock\u0026lt;std::mutex\u0026gt; lock(mtx); while (!notified) { // 避免虚假唤醒 cv.wait(lock); } // ... notified = false; } }; 避免虚假唤醒,那么什么是虚假唤醒呢?\n虚假唤醒简而言之就是,没有满足消费的条件却被唤醒后进行了消费。\n这个发生的可能多是在系统调度层面,具体的可以参考此知乎问题:为什么条件锁会产生虚假唤醒现象(spurious wakeup)?\n而解决的方案就是在消费之前再检查一下是否满足消费的条件,而这个消费条件多是用一个形如 notified 的 bool 变量来标识是否可以消费。\n如果不检查,带条件变量的执行流程就会像如下这样:\n其中少了一步检查是否可以消费的过程。\n后记 本文记录了我在学习条件变量过程中的一些疑问,如有错误之处,敬请交流指正。\nhttps://changkun.de/modern-cpp/\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","permalink":"https://blog.zzsqwq.cn/posts/why-use-condition-variable/","summary":"为什么要使用条件变量? 前言 最近看了很多与线程有关的 C++ 新特性,条件变量是见的比较多的一个特性。\n看的时候我发现,想要理解一个新的特性,关键的要看它的引入到底解决了哪些问题,没有什么特性我们要实现相同的功能要怎么做?\n以我的理解来看,条件变量是一个线程间互相同步与通知的手段,他通过主动唤醒的方式减小了各个线程的开销,取代了简单但是消耗较大的一直被动循环检验与等待。\n没有条件变量我们如何实现相同的需求? 这里采用现代C++教程1 中关于条件变量的一个例子作为基础:\n不使用条件变量版本 #include \u0026lt;queue\u0026gt; #include \u0026lt;chrono\u0026gt; #include \u0026lt;mutex\u0026gt; #include \u0026lt;thread\u0026gt; #include \u0026lt;iostream\u0026gt; #include \u0026lt;condition_variable\u0026gt; int main() { std::queue\u0026lt;int\u0026gt; produced_nums; std::mutex mtx; // 生产者 auto producer = [\u0026amp;]() { for (int i = 0; ; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(900)); std::unique_lock\u0026lt;std::mutex\u0026gt; lock(mtx); std::cout \u0026lt;\u0026lt; \u0026#34;producing \u0026#34; \u0026lt;\u0026lt; i \u0026lt;\u0026lt; std::endl; produced_nums.push(i); } }; // 消费者 auto consumer = [\u0026amp;]() { while (true) { { std::unique_lock\u0026lt;std::mutex\u0026gt; lock(mtx); if(produced_nums.","title":"为什么要使用条件变量?"},{"content":"背景 之前看到过学长学姐做过个人主页,多是用来申请一些学校的夏令营使用的,觉得非常的 Nice,自己也想搞一个。\n大家之前好像大多用的是基于 Hexo 的一个主题 — hexo-theme-academia,但是由于之前我用过 Hexo,觉得他有一些比较明显的弊端,例如环境配置比较麻烦、需要安装 Nodejs、npm 等环境,然后再安装 Hexo。其次它的构建速度比较慢,用起来感觉比较僵硬。\n后来随着了解增多,尝试了 Typecho、WordPress,Hugo 等主题后,目前还是决定使用 Hugo。它构建速度快,而且安装简单,在 Ubuntu 上只需要一行 sudo apt install hugo 即可,不可谓不简单。因此萌生了移植一个 Hugo 版本主题的想法,刚好可以锻炼一下自己。\n欢迎点击 这里 查看我的个人主页。\n一些难点 之前从来没有了解过 Hugo 主题的写法以及 Hexo 主题的写法,不过看了一下仓库的组织形式还算好理解。\n这类静态博客生成器都是需要写一些模板文件,然后根据配置文件进行个性化构建。\nHugo 的文档 十分的完善,学习就像是学习一门编程语言,里面有很多函数和变量,还有各种条件结构、循环结构等。原主题是采用的 pug + stylus 的方式,而不是传统的 html + css 。不过这两者之间的转换并不麻烦,而且有一些工具可以参考着转换,例如 pug2html 以及 stylus2css 。\n后续就参考着一点点的移植就可以,同时我也改写了一下配置文件(使用的 yaml 格式),大概是更易于配置了。\n同时,得益于 Hugo 的强大,我很方便的完成了对多语言的支持。\n最终效果 目前已经更新到了 v1.1.0 版本,欢迎大家体验,有问题可以及时反馈!\n主题链接:https://github.com/zzsqwq/hugo-academia-theme\n演示站:https://zzsqwq.github.io/academic-pages-demo/\n英文文档:https://github.com/zzsqwq/hugo-academia-theme/blob/master/README.md\n中文文档:https://github.com/zzsqwq/hugo-academia-theme/blob/master/README.zh_cn.md\n英文效果图:\n中文效果图:\n","permalink":"https://blog.zzsqwq.cn/posts/my-hugo-academia-theme/","summary":"背景 之前看到过学长学姐做过个人主页,多是用来申请一些学校的夏令营使用的,觉得非常的 Nice,自己也想搞一个。\n大家之前好像大多用的是基于 Hexo 的一个主题 — hexo-theme-academia,但是由于之前我用过 Hexo,觉得他有一些比较明显的弊端,例如环境配置比较麻烦、需要安装 Nodejs、npm 等环境,然后再安装 Hexo。其次它的构建速度比较慢,用起来感觉比较僵硬。\n后来随着了解增多,尝试了 Typecho、WordPress,Hugo 等主题后,目前还是决定使用 Hugo。它构建速度快,而且安装简单,在 Ubuntu 上只需要一行 sudo apt install hugo 即可,不可谓不简单。因此萌生了移植一个 Hugo 版本主题的想法,刚好可以锻炼一下自己。\n欢迎点击 这里 查看我的个人主页。\n一些难点 之前从来没有了解过 Hugo 主题的写法以及 Hexo 主题的写法,不过看了一下仓库的组织形式还算好理解。\n这类静态博客生成器都是需要写一些模板文件,然后根据配置文件进行个性化构建。\nHugo 的文档 十分的完善,学习就像是学习一门编程语言,里面有很多函数和变量,还有各种条件结构、循环结构等。原主题是采用的 pug + stylus 的方式,而不是传统的 html + css 。不过这两者之间的转换并不麻烦,而且有一些工具可以参考着转换,例如 pug2html 以及 stylus2css 。\n后续就参考着一点点的移植就可以,同时我也改写了一下配置文件(使用的 yaml 格式),大概是更易于配置了。\n同时,得益于 Hugo 的强大,我很方便的完成了对多语言的支持。\n最终效果 目前已经更新到了 v1.1.0 版本,欢迎大家体验,有问题可以及时反馈!\n主题链接:https://github.com/zzsqwq/hugo-academia-theme\n演示站:https://zzsqwq.github.io/academic-pages-demo/\n英文文档:https://github.com/zzsqwq/hugo-academia-theme/blob/master/README.md\n中文文档:https://github.com/zzsqwq/hugo-academia-theme/blob/master/README.zh_cn.md\n英文效果图:\n中文效果图:","title":"一个基于 Hugo 的个人主页主题"},{"content":"背景 在使用 Docker 搭建 Gitlab/Gitee 会导致无法与主机端共用 22 端口,这导致 ssh 连接的时候会使用形如 ssh://git@git.xxxx.cn:4022/zs/zsblog.git 的 ssh 链接,而不是像官方 Gitlab 那种非常干净的 git@git.xxxx.cn/zs/zsblog.git 链接。这对于我这种强迫症而言非常的难受啊,但因为主机的 22 端口已经被占用了,无法共用,所以需要考虑两者共享端口的问题。\n虽说是两者共用,但其实还是使用类似于端口转发的特点,简单说就是在主机设置 git 用户,然后通过一个脚本将 git 用户的所有 ssh 流量转发到 Gitlab 容器中,从而完成对应的事情。\n关于 Gitee 的设置,Gitee 官方的 Docker 部署教程1已经说的很清楚了,按照该步骤执行完全没问题。\n而关于 Gitlab 貌似没有比较详尽的教程,搜索后发现了一个 Issue2 以及一篇博文3,后者讲的比较清楚,但是经过实践后发现存在一定问题,因此决定将可行的方案记录下来。\n具体步骤 一、初始设置 在开始之前,docker-compose.yml 中设置比较关键的几个配置如下:\ngitlab-web: image: \u0026#39;gitlab/gitlab-ce:latest\u0026#39; container_name: \u0026#39;gitlab\u0026#39; restart: always environment: GITLAB_OMNIBUS_CONFIG: | gitlab_rails[\u0026#39;gitlab_shell_ssh_port\u0026#39;] = 4022 ports: - \u0026#39;3090:80\u0026#39; - \u0026#39;4022:22\u0026#39; - \u0026#39;6060:6060\u0026#39; volumes: - \u0026#39;/srv/gitlab/config:/etc/gitlab\u0026#39; - \u0026#39;/srv/gitlab/logs:/var/log/gitlab\u0026#39; - \u0026#39;/srv/gitlab/data:/var/opt/gitlab\u0026#39; - .... #一些其他的配置 如上设置基本可以确保 Gitlab 形如 ssh://git@git.xxxx.cn:4022/zs/zsblog.git 的链接可以使用。\n二、在 Host 宿主机创建与 Gitlab 相同的 git user 为了确保后续一些麻烦的权限问题,我们需要在宿主机也创建一个 git 用户。\n首先我们要检查 Gitlab 容器中 git 用户的 UID 以及 GID,如果不出意外的话,两者都已被硬编码为 998 。不过为了以防万一,我们可以通过下述指令进一步确认:\n❯ docker exec -it gitlab cat /etc/passwd | awk -F\u0026#39;:\u0026#39; \u0026#39;{if($1==\u0026#34;git\u0026#34;) printf(\u0026#34;uid: %s; gid: %s\\n\u0026#34;), $3, $4}\u0026#39; # 不出意外结果如下,证明 git 账户的 UID 与 GID 都为 998. uid: 998; gid: 998 这条指令会给出我们对应的 UID 以及 GID。\n接下来我们需要在宿主机中也创建 git 用户,确保 UID 及 GID 都与 Gitlab 容器内的一致。大家可以通过如下指令查看是否已有 git 用户,以及其 UID 与 GID。\n❯ cat /etc/passwd | awk -F\u0026#39;:\u0026#39; \u0026#39;{if($1==\u0026#34;git\u0026#34;) printf(\u0026#34;uid: %s; gid: %s\\n\u0026#34;), $3, $4}\u0026#39; 如果没有任何结果,说明没有 git 用户 如果有结果,并且 UID 与 GID 不为 998,说明需要重新该一下对应的 UID 与 GID,大家可以自行搜索解决方案。 我们还需要查看 /etc/passwd 与 /etc/group 两个文件确保 998 没有被使用,如果有使用也需要做对应改变。 如果没有 git 用户,则使用下面指令创建并指定家目录为 /home/git (在 root 用户下)\n❯ groupadd -g 998 git ❯ useradd -m -u 998 -g git -s /bin/sh -d /home/git git 如果已有,则确保其 UID 与 GID 和 Gitlab 容器中 git 用户相同,并确保有家目录 /home/git。\n三、复制 Gitlab 密钥文件 Gitlab 的密钥文件目前存放在容器的 /var/opt/gitlab/.ssh 中,然后根据你在 docker-compose.yml 配置的映射位置看,好比我配置的映射是 /srv/gitlab/data:/var/opt/gitlab,你就可以直接在 /srv/gitlab/data/.ssh 目录下找到对应的密钥文件。\n然后首先在 root 用户权限下执行\n❯ cp -r /srv/gitlab/data/.ssh /home/git/.ssh 将对应的文件夹复制到 git 用户家目录下,然后执行\n❯ chown -R git:git /home/git/.ssh 将所有的文件的权限及组权限都更改为 git 用户\n现在 git 用户的 .ssh 目录结构应该如下,也要确保 .ssh 文件权限为 700,authorized_keys 权限为 6004:\n❯ ls -la total 72 drwx------ 2 git git 4096 Apr 24 15:40 . drwxr-xr-x 5 git git 4096 Apr 24 02:00 .. -rw------- 1 git git 50122 Apr 24 02:00 authorized_keys -rw-r--r-- 1 git git 0 Apr 24 01:57 authorized_keys.lock -rw------- 1 git git 1679 Apr 24 01:48 id_rsa -rw-r--r-- 1 git git 390 Apr 24 01:48 id_rsa.pub -rw-r--r-- 1 git git 222 Apr 24 02:00 known_hosts 四、生成密钥文件 切换到 git 用户并生成密钥对\n❯ su - git ❯ ssh-keygen #然后一路回车 然后将公钥加入 authorized_keys\n❯ cat ~/.ssh/id_rsa.pub \u0026gt;\u0026gt; ~/.ssh/authorized_keys 五、创建脚本文件 我们不妨看一下现在的 authorized_keys 文件,里面应该有形如下面的内容一些行\ncommand=\u0026#34;/opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell key-105\u0026#34;,no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-ed25519 xxxxxxxx 这里说明我们提交时会执行一个 /opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell 脚本,这里本应该执行的是容器内的脚本,但是我们现在把它放在了容器外,因此我们需要设置一个脚本将请求转发进去,因此选择在本机的 /opt/gitlab/embedded/service/gitlab-shell/bin 目录下创建一个名为 gitlab-shell 的脚本,命令如下:\n# 创建文件夹 ❯ sudo mkdir -p /opt/gitlab/embedded/service/gitlab-shell/bin # 进入文件夹 ❯ cd /opt/gitlab/embedded/service/gitlab-shell/bin # 创建文件 ❯ sudo vim gitlab-shell 文件内容如下:\n#!/bin/sh ssh -i /home/git/.ssh/id_rsa -p 4022 -o StrictHostKeyChecking=no git@127.0.0.1 \u0026#34;SSH_ORIGINAL_COMMAND=\\\u0026#34;$SSH_ORIGINAL_COMMAND\\\u0026#34; $0 $@\u0026#34; 需要注意的是,这里的 4022 是指在 docker-compose.yml 文件映射的 4022:22 端口,如果你是 xxx:22 ,则需要在这里填写 xxx,对应起来。内\n然后不要忘记添加执行权限\n❯ sudo chmod +x /opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell 六、挂载额外的文件到 Gitlab 容器 修改我们的 docker-compose.yml ,注释掉 gitlab_rails['gitlab_shell_ssh_port'] = 4022 以及添加 '/home/git/.ssh/:/var/opt/gitlab/.ssh' ,将 git 用户的 .ssh 目录挂载到容器内。\ngitlab-web: image: \u0026#39;gitlab/gitlab-ce:latest\u0026#39; container_name: \u0026#39;gitlab\u0026#39; restart: always environment: GITLAB_OMNIBUS_CONFIG: | .... ports: - \u0026#39;3090:80\u0026#39; - \u0026#39;4022:22\u0026#39; - \u0026#39;6060:6060\u0026#39; volumes: - \u0026#39;/srv/gitlab/config:/etc/gitlab\u0026#39; - \u0026#39;/srv/gitlab/logs:/var/log/gitlab\u0026#39; - \u0026#39;/srv/gitlab/data:/var/opt/gitlab\u0026#39; - \u0026#39;/home/git/.ssh/:/var/opt/gitlab/.ssh\u0026#39; - .... #一些其他的配置 最后,重启容器即可生效。\n❯ docker-compose up -d 简单的原理说明 使用的原理就是将主机 git 用户的所有 ssh 流量都转发到容器内部。\n转发使用的是宿主机中的/opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell 脚本,而因为已经将主机 git 用户 id_rsa.pub 添加到了 authorized_keys 中,因此可以直接免密转发内容到容器内部。\n随后,容器内的 gitlab-shell 脚本对请求进行处理,完成 ssh 请求。\n这里很巧妙的使用了同一个位置的脚本,这也是需要将 git 用户的 .ssh 目录挂载到 Gitlab 内部的原因,但是每个脚本却作用不同,十分的巧妙。\n使用 Docker 安装 ↩\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nSharing SSH port between host and the container\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nExposing ssh port in dockerized gitlab-ce\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n公钥添加到authorized_keys到文件中之后仍无法免密登陆\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","permalink":"https://blog.zzsqwq.cn/posts/docker-gitlab-ssh/","summary":"背景 在使用 Docker 搭建 Gitlab/Gitee 会导致无法与主机端共用 22 端口,这导致 ssh 连接的时候会使用形如 ssh://git@git.xxxx.cn:4022/zs/zsblog.git 的 ssh 链接,而不是像官方 Gitlab 那种非常干净的 git@git.xxxx.cn/zs/zsblog.git 链接。这对于我这种强迫症而言非常的难受啊,但因为主机的 22 端口已经被占用了,无法共用,所以需要考虑两者共享端口的问题。\n虽说是两者共用,但其实还是使用类似于端口转发的特点,简单说就是在主机设置 git 用户,然后通过一个脚本将 git 用户的所有 ssh 流量转发到 Gitlab 容器中,从而完成对应的事情。\n关于 Gitee 的设置,Gitee 官方的 Docker 部署教程1已经说的很清楚了,按照该步骤执行完全没问题。\n而关于 Gitlab 貌似没有比较详尽的教程,搜索后发现了一个 Issue2 以及一篇博文3,后者讲的比较清楚,但是经过实践后发现存在一定问题,因此决定将可行的方案记录下来。\n具体步骤 一、初始设置 在开始之前,docker-compose.yml 中设置比较关键的几个配置如下:\ngitlab-web: image: \u0026#39;gitlab/gitlab-ce:latest\u0026#39; container_name: \u0026#39;gitlab\u0026#39; restart: always environment: GITLAB_OMNIBUS_CONFIG: | gitlab_rails[\u0026#39;gitlab_shell_ssh_port\u0026#39;] = 4022 ports: - \u0026#39;3090:80\u0026#39; - \u0026#39;4022:22\u0026#39; - \u0026#39;6060:6060\u0026#39; volumes: - \u0026#39;/srv/gitlab/config:/etc/gitlab\u0026#39; - \u0026#39;/srv/gitlab/logs:/var/log/gitlab\u0026#39; - \u0026#39;/srv/gitlab/data:/var/opt/gitlab\u0026#39; - .","title":"Docker-Gitlab 与主机共用 ssh 的 22 端口"},{"content":"前言 春节期间,走亲访友是必不可少的。交谈的多了,免不得一些问题的讨论。\n读了很多书,经历了很多事,似乎想法也有一些”离经叛道“,记一下自己目前的一些想法,不知道多年后的自己看这篇文章会是什么想法,还会一如既往的坚持吗。\n讨论的话题 打点关系 无论是父母,还是各方亲戚,大家好像都喜欢打点关系,以此来获得一些好处。\n最常见的是求人办事,很多时候是我们常说的”走后门“,想让孩子上个好点的小学,避免不了又送礼又吃饭。\n事件上升的恶劣一些,定然就是贪污受贿,这肯定是错的,大家都知道,但是度在哪里呢。\n和我儿时的哥哥探讨中,他认为,这种送礼打点关系是必要的,送点小礼没啥问题。而我总觉得,这就是0、1、无穷的区别,有一就有二,有二就有无穷。\n从出生到现在,试问自己从没遇到过必须送礼才能办成的事,或许以后会遇到,但我想、我应该宁愿放弃这个机会也不会去送礼打点。\n大家都对我说:“你现在是这个想法,是没有经历过社会的毒打,你踏入社会就也会这样了。”,我无言。\n或许吧,或许以后也会变成善于打点关系、整天辗转于酒局的人。\n至少我现在,还是个滴酒不沾、不屑于打点的鸟人。\n酒文化 我是个滴酒不沾的人\n有两点比较重要的原因\n一个是因为酒真的很难喝,好喝也就罢了,难喝为什么要喝呢?\n二是因为我真的很讨厌饭桌上推杯换盏,你推我我推你,大家都喝得烂醉如泥。村里有很多喝酒出事去世的例子,小时候看见一个哥哥的朋友,喝醉后在大街上和别人干架,然后在欢喜的日子里一起进医院···何必呢?\n推杯换盏还导致饭菜里会混入多多少少的酒,真的不好吃。\n大家为什么都不能别这么执拗,这里用执拗可能不合适,不过没想到什么好的词语。人家明明都说了不喝、不吃,为什么还总要一遍遍的推脱?最后立场不坚定的,只能不情愿地吃了。立场坚定的,又闹得双方不愉快似的。\n还有很多明明想喝、想吃,却又怕尴尬嘴上说着不喝不吃,一样可恶。\n硬唠 平时在家总喜欢窝在自己的屋子里,倒腾自己的事情。\n亲戚来了,似乎不出去跟他们聊天就是个错误。总是要数落你一下,在饭桌上调侃你一下,跟家长阴阳怪气一下你。\n不想说的是,真的感觉没有什么共同话题,聊不到一起去,实在是没什么话说,只能在那里低头玩手机,哦对了,手机也不得玩,玩多了也会被说。只能在那里干坐着东看西看,听大家侃大山,却因为离家过久大多事都没听说过,时间白白的浪费。\n人际关系真的蛮烦的。\n关于入党 最近舅家的哥哥萌生了入党的想法,说:”就算无论花多少钱,也得入党。“\n我问,那你入党又是为了做什么呢?\n他说,入党好啊,入党好啊,入党可以在村委里谋个一官半职,可以轻松一些,赚钱也多。\n我说你不应该为了自己的私利来入党,他说,人不为己天诛地灭,没有人不顾自己的私利。\n实话的讲,我哥哥是个不错的人,乐于与村里人交善,村民家里出什么事他也喜欢帮忙。但是这个入党的观念真的让我不理解,入党是应该认为认同,而不是因为利益驱使。\n大家入党好似都是为了后续能谋个公务员的出路,如果能贯彻为人民服务的宗旨还好,如果一心为了钱,很容易会变成蛀虫、老虎,那这样的话,不如踏踏实实另谋出路。\n后记 春节期间思考了很多,感觉与周围的很多亲戚们都格格不入。\n文章算是想到什么写什么,可能看起来杂乱无章,见谅。文章也只是我自己的一些看法,不代表普遍性,也无言对错,大家看看就好。\n还好的是,我的亲戚们大多不会问我,考的咋样,有对象了没……\n之前与一个舅家的哥哥很要好(与上文不是同一个),因为之前感觉我们两人观念很类似,亲戚们也都觉得我们两个像。\n这个春节与他进一步交流了一些,似乎观念不尽相同了。\n现在他步入社会,参加了工作,开始应付酒局,也会打点关系了。也开始教导我应该善于打点。\n我以后也会这样吗?\n","permalink":"https://blog.zzsqwq.cn/posts/224/","summary":"前言 春节期间,走亲访友是必不可少的。交谈的多了,免不得一些问题的讨论。\n读了很多书,经历了很多事,似乎想法也有一些”离经叛道“,记一下自己目前的一些想法,不知道多年后的自己看这篇文章会是什么想法,还会一如既往的坚持吗。\n讨论的话题 打点关系 无论是父母,还是各方亲戚,大家好像都喜欢打点关系,以此来获得一些好处。\n最常见的是求人办事,很多时候是我们常说的”走后门“,想让孩子上个好点的小学,避免不了又送礼又吃饭。\n事件上升的恶劣一些,定然就是贪污受贿,这肯定是错的,大家都知道,但是度在哪里呢。\n和我儿时的哥哥探讨中,他认为,这种送礼打点关系是必要的,送点小礼没啥问题。而我总觉得,这就是0、1、无穷的区别,有一就有二,有二就有无穷。\n从出生到现在,试问自己从没遇到过必须送礼才能办成的事,或许以后会遇到,但我想、我应该宁愿放弃这个机会也不会去送礼打点。\n大家都对我说:“你现在是这个想法,是没有经历过社会的毒打,你踏入社会就也会这样了。”,我无言。\n或许吧,或许以后也会变成善于打点关系、整天辗转于酒局的人。\n至少我现在,还是个滴酒不沾、不屑于打点的鸟人。\n酒文化 我是个滴酒不沾的人\n有两点比较重要的原因\n一个是因为酒真的很难喝,好喝也就罢了,难喝为什么要喝呢?\n二是因为我真的很讨厌饭桌上推杯换盏,你推我我推你,大家都喝得烂醉如泥。村里有很多喝酒出事去世的例子,小时候看见一个哥哥的朋友,喝醉后在大街上和别人干架,然后在欢喜的日子里一起进医院···何必呢?\n推杯换盏还导致饭菜里会混入多多少少的酒,真的不好吃。\n大家为什么都不能别这么执拗,这里用执拗可能不合适,不过没想到什么好的词语。人家明明都说了不喝、不吃,为什么还总要一遍遍的推脱?最后立场不坚定的,只能不情愿地吃了。立场坚定的,又闹得双方不愉快似的。\n还有很多明明想喝、想吃,却又怕尴尬嘴上说着不喝不吃,一样可恶。\n硬唠 平时在家总喜欢窝在自己的屋子里,倒腾自己的事情。\n亲戚来了,似乎不出去跟他们聊天就是个错误。总是要数落你一下,在饭桌上调侃你一下,跟家长阴阳怪气一下你。\n不想说的是,真的感觉没有什么共同话题,聊不到一起去,实在是没什么话说,只能在那里低头玩手机,哦对了,手机也不得玩,玩多了也会被说。只能在那里干坐着东看西看,听大家侃大山,却因为离家过久大多事都没听说过,时间白白的浪费。\n人际关系真的蛮烦的。\n关于入党 最近舅家的哥哥萌生了入党的想法,说:”就算无论花多少钱,也得入党。“\n我问,那你入党又是为了做什么呢?\n他说,入党好啊,入党好啊,入党可以在村委里谋个一官半职,可以轻松一些,赚钱也多。\n我说你不应该为了自己的私利来入党,他说,人不为己天诛地灭,没有人不顾自己的私利。\n实话的讲,我哥哥是个不错的人,乐于与村里人交善,村民家里出什么事他也喜欢帮忙。但是这个入党的观念真的让我不理解,入党是应该认为认同,而不是因为利益驱使。\n大家入党好似都是为了后续能谋个公务员的出路,如果能贯彻为人民服务的宗旨还好,如果一心为了钱,很容易会变成蛀虫、老虎,那这样的话,不如踏踏实实另谋出路。\n后记 春节期间思考了很多,感觉与周围的很多亲戚们都格格不入。\n文章算是想到什么写什么,可能看起来杂乱无章,见谅。文章也只是我自己的一些看法,不代表普遍性,也无言对错,大家看看就好。\n还好的是,我的亲戚们大多不会问我,考的咋样,有对象了没……\n之前与一个舅家的哥哥很要好(与上文不是同一个),因为之前感觉我们两人观念很类似,亲戚们也都觉得我们两个像。\n这个春节与他进一步交流了一些,似乎观念不尽相同了。\n现在他步入社会,参加了工作,开始应付酒局,也会打点关系了。也开始教导我应该善于打点。\n我以后也会这样吗?","title":"关于春节期间的一些碎碎念"},{"content":"前言 最近看了一些 js 有关的知识,其中令我这种初学者感到很头疼的一个问题就是异步问题。\n今天就我碰到的一个小问题详解一个关于异步的小技巧。\n背景 我在程序中需要鉴权,来判断一个用户是普通用户还是管理员,针对不同的用户渲染不同的页面。\n每个用户具有唯一的 ID,因此我只需要将管理员的 ID 放到数据库,然后加载程序的时候一一比对即可。\n但是我的主程序初始化与页面的初始化是异步的,管理员的判断逻辑我放在了主程序初始化中,这也就意味着很可能我页面在加载时,主程序还没有判断完用户的身份。\n每个人默认不是管理员,因此这就会导致一个问题——管理员可能也会显示成普通用户的页面,因为渲染页面的时候程序还不知道这个用户是管理员。\n方案 这个方案其实是我从官方的代码上学到的,其实就结合代码给大家讲一下。\n官方这里是在获取用户的 userInfo 时用到的。\n主程序初始化部分代码:\n这里主程序的逻辑就是在 getSetting 调用成功后,判断是否已经获得过 userInfo ,如果已经获得过,则可以直接调用 getUserInfo 函数获取值,赋值成一个主程序的全局变量,所有页面都可以用。\n接下来就是一个比较奇怪的点了\n可以看到官方的注释为\n由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回\n所以此处加入 callback 以防止这种情况\n这里判断了主程序内是否含有 userInfoReadyCallback 这个函数,如果有的话就执行。\nqq.getSetting({ success: res =\u0026gt; { if (res.authSetting[\u0026#39;scope.userInfo\u0026#39;]) { // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框 qq.getUserInfo({ success: res =\u0026gt; { // 可以将 res 发送给后台解码出 unionId this.globalData.userInfo = res.userInfo // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 if (this.userInfoReadyCallback) { this.userInfoReadyCallback(res) } } }) } } }) 页面初始化部分代码:\n页面初始化部分的逻辑首先判断全局变量中是否包含 userInfo 这个这个变量,我们从上文得知,如果我们在此段程序执行前主程序已经执行完毕,那么这里是包含 userInfo 这个函数的,我们直接赋值给当前的环境变量。\n而如果没有 userInfo 没有定义,也就是主程序还未完成变量的初始化,这就出现了我们之前提到的问题,页面加载时主程序未初始化完。\n定义了 userInfoReadyCallback 函数,接受 res 参数,进行赋值。\nif (app.globalData.userInfo) { this.setData({ userInfo: app.globalData.userInfo, hasUserInfo: true }) } else if (this.data.canIUse) { // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 app.userInfoReadyCallback = res =\u0026gt; { this.setData({ userInfo: res.userInfo, hasUserInfo: true }) } } else { //...... 读完上面的程序大家应该已经可以搞懂了,其实类似于设置了两个标志(flag)。\n一个标志是全局变量 userInfo、一个是全局函数 userInfoReadyCallback 。\n如果 userInfo 已经定义,说明页面初始化前页面主程序变量已初始化完毕,渲染不会出问题。\n而如果 userInfo 未定义,说明与上面相反,则在页面中定义userInfoReadyCallback 函数,后续主程序初始化到最后得知该函数已定义,则调用其来进行初始化。\n这样就总能够保证局部 userInfo 这个变量的取值总是正确的,也即页面总是渲染正确的!\n后记 这个问题应该总是可以解决两个页面同时加载但却存在变量依赖的问题。\n大家如果有什么更加优秀的解决方案也希望不吝赐教。\n","permalink":"https://blog.zzsqwq.cn/posts/223/","summary":"前言 最近看了一些 js 有关的知识,其中令我这种初学者感到很头疼的一个问题就是异步问题。\n今天就我碰到的一个小问题详解一个关于异步的小技巧。\n背景 我在程序中需要鉴权,来判断一个用户是普通用户还是管理员,针对不同的用户渲染不同的页面。\n每个用户具有唯一的 ID,因此我只需要将管理员的 ID 放到数据库,然后加载程序的时候一一比对即可。\n但是我的主程序初始化与页面的初始化是异步的,管理员的判断逻辑我放在了主程序初始化中,这也就意味着很可能我页面在加载时,主程序还没有判断完用户的身份。\n每个人默认不是管理员,因此这就会导致一个问题——管理员可能也会显示成普通用户的页面,因为渲染页面的时候程序还不知道这个用户是管理员。\n方案 这个方案其实是我从官方的代码上学到的,其实就结合代码给大家讲一下。\n官方这里是在获取用户的 userInfo 时用到的。\n主程序初始化部分代码:\n这里主程序的逻辑就是在 getSetting 调用成功后,判断是否已经获得过 userInfo ,如果已经获得过,则可以直接调用 getUserInfo 函数获取值,赋值成一个主程序的全局变量,所有页面都可以用。\n接下来就是一个比较奇怪的点了\n可以看到官方的注释为\n由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回\n所以此处加入 callback 以防止这种情况\n这里判断了主程序内是否含有 userInfoReadyCallback 这个函数,如果有的话就执行。\nqq.getSetting({ success: res =\u0026gt; { if (res.authSetting[\u0026#39;scope.userInfo\u0026#39;]) { // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框 qq.getUserInfo({ success: res =\u0026gt; { // 可以将 res 发送给后台解码出 unionId this.globalData.userInfo = res.userInfo // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 if (this.","title":"一个 Javascript 中异步的小技巧"},{"content":"前言 更换博客系统的想法已经萌生很久了,一个是感觉 Handsome 这个主题有点看腻了,但是在 Typecho 中好似已经没有更好的博客主题可选择了。\n有一个看起来貌似很不错,主题名叫 maupassant。效果如下图所示,顺附链接\npagecho/maupassant(github.com)\n不过一直没有下定决心更换,后来也尝试过使用 WordPress,又觉得 WordPress 体量有点太大了。\n每天逛 Github 的时候看到了很多很不错的静态博客主题,那天看到一个学长分析学校校园网的博客,第一眼就感觉很不错,找寻了一下发现博客基于 Hugo,主题是 hugo-PaperMod。\n于是顺着寻找了一下,发现 Hugo 中很多博客主题非常的不错。此外,Hugo 相比于 Hexo 也有很多优点:博客构建速度快,基于模板的概念组织内容,环境配置容易,在 Ubuntu 下一行命令即可,而 Hexo 依赖于 Node.js,体量稍微有点大。\n于是决定把博客迁移到 Hugo,并且采用主题 Coder 。\n过程 Typecho 文章导出 这里采用了 lizheming 大大的迁移插件:lizheming/typecho-export-hugo\n具体导出为 zip 的时候可能会提示损坏,这样的话可以直接去服务器 \\tmp\\Export2Hugo 下面打包。\n安装 hugo 过程基于 Windows 平台,很简单,在 这里 下载 hugo 最新的 release 版本,找到对应自己系统的即可。下载后解压到某个目录下,设置一下环境变量即可。这里牵扯到 hugo 和 hugo_extended 两个版本的区别,以下是某个 issue 中的解释:\nI agree.\nThe only functional difference is SASS/SCSS The technical build time difference is that it requires a C++ build chain for the target platform to build, the reason why we currently only build the extended for 3 platforms (Windows, Linux, MacOS) Binaries are slightly less portable as you need a compatible Libc version on your computer (for Windows we build a fully static version as Libc is rather uncommon unless you have Visual Studio or something installed). via: Please document the difference between the \u0026ldquo;extended\u0026rdquo; and non-\u0026ldquo;extended\u0026rdquo; versions\n我认为,直接使用 extended 版本就完事了。使用了 extended 不会报错,而不用 extended 版本可能会报错。\n构建网站 首先在合适的目录下生成一个新的网站\n$ hugo new site zsblog 然后进入目录后,初始化一个 git 仓库\n$ git init [可选]将自己心仪的目录设置为 git 的 submodule ,需要注意的是,hugo 中的主题配置多是基于 submodule 的,这种方式很灵活,也便于更新,当然,需要先学习一下 submodule 的用法:) ,这里以 coder 主题为例:\n$ git submodule add https://github.com/luizdepra/hugo-coder.git themes/hugo-coder 然后基于对应主题的 exampleSite 来设定对应的配置文件 config.toml,这里很蛋疼的是 coder 主题居然偏爱 toml 配置格式,为什么不是 yaml/json 呢?\n补充:hugo 支持三种格式的配置文件 yaml, toml, json.\n然后启动博客即可\n$ hugo server 这里很有意思的是,启动多个 server 不会冲突,hugo 会选择另外一个端口部署。同时,启动 server 不会显式生成静态文件。\n最后就是上传到 Github,然后可以选用 Github Pages 进行部署,注意 Baseurl 的设定。\n利用 Github Actions 进行持续部署 我这里采用的是将我的博客部署到我的服务器,使用 Github Actions 进行 CI/CD。\n使用了 actions/checkout@v2、peaceiris/actions-hugo@v2、peaceiris/actions-gh-pages、burnett01/rsync-deployments@5.1 这几个模板,向大佬表示感谢!\n其中有一个很坑的地方是之前用的 rsync 模板是 contention/rsync-deployments,不知道是为啥···我用这个的时候,只要使用 --exclude 参数他就犯病,显示成功但是却没有上传到云端服务器,搁那里 debug 了半天发现是插件好像有点 bug ?有点麻了..\n具体的配置文件如下:\nname: Zs-Hugo-Blog on: push: branches: - master # Set a branch to deploy pull_request: jobs: deploy: runs-on: ubuntu-20.04 concurrency: group: ${{ github.workflow }}-${{ github.ref }} steps: - uses: actions/checkout@v2 with: submodules: true # Fetch Hugo themes (true OR recursive) fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod - name: Setup Hugo uses: peaceiris/actions-hugo@v2 with: hugo-version: \u0026#39;latest\u0026#39; extended: true - name: Build run: hugo --minify - name: Deploy uses: peaceiris/actions-gh-pages@v3 if: ${{ github.ref == \u0026#39;refs/heads/master\u0026#39; }} with: github_token: ${{ secrets.HUGO_DEPLOY }} publish_dir: ./public - uses: actions/checkout@v2 with: ref: \u0026#39;gh-pages\u0026#39; - name: rsync deployments uses: burnett01/rsync-deployments@5.1 with: switches: -avzr --delete --exclude=\u0026#34;.htaccess\u0026#34; --exclude=\u0026#34;/usr/\u0026#34; path: ./ remote_path: /www/wwwroot/new_blog/ remote_host: zzsqwq.cn remote_user: www remote_key: ${{ secrets.SSH_KEY }} 一些其他配置 再者我还配置了 Google analytics,hugo 对 Google analytics 的支持很不错,点击 这里 查看详情。\n此外还有配置了基于 Utterances 的评论系统,起初想要尝试使用 Commento 的,自己搭建了个服务,搞了半天也没搞好,无法在我的网站正常加载,最后还是采用了 Utterances,几分钟就搞好了,可恶。\n同时,为了保持原先博客的链接活性,我将原博客部署到了 https://lastblog.zzsqwq.cn ,在 Apache 中将原博客链接全部重定向到当前网站,这样就不会产生死链了,配置如下:\n#rewrite RewriteEngine On RewriteRule ^/?index.php/(.*)$ https://lastblog.zzsqwq.cn/index.php/$1 [R,L] 后记 其中还有一些 RSS 的配置、评论系统宽度的修改等一些小问题,就不细说了。\n有个比较蛋疼的问题就是目前 Utterances 评论系统的配色不能随着博客亮暗的切换改变,后续计划改善一下\n同时,为了保持主题的可配置性,我 fork 了一份主题,并且针对做了一些修改,仓库地址:zzsqwq/hugo-coder\n","permalink":"https://blog.zzsqwq.cn/posts/221/","summary":"前言 更换博客系统的想法已经萌生很久了,一个是感觉 Handsome 这个主题有点看腻了,但是在 Typecho 中好似已经没有更好的博客主题可选择了。\n有一个看起来貌似很不错,主题名叫 maupassant。效果如下图所示,顺附链接\npagecho/maupassant(github.com)\n不过一直没有下定决心更换,后来也尝试过使用 WordPress,又觉得 WordPress 体量有点太大了。\n每天逛 Github 的时候看到了很多很不错的静态博客主题,那天看到一个学长分析学校校园网的博客,第一眼就感觉很不错,找寻了一下发现博客基于 Hugo,主题是 hugo-PaperMod。\n于是顺着寻找了一下,发现 Hugo 中很多博客主题非常的不错。此外,Hugo 相比于 Hexo 也有很多优点:博客构建速度快,基于模板的概念组织内容,环境配置容易,在 Ubuntu 下一行命令即可,而 Hexo 依赖于 Node.js,体量稍微有点大。\n于是决定把博客迁移到 Hugo,并且采用主题 Coder 。\n过程 Typecho 文章导出 这里采用了 lizheming 大大的迁移插件:lizheming/typecho-export-hugo\n具体导出为 zip 的时候可能会提示损坏,这样的话可以直接去服务器 \\tmp\\Export2Hugo 下面打包。\n安装 hugo 过程基于 Windows 平台,很简单,在 这里 下载 hugo 最新的 release 版本,找到对应自己系统的即可。下载后解压到某个目录下,设置一下环境变量即可。这里牵扯到 hugo 和 hugo_extended 两个版本的区别,以下是某个 issue 中的解释:\nI agree.\nThe only functional difference is SASS/SCSS The technical build time difference is that it requires a C++ build chain for the target platform to build, the reason why we currently only build the extended for 3 platforms (Windows, Linux, MacOS) Binaries are slightly less portable as you need a compatible Libc version on your computer (for Windows we build a fully static version as Libc is rather uncommon unless you have Visual Studio or something installed).","title":"记一次博客迁移记录"},{"content":"前言 近期著名 Markdown 编辑器 Typora 宣布收费了,起初感觉很难受,后来感慨之余也觉得算是合理,毕竟 Typora 用起来感觉是真的很良心,也在考虑是否买一份支持一下。\n已于2021/12/10购入,还是选择回归了 Typora 了哈哈哈\n虽说左右分屏的设计可能更符合 Markdown 的初衷,但是像 Typora 这种所见即所得(WYSIWYG) 的书写体验确实是感觉习惯了就回不去了。\n因此近期也搜集了 Markdown 编辑器作为 Typora 的替代品,在这里给大家分享一下。\n特别声明,下面的分享多是我日常体验中的一些感受,可能不够客观,比较片面,大家可以自己使用体验一下!\n一、Obsidian 界面预览 特点 具有文档的双向链接\n支持行级和块级公式\n官网可以购买 sync 套餐保持各个客户端同步\n可以购买 publish 服务将 markdown 发布为排版美观的界面\n有丰富的插件,例如日历、待办清单、Git同步等等。\n有Linux,Windows,iPad等多平台支持。\n使用体验 Obsidian 中文为黑曜石。我觉得它的图标很好看。\n在我使用的一段时间内,他给我的感觉是,功能十分丰富的一个 Markdown 文件管理工具。如果你购买了他的同步服务,那你可以很轻松的在各平台同步你的 Markdown 文件夹,并且基于他强大的插件,可以很完成很多 Markdown 文件份外的事,例如待办清单、日历等等。\n他虽没有所见即所得的模式,但是依靠其一款第三方插件,可以达成类似的效果,不过还是用起来不如 Typora 这种顺手。同时,它的各端同步如果不开启官方的服务,用起来还是挺麻烦的,经过我的一阵倒腾,我总结了如下几个方案:\n使用第三方Git管理插件,可以定时推送文件夹中的内容到仓库,这样可以完成 linux 与 Windwos 平台的同步,只需要在某一方推送某一方拉取即可。而 Windows 平台与 iPad 平台的同步,可以借助 Apple 的 iCloud,Windows上有对应的客户端,这也是 Obsidian 官方支持的。不过在我使用的过程中我发现,这样异常的麻烦,使用 Git 来管理很可能会产生冲突,导致需要手动处理冲突,久而久之就会觉得很烦。\n使用自建云盘如 NextCloud + Obsidian,或者 Seafile + Obsidian。 这个是我觉得目前非常可行的一个方案,最近我也有在尝试 NextCloud,它的多端同步做的非常不错,依靠此可以在各个平台同步文件夹,加上 Obsidian 强悍的能力,是不错的组合!\n二、Mark Text 界面预览 特点 开源!!\n所见即所得(WYSIWYG)\n支持行级和块级公式\n界面简洁且美观\nWindows,Linux 等多平台支持,不支持 iPad\n缺点:目前仍不支持中文\n使用体验 Mark Text 是 Github 上一个开源的项目\n个人认为他是在对标 Typora 的一个软件,有着和 Typora 非常相近的写作手感,并且界面简洁美观,我个人真的是非常喜欢,也是我目前在用的一款编辑器,本篇文章就是使用此编辑器书写。\n它的可配置程度虽然没有 Typora 那么高,但是平常的使用已经足够。不过值得说道的是,他不支持导出 Word 文档,而且对用公式的补全做的不够完美。\n可能还是有一些 bug 的,软件的最后一次 release 还是在 2020 年了(说明非常的稳定啊哈哈)。不过贵在他是个开源的软件,有很多大佬愿意为之奉献,期待后续的更新!\n三、Zettlr 界面预览 特点 开源!!\n可导出的格式非常的多,如 Latex、Word 等都可以。\n可以说是所见即所得,不过和 Typora 的理念略有不同。\n支持 Windows、Linux 等平台。\n支持语言的种类要比 Mark Text 多很多。\n缺点:自认为界面没有 Mark Text 和 Typora 这种好看。\n使用体验 上面的有个特点我描述的是 “可以说是所见即所得,不过和 Typora 的理念略有不同”\n我感觉它的所见即所得不是纯正的所见即所得,还是会保留部分源代码的元素在上面。不过他支持导出的格式要比 Mark Text 多不少。\n同时他也支持任务清单这种小功能,但是我认为它没有 Mark Text 美观和好用。使用的也不算太多,就不过多的评价了~\n四、VSCode + 插件 界面预览 特点 基于 VSCode 这个宇宙第一编辑器,不需要装别的软件\n可选的插件很多,不差这个一个\n多是基于 vditor,对 vditor 有钟爱的同学不要错过!\n所见即所得\n使用体验 因为我自己没有深度体验这个东西,但是我认为功能还是很强大的~\n虽然说,他可能没有一个单独的软件配置项那么多,但是贵在他只是一个集成于 VSCode 的插件,不要安装一个那么大体量的软件。\n同时可以很快的在代码与文档之间切换,这应该也算是一个优势了。\n后记 本来想把这个博文做成一个各类软件推荐文的,但是写着写着发现光是 Markdown 类的已经可以写很多了,为了防止篇幅过长,就单做一个 Markdown 编辑器的推荐文吧~\n如果大家有更好的 Markdown 编辑器推荐,欢迎在下面留言!\n","permalink":"https://blog.zzsqwq.cn/posts/220/","summary":"前言 近期著名 Markdown 编辑器 Typora 宣布收费了,起初感觉很难受,后来感慨之余也觉得算是合理,毕竟 Typora 用起来感觉是真的很良心,也在考虑是否买一份支持一下。\n已于2021/12/10购入,还是选择回归了 Typora 了哈哈哈\n虽说左右分屏的设计可能更符合 Markdown 的初衷,但是像 Typora 这种所见即所得(WYSIWYG) 的书写体验确实是感觉习惯了就回不去了。\n因此近期也搜集了 Markdown 编辑器作为 Typora 的替代品,在这里给大家分享一下。\n特别声明,下面的分享多是我日常体验中的一些感受,可能不够客观,比较片面,大家可以自己使用体验一下!\n一、Obsidian 界面预览 特点 具有文档的双向链接\n支持行级和块级公式\n官网可以购买 sync 套餐保持各个客户端同步\n可以购买 publish 服务将 markdown 发布为排版美观的界面\n有丰富的插件,例如日历、待办清单、Git同步等等。\n有Linux,Windows,iPad等多平台支持。\n使用体验 Obsidian 中文为黑曜石。我觉得它的图标很好看。\n在我使用的一段时间内,他给我的感觉是,功能十分丰富的一个 Markdown 文件管理工具。如果你购买了他的同步服务,那你可以很轻松的在各平台同步你的 Markdown 文件夹,并且基于他强大的插件,可以很完成很多 Markdown 文件份外的事,例如待办清单、日历等等。\n他虽没有所见即所得的模式,但是依靠其一款第三方插件,可以达成类似的效果,不过还是用起来不如 Typora 这种顺手。同时,它的各端同步如果不开启官方的服务,用起来还是挺麻烦的,经过我的一阵倒腾,我总结了如下几个方案:\n使用第三方Git管理插件,可以定时推送文件夹中的内容到仓库,这样可以完成 linux 与 Windwos 平台的同步,只需要在某一方推送某一方拉取即可。而 Windows 平台与 iPad 平台的同步,可以借助 Apple 的 iCloud,Windows上有对应的客户端,这也是 Obsidian 官方支持的。不过在我使用的过程中我发现,这样异常的麻烦,使用 Git 来管理很可能会产生冲突,导致需要手动处理冲突,久而久之就会觉得很烦。\n使用自建云盘如 NextCloud + Obsidian,或者 Seafile + Obsidian。 这个是我觉得目前非常可行的一个方案,最近我也有在尝试 NextCloud,它的多端同步做的非常不错,依靠此可以在各个平台同步文件夹,加上 Obsidian 强悍的能力,是不错的组合!","title":"Markdown 编辑器推荐"},{"content":"2021版小新Pro14 Ubuntu 20.04 配置指南 补充 最近重装了 Ubuntu 20.04,又找了相关的一些帖子,发现 聯想Yoga 14s 2021款裝機小記 中提到了下文中提到的屏幕闪烁的问题,解决办法是:只需要在内核参数中加入 i915.enable_psr=0 即可。\n具体操作步骤如下:\n$ sudo vim /etc/default/grub 在 GRUB_CMDLINE_LINUX_DEFAULT 这一行的最后添加 i915.enable_psr=0,保存后终端运行:\n$ sudo update-grub 然后重启即可。\n前言 苦于沉重游戏本的迫害,新买了一台小新Pro14 2021款,上手感觉还挺不错的。如下是配置:\nCPU:酷睿 i5-11300H 显卡:集成显卡 Intel 锐炬Iris Xe 内存:16G 外存:512 SSD 屏幕:分辨率 2880x1800、400nits、100%sRGB 这里需要注意的是,不同时间出的小新Pro14配置是不太一样的,所以我这里列了一下配置。主要区别在于有一部分是2.2K分辨率+MX450显卡,而我这个是2.8K分辨率+锐炬Iris Xe显卡。\n为了工作的需要,要装一个Ubuntu,先是装了之前用过的 Ubuntu 18.04,安装后发现触摸板无法使用,一系列探索后无果,在朋友的推荐下,还是决定安装 Ubuntu 20.04 试一下,踩了一些坑,在这里记录一下。\n问题列表 如果你遇到了以下问题,那么这篇文章的方法可能会对你有益处:\nUbuntu 18.04 相关 Ubuntu 18.04 无法使用触摸板 Ubuntu 18.04 无法使用内置键盘 Ubuntu 18.04 无法调节亮 Ubuntu 18.04 查看GPU发现是llvm,而不是Iris Xe Ubuntu 20.04 相关 Ubuntu 20.04 进入后屏幕花屏、黑屏 Ubuntu 20.04 查看GPU发现是llvm,而不是Iris Xe 现在达成的效果 Ubuntu 20.04 能够正常使用,触摸板以及外界屏幕,亮度调节均无问题。\n开机时也能够使用键盘。\n但是开机登录界面还是存在花屏、闪屏的问题,我通过自动登录解决。BIOS界面仍旧会闪屏。\n安装 Ubuntu 18.04 的问题 首先安装Ubuntu 18.04 还是比较顺利,没有什么坑。\n安装的话就是按流程来一遍——压缩卷、进入BIOS关闭安全启动模式(这里网上有部分同学说也需要关闭 Intel Platform Trust Technology 、但是我不关闭也是可以的)、然后Try Ubuntu看一下效果(这里Try Ubuntu我没法使用鼠标,不过安装的时候可以)、开始安装。\n安装过程一般没啥问题,进入系统后我们就会发现一些问题,首先是你的**触摸板用不了,然后键盘也用不了。**再就是屏幕没法调节亮度(这个是小问题我觉得,好像也可以通过安装插件解决,大家可以自行搜索。)\n经过查询资料,这里有同学已经提出很好的解决方案:https://zhuanlan.zhihu.com/p/322377515\n简而言之,键盘用不了需要在 grub 启动项中加入 i8042.dumbkbd 参数,然后运行\nsudo update-grub2 即可在每次启动后保证键盘可用。\n关于没法使用触摸板和调节亮度,办法就是升级内核,据说是内核升级到5.9.8以上可用,Ubuntu 18.04内置版本是5.4.0.84好像是,但是我在更新后会花屏、黑屏等来回鬼畜,试了好多四五个内核依旧不管用,我猜想是因为我是2.8K的屏幕而网上的教程多是基于2.2K屏幕的,锐炬显卡对于高分辨率的屏幕支持并没有那么优秀。\n于是一直被这个问题折磨,搜了很多的教程也没有解决办法,最后决定换Ubuntu 20.04 尝试一下,之前一直觉得系统版本是个不可逾越的鸿沟,但是随着实践的越来越多,发现很多版本不兼容的问题都是有可解决办法的,因此也下定决心尝试一下未曾试过的 20.04。\n安装Ubuntu 20.04 的问题 首先是关于安装的问题\n在安装Ubuntu 18.04 的时候只有四个选项,应该是一个 Try Ubuntu、一个直接安装,一个高级模式,一个进BIOS\n而安装Ubuntu 20.04 的时候却有五个选项,分别是Ubuntu、Ubuntu(safe graphics)、OEM install(for manufacturers)、还有就是一个是高级模式、一个是进BIOS\n说一下三个安装方式的区别\n第一个模式与第二个模式的区别就是,第二个模式对于grub启动项目中添加了一个 nomodeset 选项,那么这个选项是做什么的?以下是他的解释:\nThe newest kernels have moved the video mode setting into the kernel. So all the programming of the hardware specific clock rates and registers on the video card happen in the kernel rather than in the X driver when the X server starts.. This makes it possible to have high resolution nice looking splash (boot) screens and flicker free transitions from boot splash to login screen. Unfortunately, on some cards this doesn’t work properly and you end up with a black screen. Adding the nomodeset parameter instructs the kernel to not load video drivers and use BIOS modes instead until X is loaded.\n大概意思是在最新的内核中,已经能够在BIOS引导阶段启用显卡,这样做的目的是很好的适应高分辨率屏,但是很遗憾的是某些显卡并不能很好的适配,通过 nomodeset 参数可以防止以不支持的显卡驱动视频流。\n很遗憾,锐炬显卡刚好没有被适配,所以选第一个选项(Ubuntu)来安装也会屏幕一闪一闪的,因此我们安装选择Ubuntu(safe graphics)选项来进行安装然后流程是一样的,蛮顺利。\n这里装完就没有触摸板的问题,屏幕亮度调节也没有问题。不过键盘依旧有问题,可以根据上面描述进行更改。\n然后更鬼畜的问题来了,只要这么一搞,从BIOS引导阶段开始,就会一直闪屏,尤其是输入密码进行登录的时候,会卡个好长时间,几乎无法使用,不过很有意思的是,只要外接屏幕,外接的屏幕显示不会有问题。\n因此求助于搜索引擎,因为怀疑是显卡的问题,所以搜索了关键词 Ubuntu Iris Xe,找到了以下两个比较有用的答案:\nStackOverflow:Ubuntu 20.04 no driver loaded for Intel Iris Xe Graphics\nIntel:Intel Iris Xe MAX Graphics with Linux\n这两个帖子都说了一个问题吧,就是如何在 Ubuntu 20.04 上更好的使用锐炬显卡\n这个问题实质解决的是没有在Ubuntu 20.04 上启动起来显卡,所以你会在你的 Ubuntu-\u0026gt;Settings-\u0026gt;About 页面看到的是 llvm 有关的字眼,而不是上面我截图所示的 Mesa Intel® Xe Graphics (TGL GT2)。\n解决这个问题比较关键的步骤是\nsudo apt update sudo apt install linux-oem-20.04 sudo reboot 这样开机再启动应该就会正常启动显卡了,这个方式在Ubuntu18.04是否奏效我没有实验过,可能可以安装对应的 linux-oem-18.04 包。\n在 Intel 官方的教程中,还添加了 grub 启动项等,我并没有发现他们的实际作用,在他后续的测试中我也没有达到期待的效果,因此没有继续尝试,如果有同学跟着文档做成功了,可以一起来讨论一下。\n但是!!!\n安装完成后,我还是会花屏和黑屏,问题依旧没有解决。我突发奇想,考虑到我外接屏幕没有问题,而自带的屏幕有问题,**因为外接屏是 1920x1080 而内置屏幕是 2880x1800,我联想到会不会是高分辨率屏幕的问题,所以尝试着把外接屏的显示比例调成了 150%(需要开启 Fractional Scaling),没想到歪打正着,居然好了,看起来也更加的顺眼,比例也更加协调。**具体的内部原因还不是很清楚。 已解决,见本文开头。\n但是还是有一个小瑕疵,就是在BIOS引导阶段与输入密码登录的界面,我仍旧是会花屏、闪屏,我考虑到这是还没有初始化屏幕设置的问题,尝试搜索了修改BIOS比例、提前初始化login界面的分辨率,依旧没有找到比较好的解决办法,\n因此最后只好启动自动登录来跳过登录界面,这样就看上去算是一个完好的系统了QAQ。。\n这里给出一些可能有价值的资料,大家可以自行查阅\nHow to change the login screen resolution in Ubuntu 18.04\nCustom Resolution Ubuntu 20.04\nHow can I change the resolution of the GRUB menu?\n根据上述第三个教程,我修改了 GRUB 的显示分辨率为 1920x1080,还是会闪屏。\n如果有大佬有想法或者解决了,欢迎留言一起探讨。\n后记与感想 折腾了一下午加一晚上,终于把系统整的能用了,不过又要重新配置各种软件,还是挺麻烦的。\n不过尝试新鲜事物、好比Windows11、最新款的电脑,还是挺高血压的,需要应付各种Bug,这可能也是一种平衡?hhhh,想要尝试新的事物、走在前沿、就必须要有付出。\n此外,发现查英文的资料要比中文靠谱的多,尤其是这种比较新的问题、要多去StackOverflow和AskUbuntu等论坛和官网查看,有奇效。\n参考资料 联想小新pro14安装Ubuntu20.04 Ubuntu 20.04 no driver loaded for Intel Iris Xe Graphics Intel Iris Xe MAX Graphics with Linux How to change the login screen resolution in Ubuntu 18.04 Custom Resolution Ubuntu 20.04 How can I change the resolution of the GRUB menu? ","permalink":"https://blog.zzsqwq.cn/posts/215/","summary":"2021版小新Pro14 Ubuntu 20.04 配置指南 补充 最近重装了 Ubuntu 20.04,又找了相关的一些帖子,发现 聯想Yoga 14s 2021款裝機小記 中提到了下文中提到的屏幕闪烁的问题,解决办法是:只需要在内核参数中加入 i915.enable_psr=0 即可。\n具体操作步骤如下:\n$ sudo vim /etc/default/grub 在 GRUB_CMDLINE_LINUX_DEFAULT 这一行的最后添加 i915.enable_psr=0,保存后终端运行:\n$ sudo update-grub 然后重启即可。\n前言 苦于沉重游戏本的迫害,新买了一台小新Pro14 2021款,上手感觉还挺不错的。如下是配置:\nCPU:酷睿 i5-11300H 显卡:集成显卡 Intel 锐炬Iris Xe 内存:16G 外存:512 SSD 屏幕:分辨率 2880x1800、400nits、100%sRGB 这里需要注意的是,不同时间出的小新Pro14配置是不太一样的,所以我这里列了一下配置。主要区别在于有一部分是2.2K分辨率+MX450显卡,而我这个是2.8K分辨率+锐炬Iris Xe显卡。\n为了工作的需要,要装一个Ubuntu,先是装了之前用过的 Ubuntu 18.04,安装后发现触摸板无法使用,一系列探索后无果,在朋友的推荐下,还是决定安装 Ubuntu 20.04 试一下,踩了一些坑,在这里记录一下。\n问题列表 如果你遇到了以下问题,那么这篇文章的方法可能会对你有益处:\nUbuntu 18.04 相关 Ubuntu 18.04 无法使用触摸板 Ubuntu 18.04 无法使用内置键盘 Ubuntu 18.04 无法调节亮 Ubuntu 18.04 查看GPU发现是llvm,而不是Iris Xe Ubuntu 20.04 相关 Ubuntu 20.","title":"2021版小新Pro14 Ubuntu 20.04 配置指南"},{"content":"前言 前段时间在 Github 学完了关于 git 的小游戏 learnGitBranching ,受益匪浅。\n它通过可视化的方式将分支的关系,每条命令的作用等都明明白白的体现出来,可以很直观的感受到你每条命令对整个分支树,每一个 ref 的作用。\n通过这种学习感觉自己对 Git 的理解更加深入一步,能够理解其中的原理,而不是浅尝辄止,照猫画虎。\n学习中记了一些零零散散的思路,想要写一篇笔记记录出来,之前已经写过一个简单的 Git 教程,这篇教程将会更加深入,希望可以帮助大家更好的掌握 Git。\n窃认为,想要学好 Git ,必须要理解清楚其中的分区以及引用,学会了这两个,各种基本操作就很容易理解了。接下来的笔记也基本以此思路展开。\nGit中的分区 首先,Git中存在三大分区,分别是工作区、暂存区、版本库。其中,\n工作区即我们工作的目录,暂存区是我们执行 git add 后文件存在的区域。\n我们可以通过 git status 对两种状态进行查看,例如:\n~/test master* base ❯ git status On branch master Changes to be committed: (use \u0026#34;git restore --staged \u0026lt;file\u0026gt;...\u0026#34; to unstage) modified: test Changes not staged for commit: (use \u0026#34;git add \u0026lt;file\u0026gt;...\u0026#34; to update what will be committed) (use \u0026#34;git restore \u0026lt;file\u0026gt;...\u0026#34; to discard changes in working directory) modified: test 上图中存在两部分, 分别为 Changes to be committed 这里是表示的版本库与暂存区的区别,还有Changes not staged for commit ,它表示的是工作区与暂存区的区别。\n版本库是我们执行 git commit -m \u0026quot;xxx\u0026quot; 后,文件存在的区域。在上述过程中,Git 记录暂存区与版本库的差异,生成版本号,记录下来。我们可以通过 git log 来查看我们产生的更改,内容如下:\ncommit 9da52a0e4800547ca46bd6bb919d1105cea43f1e (HEAD -\u0026gt; master) Author: zs \u0026lt;2459958352@qq.com\u0026gt; Date: Thu Jul 22 22:09:45 2021 +0800 test commit 其中包含了版本号、当前节点上的 ref 记录、作者、邮箱、日期以及此次提交的注释。\nGit中的引用 在 Git 中,引用到处可见,引用类似于给某一个 commit-id 即某一次提交的 SHA-1 值起一个简单的名字,如 branch ,tag 这些都是引用。\nGit 中存在一个命令, git update-ref ,你可能几乎没见过,但可能天天在用。\n当运行类似于 git branch \u0026lt;branch\u0026gt; 这样的命令时,Git 实际上会运行 git update-ref 命令,例如,运行 git branch zs,就等效于\n$ git update-ref refs/heads/zs \u0026lt;commit-id\u0026gt; 这里的 commit-id 就是当前提交的 commit-id ,那他是如何获得的呢?\n使用过 Git 的人一定知道,Git 中存在一个名叫 HEAD 的引用,它可能是引用,也可能是引用的引用。即它很多时候是指向某一个引用,如指向分支 master 这个引用。不过,它也可以与引用分离,称为游离的HEAD,即不指向某个引用,而指向单独的一个 commit 。\n可以通过 git commit commit-id 来实现,不过,我们一般不推荐这种操作。下面的讨论,我们都是基于 HEAD 是指向某一分支的。\n下面是关于一个引用的小例子:\n~/test master* base ❯ git branch zs ~/test master* base ❯ cat .git/refs/heads/zs 9da52a0e4800547ca46bd6bb919d1105cea43f1e ~/test master* base ❯ git update-ref refs/heads/test 9da52a ~/test master* base ❯ cat .git/HEAD ref: refs/heads/master ~/test master* base ❯ cat .git/refs/heads/master 9da52a0e4800547ca46bd6bb919d1105cea43f1e ~/test master* base ❯ cat .git/refs/heads/test 9da52a0e4800547ca46bd6bb919d1105cea43f1e 可以发现,例子中 HEAD 指向 master ,master,zs,test 同时都指向 id 为 9da52a 的提交。\n撤销更改 撤销本地更改 通过版本库撤销暂存区更改,工作区不改 $ git reset HEAD^ #撤销一次更改 $ git reset HEAD~nums #撤销HEAD往前nums次更改 直接通过版本库撤销工作区的更改 $ git reset HEAD^ --hard #撤销一次更改 $ git reset HEAD~nums --hard #撤销HEAD往前nums次更改 可以发现只要加了 --hard ,就可以直接也把工作区改掉,不过建议三思而后行!\n撤销远程更改 上面说的是你本地的工作区 or 暂存区的撤销\n如果你已经把更改推送到了远端仓库,那么你想要去掉那次改动怎么办?\n可能你会想,直接通过 git reset 切换到上面的某个需要的节点,然后再改?But,很容易想到这样会产生严重的冲突。一旦commit已经被push到远程仓库,那么是坚决不允许去reset它的。\n还好,Git 给我们提供了一个更好的选择,你可以通过 git revert 产生一个类似于补丁的东西来消除掉更改,很容易理解,这样没有改变树的结构,相对于 git reset 他会往前走而不是回溯,这不会对之前的历史产生重要的影响。\n需要注意的是, git revert 的用法:\n$ git revert HEAD #撤销掉HEAD这次更改,回到HEAD的上次版本 $ git revert \u0026lt;commit_id\u0026gt; #撤销掉这次cmmit的修改 两种合并方式 我们知道,Git 中存在两种合并分支的方式,分别为 git merge 和 git rebase 。\n两种方式各有优劣,简单说,rabase 是把两条分支的提交记录整理到某一主分支上,它有着历史的完整记录。而 merge 虽然也是整理了提交,但是某一分支的中间提交更改的过程合并后并不会体现在主分支上,中间过程可以说是在主分支上不可见的。\n很容易发现,rebase 产生的主分支提交记录会更加的详细,它记录了每一步小的改动。而 merge 产生的更简洁,有点类似于封装的意味,只是告诉你我这个提交完成了这个任务的开发,内部的实现细节却不会告诉你。\n而 rebase 相比与 merge 也会更加繁琐一些,你也可以通过 git rebase -i 来通过可视化界面(可视化文本列表)的方式,来对记录做取舍与改动,不过还是没有 merge 方便,远程仓库的合并操作一般都是使用 merge 。\n需要注意的是,两种方法的使用习惯很不一样:\n$ git merge \u0026lt;branch\u0026gt; 代表的是将 \u0026lt;branch\u0026gt; 分支合并到当前 HEAD 所在的分支。\n$ git rebase \u0026lt;branch1\u0026gt; \u0026lt;branch2\u0026gt; 代表的是将 branch2 合并到 \u0026lt;branch1\u0026gt; 的位置。如果省略 \u0026lt;branch2\u0026gt; ,那么就是合并 HEAD 所在分支到 \u0026lt;branch1\u0026gt; 分支。\n可以发现 merge 体现的是一种, merge xx 到当前位置。而 rebase 体现的是将自己合并到 xx 那里去。一个是别人过来,一个是自己过去。建议两个命令改成 merge from ,rebase into,哈哈。\n顺便提一下, merge 会导致一个节点有多个父节点,通过上文我们知道可以通过 ~ 在一条线上移动,在这里,我们可以通过 ^ 来指定第几个父节点,如 HEAD^3 就是指 HEAD 所在节点的第三个父节点。\n整理提交记录 我们有时会需要把另一个分支的部分更改放到主分支上来,即整理我们所有的提交记录,拿到我们所需要的来组成一个完整功能。\n为了完成这件事,我们想到,这有点像合并分支,不过可能不需要某一个分支上的全部更改,只需要其中的一部分就可以了。\n上面提到,通过 git rebase -i 可以进行交互式的 rebase ,可以对提交记录进行取舍,因此这样就可以满足我们的需求,只不过可能合并的时候需要想明白是从哪里变到哪里,有一些烧脑。\n幸运的是,Git 还给我们提供了另一个更加简洁的方式——git cherry-pick ,语法如下:\n$ git cherry-pick \u0026lt;commid-id\u0026gt; 你可以通过这种方式,将树上的任意一个节点的提交添加到当前 HEAD 所在分支的下方,这真是功能强大的命令!你也可以通过空格间隔,来顺序摘取多个提交。\n两条万能指令 除了上面我觉得值得说道的问题,我还想推荐两条我认为非常有用的指令,掌握了他们,你就可以在分支树上随心所欲的移动!\n移动分支 $ git branch -f \u0026lt;branch\u0026gt; \u0026lt;commit-id\u0026gt; 通过这条指令,你可以将 \u0026lt;branch\u0026gt; 的引用指向 commit-id ,如果你读懂了上面的内容,你会发现它只是通过 update-ref 更新了对应的引用。\n移动 HEAD $ git checkout \u0026lt;branch\u0026gt; $ git checkout \u0026lt;commit-id\u0026gt; 通过这条指令,你可以自由的移动 HEAD 引用,前者让他指向了 \u0026lt;branch\u0026gt; 分支,后者让他指向了SHA-1为 \u0026lt;commit-id\u0026gt; 的提交。\n推荐的资料 在学习的过程中,看了很多资料,一并推荐给大家!\nlearnGitBranching:有趣的闯关游戏,但也干货满满。\nGit三大分区概念:讲解了关于分区的概念,还有直观清晰的图片!\nGit的引用:来自 Git 官方的讲解,十分硬核。\n","permalink":"https://blog.zzsqwq.cn/posts/201/","summary":"前言 前段时间在 Github 学完了关于 git 的小游戏 learnGitBranching ,受益匪浅。\n它通过可视化的方式将分支的关系,每条命令的作用等都明明白白的体现出来,可以很直观的感受到你每条命令对整个分支树,每一个 ref 的作用。\n通过这种学习感觉自己对 Git 的理解更加深入一步,能够理解其中的原理,而不是浅尝辄止,照猫画虎。\n学习中记了一些零零散散的思路,想要写一篇笔记记录出来,之前已经写过一个简单的 Git 教程,这篇教程将会更加深入,希望可以帮助大家更好的掌握 Git。\n窃认为,想要学好 Git ,必须要理解清楚其中的分区以及引用,学会了这两个,各种基本操作就很容易理解了。接下来的笔记也基本以此思路展开。\nGit中的分区 首先,Git中存在三大分区,分别是工作区、暂存区、版本库。其中,\n工作区即我们工作的目录,暂存区是我们执行 git add 后文件存在的区域。\n我们可以通过 git status 对两种状态进行查看,例如:\n~/test master* base ❯ git status On branch master Changes to be committed: (use \u0026#34;git restore --staged \u0026lt;file\u0026gt;...\u0026#34; to unstage) modified: test Changes not staged for commit: (use \u0026#34;git add \u0026lt;file\u0026gt;...\u0026#34; to update what will be committed) (use \u0026#34;git restore \u0026lt;file\u0026gt;.","title":"关于Git的一些理解"},{"content":"前言 最近基地的打印机突然又好起来了。\n因为基地的打印机型号比较老——HP LaserJet 1020,没有无线打印的功能。所以之前一位学长1 用树莓派配置了打印机的无线打印功能,但是后来发现有一些问题,有时候发送打印请求树莓派无法接收,而且不知道为何,学长之前用的是树莓派自己创建WiFi,连接对应WiFi才能打印,但是这个显然不是最优的解决办法。\n考虑到之间已经配置好基地WiFi,我决定重新配置一下打印功能,使其连接基地WiFi即可实现局域网打印。\n配置过程 查看树莓派内容 通过ssh连接树莓派,发现里面除了Github上的一个开源项目create_ap ,就没有什么其他的内容了,连接屏幕后发现没有任何图像信号,无从下手,因此考虑重新刷机。\n对树莓派进行刷机 把数据备份了一下,看了一下树莓派版本是2015年生产的 Raspberry Pi 3 model B V1.2 ,是老古董了。\n去官网看了一下,因为我对Ubuntu比较熟悉,我计划安装一个 Ubuntu20.04版本的,考虑到版本比较老,就装了server版本的,相比与desktop版本负担更小一些。\n其实就是下一个官方的软件,Raspberry Pi Imager ,直接用读卡器对树莓派的存储卡刷机即可。\n这里是对应的镜像以及教程: 镜像下载 安装教程\n配置网络相关 Ubuntu的server版本有个比较蛋疼的问题就是上网比较困难,如果是用的学校网线,必须要PPPOE拨号才能上网,但是server版本居然没有 net-tools 和 network-manager ,连接WiFi啥的试了很多办法但还是没有什么作用。\n解决办法:用网线直接连接树莓派和有网的路由器,安装 net-tools 和 network-manager ,执行\n$ sudo nmtui 选择 Activate a connect 连接无线的WiFi,执行\n$ sudo ifconfig 查看WiFi对应的IP,至此,树莓派可以摆脱屏幕,我们可以使用电脑进行使用 ssh 连接。\n这里也可以使用网线进行连接,具体操作如下\n用网线连接树莓派和自己的电脑。\n在树莓派的利用 nmtui 选择 Edit a connection ,Add一个Ethernet connect,对IPv4 CONFIGURATION进行设置,首先讲 Automatic 设置为 Manual,设置 Address 为 静态IP 如 192.168.3.2 ,Gateway 设置为 192.168.3.1 。\n在自己电脑利用 nmtui 同上不过设置 Address 为 192.168.3.3 ,只要是位于同一网段即可。\n这时候就可以通过网线进行 ssh 连接了。\n配置cups 以下大多参考:如何正确地用树莓派共享打印机\n大佬言:\n其实,这一步的工作量非常少,因为软件包 CUPS 就是为共享打印机而生。我们要做的只是将打印机用 USB 线缆连接树莓派,然后安装并配置 CUPS。\n然而,事实并非如此。\n换源 在安装之前需要换源,如果不换源的话,安装会十分缓慢,具体的流程可以看上面的blog,因为我们基地的WiFi自带代理,因此这一步我没有做。\n安装驱动及打印程序 首先更新源并安装Hp的打印机驱动 hplip $ sudo apt update $ sudo apt install hplip 然后安装Apple开源的远程打印工具 cups,并配置相应权限 $ sudo apt install cups # Install cups package $ sudo usermod -aG lpadmin pi # Add user to lpadmin group,pi is your user name $ sudo cupsctl --remote-any # open remote access 然后使用在同一局域网的电脑,访问 https://树莓派IP:631,可以进入如下界面,按照下图设置右侧的Server Settings 连接打印机和树莓派,点击Add Printer添加打印机,在弹出的窗口中输入对应的用户信息,使用在上一步中用户组中添加的用户\n然后按着一步步的指引,选择HP LaserJet 1020打印机,然后按照提示,选择和名称对应的驱动,我们会发现 LaserJet 1020 对应驱动会提示:HP laserjet requires proprietary plugin,也就是我们不仅需要这个通用的驱动,而且需要一些额外的插件,打印机才能正常工作。\n查阅资料发现:HP官方已经给出了说明,我们需要查看hplip版本,然后安装对应的驱动插件。\n首先我们查看一下版本,发现是3.20.3版本 $ sudo apt show hplip Package: hplip Version: 3.20.3+dfsg0-2 Priority: optional Section: utils Origin: Ubuntu Maintainer: Ubuntu Developers \u0026lt;ubuntu-devel-discuss@lists.ubuntu.com\u0026gt; Original-Maintainer: Debian Printing Team \u0026lt;debian-printing@lists.debian.org\u0026gt; Bugs: https://bugs.launchpad.net/ubuntu/+filebug Installed-Size: 518 kB 然后在 插件列表 中找到 3.20.3 对应的hplip-3.20.3-plugin.run和hplip-3.20.3-plugin.run.asc,使用wget下载到树莓派本地。\n运行 hp-setup -i 使用命令行进行安装,按照提示命令,进行插件的安装。\n[scode type=\u0026ldquo;yellow\u0026rdquo;]这里建议提前下好安装,而不是直接联网下载,速度较快,指定路径需要为绝对路径[/scode]\n至此,我们可以尝试使用手机或者电脑搜索打印机来进行打印测试,没有其他意外的话,可以发现打印成功!\n结语 其实这个配置过程远没有这么简单,期间还有很多小问题,但是大致的流程大概就是如上述所示,全写出来可能太啰嗦,大家如果配置过程中遇到更多的疑问,可以在下方评论一起探讨~\n参考链接 What is the HPLIP Binary Plug-In and How Do I Install It? Plugins Other Plugins cups 使用树莓派搭建无线打印机 如何正确地用树莓派共享打印机 学长的博客在这里:\tdykai\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","permalink":"https://blog.zzsqwq.cn/posts/198/","summary":"前言 最近基地的打印机突然又好起来了。\n因为基地的打印机型号比较老——HP LaserJet 1020,没有无线打印的功能。所以之前一位学长1 用树莓派配置了打印机的无线打印功能,但是后来发现有一些问题,有时候发送打印请求树莓派无法接收,而且不知道为何,学长之前用的是树莓派自己创建WiFi,连接对应WiFi才能打印,但是这个显然不是最优的解决办法。\n考虑到之间已经配置好基地WiFi,我决定重新配置一下打印功能,使其连接基地WiFi即可实现局域网打印。\n配置过程 查看树莓派内容 通过ssh连接树莓派,发现里面除了Github上的一个开源项目create_ap ,就没有什么其他的内容了,连接屏幕后发现没有任何图像信号,无从下手,因此考虑重新刷机。\n对树莓派进行刷机 把数据备份了一下,看了一下树莓派版本是2015年生产的 Raspberry Pi 3 model B V1.2 ,是老古董了。\n去官网看了一下,因为我对Ubuntu比较熟悉,我计划安装一个 Ubuntu20.04版本的,考虑到版本比较老,就装了server版本的,相比与desktop版本负担更小一些。\n其实就是下一个官方的软件,Raspberry Pi Imager ,直接用读卡器对树莓派的存储卡刷机即可。\n这里是对应的镜像以及教程: 镜像下载 安装教程\n配置网络相关 Ubuntu的server版本有个比较蛋疼的问题就是上网比较困难,如果是用的学校网线,必须要PPPOE拨号才能上网,但是server版本居然没有 net-tools 和 network-manager ,连接WiFi啥的试了很多办法但还是没有什么作用。\n解决办法:用网线直接连接树莓派和有网的路由器,安装 net-tools 和 network-manager ,执行\n$ sudo nmtui 选择 Activate a connect 连接无线的WiFi,执行\n$ sudo ifconfig 查看WiFi对应的IP,至此,树莓派可以摆脱屏幕,我们可以使用电脑进行使用 ssh 连接。\n这里也可以使用网线进行连接,具体操作如下\n用网线连接树莓派和自己的电脑。\n在树莓派的利用 nmtui 选择 Edit a connection ,Add一个Ethernet connect,对IPv4 CONFIGURATION进行设置,首先讲 Automatic 设置为 Manual,设置 Address 为 静态IP 如 192.","title":"利用树莓派为HP LaserJet 1020配置无线打印功能"},{"content":"问题描述 ​Ubuntu下想要使用QQ有一个比较好的解决方案就是deepin-wine的版本,deepin-wine版本的QQ一共有两个版本,分别是 8.9.1 和 9.1.8 ,前者安装后发现无法登陆,登录时会提示版本过低的问题,于是我换到9.1.8版本后,启动初始化后就无任何信息了,于是开始排查问题\n解决方案 ​首先我们根据上文的启示,因为每一个应用程序对应了一个 xxx.desktop 文件,因此在应用库中的QQ一定也有一个对应的 desktop 文件\n​我们进入到 /usr/share/applications ,运行\n$ ls | grep -i qq ​可以发现其中有一个名为 deepin.com.qq.im.desktop 的文件,我们打开后发现内容如下:\n#!/usr/bin/env xdg-open [Desktop Entry] Encoding=UTF-8 Type=Application X-Created-By=Deepin WINE Team Categories=chat; Icon=deepin.com.qq.im Exec=\u0026#34;/opt/deepinwine/apps/Deepin-QQ/run.sh\u0026#34; -u %u Name=QQ Name[zh_CN]=QQ Comment=Tencent QQ Client on Deepin Wine StartupWMClass=QQ.exe MimeType= ​可以看到Exec那一栏为 Exec=\u0026quot;/opt/deepinwine/apps/Deepin-QQ/run.sh\u0026quot; -u %u ,发现他是运行目录下的一个 run.sh 脚本来启动的。\n​我们进入目录下直接运行该脚本,查看log信息:\nbase ❯ ./run.sh Run Deepin-QQ 9.1.8deepin0 c:/Program Files/Tencent/QQ/Bin/QQ.exe run Deepin-QQ progress pid Gtk-Message: 01:16:58.069: GtkDialog mapped without a transient parent. This is discouraged. total 0 lrwxrwxrwx 1 zs zs 10 6月 16 01:16 c: -\u0026gt; ../drive_c lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com1 -\u0026gt; /dev/ttyS0 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com10 -\u0026gt; /dev/ttyS9 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com11 -\u0026gt; /dev/ttyS10 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com12 -\u0026gt; /dev/ttyS11 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com13 -\u0026gt; /dev/ttyS12 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com14 -\u0026gt; /dev/ttyS13 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com15 -\u0026gt; /dev/ttyS14 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com16 -\u0026gt; /dev/ttyS15 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com17 -\u0026gt; /dev/ttyS16 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com18 -\u0026gt; /dev/ttyS17 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com19 -\u0026gt; /dev/ttyS18 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com2 -\u0026gt; /dev/ttyS1 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com20 -\u0026gt; /dev/ttyS19 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com21 -\u0026gt; /dev/ttyS20 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com22 -\u0026gt; /dev/ttyS21 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com23 -\u0026gt; /dev/ttyS22 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com24 -\u0026gt; /dev/ttyS23 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com25 -\u0026gt; /dev/ttyS24 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com26 -\u0026gt; /dev/ttyS25 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com27 -\u0026gt; /dev/ttyS26 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com28 -\u0026gt; /dev/ttyS27 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com29 -\u0026gt; /dev/ttyS28 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com3 -\u0026gt; /dev/ttyS2 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com30 -\u0026gt; /dev/ttyS29 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com31 -\u0026gt; /dev/ttyS30 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com32 -\u0026gt; /dev/ttyS31 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com4 -\u0026gt; /dev/ttyS3 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com5 -\u0026gt; /dev/ttyS4 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com6 -\u0026gt; /dev/ttyS5 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com7 -\u0026gt; /dev/ttyS6 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com8 -\u0026gt; /dev/ttyS7 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com9 -\u0026gt; /dev/ttyS8 lrwxrwxrwx 1 zs zs 8 6月 16 01:16 y: -\u0026gt; /home/zs lrwxrwxrwx 1 zs zs 1 6月 16 01:16 z: -\u0026gt; / CallApp Deepin-QQ c:/Program Files/Tencent/QQ/Bin/QQ.exe 2021年 06月 16日 星期三 01:16:58 CST:kill QQ.exe block 2021年 06月 16日 星期三 01:16:58 CST:No wine process found /home/zs/.deepinwine/Deepin-QQ/drive_c/Program Files/Tencent/QQ/Bin Starting process c:/Program Files/Tencent/QQ/Bin/QQ.exe ... /opt/deepinwine/apps/Deepin-QQ base ❯ wine: cannot find L\u0026#34;C:\\\\windows\\\\system32\\\\winemenubuilder.exe\u0026#34; wine version: 2.18 libGL error: No matching fbConfigs or visuals found libGL error: failed to load driver: swrast X Error of failed request: GLXBadContext Major opcode of failed request: 152 (GLX) Minor opcode of failed request: 6 (X_GLXIsDirect) Serial number of failed request: 207 Current serial number in output stream: 206 ​可以发现最下面的log信息有一些异常,首先第一行是因为我们是Ubuntu系统,可以暂且不关注\n​接下来可以看到有一个LibGL的错误,我们通过Google搜索\nlibGL error: No matching fbConfigs or visuals found libGL error: failed to load driver: swrast X Error of failed request: GLXBadContext Major opcode of failed request: 152 (GLX) Minor opcode of failed request: 6 (X_GLXIsDirect) Serial number of failed request: 207 Current serial number in output stream: 206 ​发现类似的错误及解决方案如下:\nSOLVED] LibGL errors with osu! and wine\nSteam: libGL error: No matching fbConfigs or visuals found libGL error: failed to load driver: swrast\n​从搜索结果来看,这个问题还是非常常见的,用steam也会遇到,一般都是因为电脑安装了64位的NVIDIA显卡驱动,但是因为应用是32位的导致不能兼容,因此无法启动\n​最终解决方案有两个\n如果是不常用NVIDIA驱动的人,普通的办公一下,可以搜索网上教程关闭独显,只启用集显,可以发现QQ可以正常启动, 重新安装32位的NVIDIA驱动 最后 虽然已经知道了解决方案,但是最终我还是选择卸载掉QQ,安装了wine版本的TIM,感觉和QQ没什么区别,而且更加简洁,而且可以流畅运行,没有N卡兼容问题!大家可以考虑一下~\n而且QQ和TIM某些情况下会出现bug,字体全部变为方块,在 deepin-wine-ubuntu 的 Issues 中找到了解决方案 Ubuntu 安装QQ后中文方块解决方法 ,大家有同样困扰的也可以看一下~\n","permalink":"https://blog.zzsqwq.cn/posts/195/","summary":"问题描述 ​Ubuntu下想要使用QQ有一个比较好的解决方案就是deepin-wine的版本,deepin-wine版本的QQ一共有两个版本,分别是 8.9.1 和 9.1.8 ,前者安装后发现无法登陆,登录时会提示版本过低的问题,于是我换到9.1.8版本后,启动初始化后就无任何信息了,于是开始排查问题\n解决方案 ​首先我们根据上文的启示,因为每一个应用程序对应了一个 xxx.desktop 文件,因此在应用库中的QQ一定也有一个对应的 desktop 文件\n​我们进入到 /usr/share/applications ,运行\n$ ls | grep -i qq ​可以发现其中有一个名为 deepin.com.qq.im.desktop 的文件,我们打开后发现内容如下:\n#!/usr/bin/env xdg-open [Desktop Entry] Encoding=UTF-8 Type=Application X-Created-By=Deepin WINE Team Categories=chat; Icon=deepin.com.qq.im Exec=\u0026#34;/opt/deepinwine/apps/Deepin-QQ/run.sh\u0026#34; -u %u Name=QQ Name[zh_CN]=QQ Comment=Tencent QQ Client on Deepin Wine StartupWMClass=QQ.exe MimeType= ​可以看到Exec那一栏为 Exec=\u0026quot;/opt/deepinwine/apps/Deepin-QQ/run.sh\u0026quot; -u %u ,发现他是运行目录下的一个 run.sh 脚本来启动的。\n​我们进入目录下直接运行该脚本,查看log信息:\nbase ❯ ./run.sh Run Deepin-QQ 9.1.8deepin0 c:/Program Files/Tencent/QQ/Bin/QQ.exe run Deepin-QQ progress pid Gtk-Message: 01:16:58.069: GtkDialog mapped without a transient parent.","title":"deepin-wine-qq-9.1.8版本无法正常启动的解决方案"},{"content":"前言 前一阵学校有五一数模节校赛,和朋友一起参加做B题,波士顿房价预测,算是第一次自己动手实现一个简单的小网络吧,虽然很简单,但还是想记录一下。\n题目介绍 波士顿住房数据由哈里森和鲁宾菲尔德于1978年Harrison and Rubinfeld1收集。它包括了波士顿大区每个调查行政区的506个观察值。1980年Belsley et al.2曾对此数据做过分析。\n数据一共14列,每一列的含义分别如下:\n英文简称 详细含义 CRIM 城镇的人均犯罪率 ZN 大于25,000平方英尺的地块的住宅用地比例。 INDUS 每个镇的非零售业务英亩的比例。 CHAS 查尔斯河虚拟变量(如果环河,则等于1;否则等于0) NOX 一氧化氮的浓度(百万分之几) RM 每个住宅的平均房间数 AGE 1940年之前建造的自有住房的比例 DIS 到五个波士顿就业中心的加权距离 RAD 径向公路通达性的指标 TAX 每一万美元的全值财产税率 PTRATIO 各镇的师生比率 B 计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例 LSTAT 底层人口的百分比(%) price 自有住房数的中位数,单位(千美元) 基于上述数据,请完成以下问题:\n建立波士顿房价预测模型并对预测结果进行评价。\n问题分析 首先这道题目的很明确,数据一共是 $506×14$ 的一个矩阵,有十三维的自变量,通过建立一个模型来拟合回归出最终的因变量 price,即户主拥有住房价值的中位数。这是一个回归问题,综合考虑有以下两个思路\n通过各种回归算法(GradientBoostingRegressor,RandomForestRegressor,ExtraTreesRegressor,LinearRegressor等)结合全部或部分自变量来回归最终的price\n建立前馈神经网络模型,根据通用逼近定理,我们可以拟合此回归模型。\n我们对上述模型来进行实现并确定评估标准来对他们进行比较,选择最优的模型作为预测模型。\n算法流程 传统的回归算法 自变量的选择 首先,考虑到数据集中13列自变量其中某一些可能和最终的房价并无强相关性,如果全部使用进行预测可能会对模型引入噪声,因此我们首先计算了房价price与各个自变量之间的相关系数 $r$ ,其中 $r$ 计算公式如下: $$ r = \\frac{\\sum(x_i-\\bar{x})(y_i-\\bar{y})}{\\sqrt{\\sum(x_i-\\bar{x})^2\\sum(y_i-\\bar{y})^2}} $$ 其中 $x_i,y_i$ 为数据的每个分量,$\\bar{x},\\bar{y}$ 为数据的均值\n该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下:\nCRIM ZN INDUS CHAS NOX RM LSTAT -0.385832 0.360445 -0.483725 0.175260 -0.427321 0.695360 -0.737663 AGE DIS RAD TAX PTRATIO B -0.376955 0.249929 -0.381626 -0.468536 -0.507787 0.333461 观察结果可以发现,在给定的十三个变量中,LSTAT 与 price 的相关程度最高$(|r|\u0026gt;0.7)$,其次是 RM 与PTRATIO $(|r|\u0026gt;0.5)$,再者是 TAX,INDUS,NOX $(|r|\u0026gt;0.4)$,除上述之外的七个变量都与 price 无较强的相关性,因此我们考虑使用六个相关性较强变量和十三个变量分别来对房价进行预测,并对他们进行对比,来寻找最优的回归模型。\n模型的构建 首先我们使用了sklearn中自带的 boston 数据集,并将整体数据集随机划分为了训练集和测试集两部分,所占比例分别为80%和20%。\n然后,我们利用Linear,Ridge,Lasso,ElasticNet,DecisionTree,GradientBoosting,RandomForest,ExtraTrees八种模型通过训练集对其进行训练。\n接下来,我们利用训练集拟合得到的模型,使用测试集对其进行测试,与 Ground Truth 进行对比,并通过 $R^2$ 来评价该预测结果,其中 $R^2$ 计算公式如下,其是衡量回归模型好坏的常见指标,其值一般处于[0,1]之间,$R^2$ 越接近1,说明模型的性能越好。 $$ R^2 = 1-\\frac{\\sum(\\hat{y_i}-y_i)^2}{\\sum(\\bar{y}-y_i)^2} $$\n最后,考虑到模型的训练及预测可能具有偶然性,因此我们对于每一个模型进行20次训练及预测,利用20次的结果对其进行综合评价。利用得到的结果绘制 箱线图 所得结果如下:\n分析最终结果可以发现,无论是使用六个相关性较强变量还是十三个变量来进行预测,GradientBoost(梯度提升决策树)回归模型都是最好的,此外,我们可以发现,利用十三个变量要比利用六个主要变量来进行预测比有着更好的效果。\n前馈神经网络 模型的构建 近年来,神经网络理论不断发展,前馈神经网络(多层感知机、全连接神经网络)越来越多的被利用到数据分析中,因此考虑使用前馈神经网络来解决此问题。\n前馈神经网络(全连接神经网络)的网络结构一般由三部分构成,输入层,隐藏层,以及输出层,输入层与输出层一般只有一层,隐藏层可有多层。中间利用非线性函数作为激活函数可以使得网络具有拟合非线性函数的能力\n根据通用近似定理:\n通用近似定理\n对于具有线性输出层和至少一个使用“挤压”性质的激活函数的隐藏层组成的前馈神经网络,只要其隐藏层神经元的数量足够,它可以以任意精度来近似任何从一个定义在实数空间中的有界闭集函数。\n只要隐藏层网络维度够高,就可以拟合任意的函数。\n考虑到我们的模型有六维or十三维的数据输入,因此我们建立两层前馈神经网络,中间具有一层隐藏层,维度为1000维,激活函数使用Relu,Relu函数有以下优点:\nRelu相比于传统的Sigmoid、Tanh,导数更加好求,反向传播就是不断的更新参数的过程,因为其导数不复杂形式简单,可以使得网络训练更快速。\n此外,当数值过大或者过小,Sigmoid,Tanh的导数接近于0,Relu为非饱和激活函数则不存在这种现象,可以很好的解决梯度消失的问题\nRelu函数及网络结构图如图所示:\n$$ Relu:f(x) = max(0,x) $$\n具体实现 利用流行的深度学习框架 Pytorch 来对模型进行实现。\n首先,将数据集随机划分为训练集和测试集两部分,分别占80%和20%,并将其转化为Pytorch中的张量形式。 然后,利用MinMaxScaler对输入数据进行归一化,利用下列公式将其统一归一化为 $[0,1]$ 之间,以求模型能够更快的收敛。 $$ MinMaxScaler:x^{*} = \\frac{x-min(x)}{max(x)-min(x)} $$\n接下来,构建网络模型,利用 mseloss 作为损失函数,在训练过程中利用反向传播使其最终收敛为0。 $$ MseLoss = \\frac{1}{2n}\\sum||y(x)-a^L(x)||^2 $$\n最后,我们设置网络的学习率为0.01,训练10000个epoch,发现其loss最终降低到0.3%左右,我们利用上文提到的 $R^2$ 对结果进行评估并与回归模型进行对比,通过观察图片可以发现,前馈神经网络相比于传统的回归模型有着更好的拟合效果, 20次预测得到的$R^2$平均值达到了0.95,此外中位数,最大值,最小值也要比回归模型更加优秀,因此我们采用前馈神经网络模型来对最后的房价进行预测。 最终预测 最终我们利用构建的前馈神经网络模型进行预测,利用测试集对其进行对比,绘制预测如下:\n​\n可以看到其中很多点都覆盖的很好,即预测准确。\n通过理论对模型进行量化分析,计算预测的 $R^2$ $$ R^2 = 1-\\frac{\\sum(\\hat{y_i}-y_i)^2}{\\sum(\\bar{y}-y_i)^2} = 1-0.01357 = 0.98643=98.643% $$ 可以发现 $R^2$ 十分接近1,说明回归模型性能良好,符合要求。\n实现代码 代码放在我的Github了,其中写了较详细的README,链接为 BostonPredict 参考链接 很系统的波士顿房价预测研究报告(期中作业)\n作业-机器学习-波士顿房价预测 四种回归算法\n基于Python预测波士顿房价\n波士顿房价预测——回归分析案例(献给初学者)\n","permalink":"https://blog.zzsqwq.cn/posts/182/","summary":"前言 前一阵学校有五一数模节校赛,和朋友一起参加做B题,波士顿房价预测,算是第一次自己动手实现一个简单的小网络吧,虽然很简单,但还是想记录一下。\n题目介绍 波士顿住房数据由哈里森和鲁宾菲尔德于1978年Harrison and Rubinfeld1收集。它包括了波士顿大区每个调查行政区的506个观察值。1980年Belsley et al.2曾对此数据做过分析。\n数据一共14列,每一列的含义分别如下:\n英文简称 详细含义 CRIM 城镇的人均犯罪率 ZN 大于25,000平方英尺的地块的住宅用地比例。 INDUS 每个镇的非零售业务英亩的比例。 CHAS 查尔斯河虚拟变量(如果环河,则等于1;否则等于0) NOX 一氧化氮的浓度(百万分之几) RM 每个住宅的平均房间数 AGE 1940年之前建造的自有住房的比例 DIS 到五个波士顿就业中心的加权距离 RAD 径向公路通达性的指标 TAX 每一万美元的全值财产税率 PTRATIO 各镇的师生比率 B 计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例 LSTAT 底层人口的百分比(%) price 自有住房数的中位数,单位(千美元) 基于上述数据,请完成以下问题:\n建立波士顿房价预测模型并对预测结果进行评价。\n问题分析 首先这道题目的很明确,数据一共是 $506×14$ 的一个矩阵,有十三维的自变量,通过建立一个模型来拟合回归出最终的因变量 price,即户主拥有住房价值的中位数。这是一个回归问题,综合考虑有以下两个思路\n通过各种回归算法(GradientBoostingRegressor,RandomForestRegressor,ExtraTreesRegressor,LinearRegressor等)结合全部或部分自变量来回归最终的price\n建立前馈神经网络模型,根据通用逼近定理,我们可以拟合此回归模型。\n我们对上述模型来进行实现并确定评估标准来对他们进行比较,选择最优的模型作为预测模型。\n算法流程 传统的回归算法 自变量的选择 首先,考虑到数据集中13列自变量其中某一些可能和最终的房价并无强相关性,如果全部使用进行预测可能会对模型引入噪声,因此我们首先计算了房价price与各个自变量之间的相关系数 $r$ ,其中 $r$ 计算公式如下: $$ r = \\frac{\\sum(x_i-\\bar{x})(y_i-\\bar{y})}{\\sqrt{\\sum(x_i-\\bar{x})^2\\sum(y_i-\\bar{y})^2}} $$ 其中 $x_i,y_i$ 为数据的每个分量,$\\bar{x},\\bar{y}$ 为数据的均值\n该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下:","title":"利用神经网络进行波士顿房价预测"},{"content":"前言 ​说起来的话今天距离比赛已经过去近一个月了,比赛结束一直想要记录一下and总结一下经验,但是实在是太懒了,临近五一假期,在四月的末尾为这次中国赛画一个句号吧。\n比赛过程 ​如果没记错的话比赛是3.30号(周二)去,4.1号(周四)结束,共三天。但是因为第三天没做什么有意义的事情,就只记录两天了。\n第一天 ​第一天大概中午十点到的吧,去的时候登记完领了牌,就在当地布置场地了。到了场地上才发现,我们好像是拿的东西最多的,包括外接显示屏和集成主机,好像都基本没人带过去····集成主机拿了过去也没怎么用到,本来预想用到的哨岗相机因为 ROS 的通信问题也没能跑成,最后两个机器人还是各跑各的策略了。\n​调试的时候出了一点问题,两个哨岗相机通过20m的USB延长线后,只有一个能连接,后来排查了一下,好像是因为有一条线是光纤USB3.0的线,跟相机的接口不兼容···这个问题还没想好怎么解决,可能会考虑到时候自己带一根USB延长线过去。\n​犹记得调试的时候是和青海大学一起调的,有点可惜的是调试中的我方机器人一直在一个地方鬼畜。那晚上我记得大家熬到了很晚···很可惜的视觉因为用的是学习的框架可调性很差,并没有帮上太大的忙。\n第二天 ​第二天记得一共有三场比赛,分别是打哈工大,哈工大深圳,以及青海大学。\n​在比赛过程中其实对视觉,我没有做太多的调整,主要还是大家在写导航和策略相关的东西吧。\n​跟哈工大打的那一场二车因为没有写好启动判定被罚下了,一车因为点位有问题一直卡在障碍物上。\n​跟哈工深和哈工大两场之间还隔了挺长时间,一个上午是一个下午,中间大家调试了很久,幸好在下午和哈工深打的时候基本没有鬼畜,可以正常的对局,只是因为实力不够强,很明显的一个问题就是视觉做的有问题吧,很多时间在朝着自己的队友打,还有就是会朝着场外的人员打,这是需要改进的点。\n​跟青海大学打的那场,距和哈工深比赛结束只有十几分钟的间隔时间,大家调了一个小bug就又重新赶去检录了,虽然当时已知青海大学的战术是站在原地不动的,但是由于不知道哪里出问题了,比赛中前一分钟两车都没动,后一分钟二车虽然动起来了去吃了加成区,但是因为定位的一些问题,没有看到敌方机器人并且撞墙了··自己撞掉了60血,最后还是败了QAQ。\n​所以就很耻辱的被3:0送走了,这样就结束了比赛日程。\n​值得反思的事情很多吧,赛前虽然基本熬了一个多星期来调车,还是只在最后一天才开始连裁判系统联调,包括暑假效率不高等问题都是值得反思的···打完比赛心中大概已经有了一些改进点,也想把自己的一些调车心得等记录下来,但是因为时间以及学业上的一些事情等一直没去做,本来计划的五月初做好改进的视觉也一直没兑现,希望这个五一假期会有较大的突破吧,不过还要打数模···好累,不想动。\n最后,这一天还拿到了和Charm young的合照,还挺动容的,之前看Robomaster的一个宣传标语就是让工程师们成为明星,给他们一个展示的舞台,看到大家对Charm young的热情,深深的感受到了这一点。\n","permalink":"https://blog.zzsqwq.cn/posts/173/","summary":"前言 ​说起来的话今天距离比赛已经过去近一个月了,比赛结束一直想要记录一下and总结一下经验,但是实在是太懒了,临近五一假期,在四月的末尾为这次中国赛画一个句号吧。\n比赛过程 ​如果没记错的话比赛是3.30号(周二)去,4.1号(周四)结束,共三天。但是因为第三天没做什么有意义的事情,就只记录两天了。\n第一天 ​第一天大概中午十点到的吧,去的时候登记完领了牌,就在当地布置场地了。到了场地上才发现,我们好像是拿的东西最多的,包括外接显示屏和集成主机,好像都基本没人带过去····集成主机拿了过去也没怎么用到,本来预想用到的哨岗相机因为 ROS 的通信问题也没能跑成,最后两个机器人还是各跑各的策略了。\n​调试的时候出了一点问题,两个哨岗相机通过20m的USB延长线后,只有一个能连接,后来排查了一下,好像是因为有一条线是光纤USB3.0的线,跟相机的接口不兼容···这个问题还没想好怎么解决,可能会考虑到时候自己带一根USB延长线过去。\n​犹记得调试的时候是和青海大学一起调的,有点可惜的是调试中的我方机器人一直在一个地方鬼畜。那晚上我记得大家熬到了很晚···很可惜的视觉因为用的是学习的框架可调性很差,并没有帮上太大的忙。\n第二天 ​第二天记得一共有三场比赛,分别是打哈工大,哈工大深圳,以及青海大学。\n​在比赛过程中其实对视觉,我没有做太多的调整,主要还是大家在写导航和策略相关的东西吧。\n​跟哈工大打的那一场二车因为没有写好启动判定被罚下了,一车因为点位有问题一直卡在障碍物上。\n​跟哈工深和哈工大两场之间还隔了挺长时间,一个上午是一个下午,中间大家调试了很久,幸好在下午和哈工深打的时候基本没有鬼畜,可以正常的对局,只是因为实力不够强,很明显的一个问题就是视觉做的有问题吧,很多时间在朝着自己的队友打,还有就是会朝着场外的人员打,这是需要改进的点。\n​跟青海大学打的那场,距和哈工深比赛结束只有十几分钟的间隔时间,大家调了一个小bug就又重新赶去检录了,虽然当时已知青海大学的战术是站在原地不动的,但是由于不知道哪里出问题了,比赛中前一分钟两车都没动,后一分钟二车虽然动起来了去吃了加成区,但是因为定位的一些问题,没有看到敌方机器人并且撞墙了··自己撞掉了60血,最后还是败了QAQ。\n​所以就很耻辱的被3:0送走了,这样就结束了比赛日程。\n​值得反思的事情很多吧,赛前虽然基本熬了一个多星期来调车,还是只在最后一天才开始连裁判系统联调,包括暑假效率不高等问题都是值得反思的···打完比赛心中大概已经有了一些改进点,也想把自己的一些调车心得等记录下来,但是因为时间以及学业上的一些事情等一直没去做,本来计划的五月初做好改进的视觉也一直没兑现,希望这个五一假期会有较大的突破吧,不过还要打数模···好累,不想动。\n最后,这一天还拿到了和Charm young的合照,还挺动容的,之前看Robomaster的一个宣传标语就是让工程师们成为明星,给他们一个展示的舞台,看到大家对Charm young的热情,深深的感受到了这一点。","title":"2021RoboMaster中国赛比赛记录"},{"content":"前言 最近使用Anaconda的时候遇到了一个很奇怪的问题,如当我新建环境 condatest 后,使用 pip -V 查看pip的路径指向,会发现pip指向的是另一个环境 CenterNet 的路径。搜索了很久得到一个有一些用的解决方法\n解决方案 设有问题的环境为 condatest ,python版本为 3.6\n然后进入 ~/anaconda3/envs/condatest/lib/python3.6\n编辑目录下的 site.py 文件,将其中的 USER_SITE 的值修改为 /home/zs/anaconda3/envs/condatest ,注意这里路径里面的 zs 是你的当前用户名, USER_BASE 的值修改为 /home/zs/anaconda3/envs/condatest/lib/python3.6/site.py,然后问题应该就解决了。\n因为如果环境问题的话,上面两个字符串都为空,猜测的原因是因为有同python版本的环境导致默认指向错误,此方式为修改conda中pip的指向。\n参考链接 更改conda环境中的pip包安装的默认路径 ","permalink":"https://blog.zzsqwq.cn/posts/169/","summary":"前言 最近使用Anaconda的时候遇到了一个很奇怪的问题,如当我新建环境 condatest 后,使用 pip -V 查看pip的路径指向,会发现pip指向的是另一个环境 CenterNet 的路径。搜索了很久得到一个有一些用的解决方法\n解决方案 设有问题的环境为 condatest ,python版本为 3.6\n然后进入 ~/anaconda3/envs/condatest/lib/python3.6\n编辑目录下的 site.py 文件,将其中的 USER_SITE 的值修改为 /home/zs/anaconda3/envs/condatest ,注意这里路径里面的 zs 是你的当前用户名, USER_BASE 的值修改为 /home/zs/anaconda3/envs/condatest/lib/python3.6/site.py,然后问题应该就解决了。\n因为如果环境问题的话,上面两个字符串都为空,猜测的原因是因为有同python版本的环境导致默认指向错误,此方式为修改conda中pip的指向。\n参考链接 更改conda环境中的pip包安装的默认路径 ","title":"关于Anaconda中pip路径指向问题"},{"content":"CenterNet—Objects as Points介绍 ​CenterNet是一个anchor-free的目标检测网络,与YOLOv3相比,精度有所提升,此外他不仅能够用于2D目标检测,也能够用于人体姿态识别,3D目标检测等···\n安装CenterNet ​其实安装CenterNet的过程就是一个配置环境的问题,直接跟着官方给出的这里Install.md配置一下即可,十分推荐使用Conda来管理环境,这里给出我的环境给大家参考一下:\nUbuntu = 18.04 LTS\npytorch = 1.2.0\npython = 3.6.12\ntorchvision = 0.4.0\ncuda = 10.2\n​需要注意的是:\n官方给出的教程里面使用的是 pytorch 0.4.1,但是我个人在实测过程中遇到了一些问题,遂安装网上的教程更改为 pytorch 1.2.0,并且需要把 ${CenterNet_Root}/src/lib/models/networks/DCNv2 中的这个DCNv2网络更改为官方的最新版。 这里使用的cuda版本最好和你的显卡匹配,之前因为显卡驱动的一些问题导致重装了电脑,根据我们学长学姐的建议,最好直接去cuda官网那边去下载deb包直接安装。 遇到环境配置问题可以先去Google一下,一般作者都在CenterNet\u0026rsquo;s Issues中给出了回复,如果没有,可以发邮件给作者询问,当然也可以发消息/邮箱给我,大家一起探讨一下~ 运行CenterNet的demo ​想要运行demo,首先要去 Model zoo 中下载一下我们需要使用的model,2D目标检测使用的是 ctdet_coco_dla_2x.pth ,人体姿态评估使用的是 multi_pose_dla_3x.pth ,下载后统一将他们放在CenterNet根目录中的model文件夹中。\n​然后使用conda切换到CenterNet的环境,在终端中运行:\npython demo.py ctdet --demo ${CenterNet_Root}/images/17790319373_bd19b24cfc_k.jpg --load_model ../models/ctdet_coco_dla_2x.pth ​这里需要注意的是 --demo 后面的 ${CenterNet_Root}/images/17790319373_bd19b24cfc_k.jpg ,这里我使用的是官方给出的实例图片,它位于CenterNet根目录的images文件夹中,前面的 ${CenterNet_Root} 代表的是 CenterNet根目录,好比我的就位于 /home/zs/CenterNet 。\n​如果不出意外的话效果应该如下图所示:\n运行CenterNet的3D目标检测 配置数据集和模型 ​我们可以直接参考官方的 DATA.md 来配置我们的数据集。\n​然后到 Model zoo 下载3D检测使用的模型 ddd_3dop.pth 。\n​这里说一下遇到的几个坑:\n首先是配置数据集的过程中,我们需要配置的目录结构如图所示(官方给出的结构树有点模糊不清的感觉)\n. ├── ImageSets_3dop │ ├── test.txt │ ├── train.txt │ ├── trainval.txt │ └── val.txt ├── ImageSets_subcnn │ ├── test.txt │ ├── train.txt │ ├── trainval.txt │ └── val.txt └── training ├── calib ├── image_2 └── label_2 然后去到 ${CenterNet_ROOT}/src/tools目录下,运行 python convert_kitti_to_coco.py 将 kitti 数据集转换为 coco 数据集的格式,不出意外应该会报错如下:\n这里的解决方案参考CenterNet中的一个Issue , How to generate the image dir in kitti? ,我们需要回到 data/kitti 目录下手动创建一个 annotations 文件夹,然后再回去运行转换程序。转换后目录结构如下:\n. ├── annotations │ ├── kitti_3dop_train.json │ ├── kitti_3dop_val.json │ ├── kitti_subcnn_train.json │ └── kitti_subcnn_val.json ├── ImageSets_3dop │ ├── test.txt │ ├── train.txt │ ├── trainval.txt │ └── val.txt ├── ImageSets_subcnn │ ├── test.txt │ ├── train.txt │ ├── trainval.txt │ └── val.txt └── training ├── calib ├── image_2 └── label_2 然后根据官方的教程,我们需要创建一个images文件夹,然后将其 training/image_2 链接到 images/trainval,我在实际的测试中,发现此方法并不可行。参考CenterNet中的一个Issue: Evaluate kitti\u0026ndash;AttributeError: \u0026lsquo;NoneType\u0026rsquo; object has no attribute \u0026lsquo;shape\u0026rsquo; ,其中 juanmed给出了解决方案:\nI had the same problem. For some reason the simlinks that are created during the data preparation process described in DATA.md are not working. So instead of creating simlinks I simply copied the actual data into the directories indicated in DATA.md. In other words the folders data/kitti/images/test and data/kitti/images/trainval do contain the actual images.\n意思就是说,我们在 images 中的图片必须都是真实的照片,而不能只是软链接过去。\n解决方案很显然,只需要在 images 文件夹中建立一个 trainval 文件夹,将 training/image_2 中的所有图像都移入其中即可。如果有test的照片,那么也照规在 images 新建一个 test 文件夹,把测试的照片移入其中即可。\n运行测试程序 接下来我们就可以根据官方给出的 GETTING_STARTED.md 来进行我们的检测了。\n即先编译一下评估工具,然后运行测试程序,但其实还是有一点点小问题。\n具体问题可以参考 Issus: kitti test: Couldn\u0026rsquo;t read: 006042.txt of ground truth.\nIssue下 lhyfst 已经给出了解决方案 :\nThe solution is quite simple. cd data/kitti mv label_2 label_val\n​ 更改后,运行成功~\n我们应该可以在 ${CenterNet_ROOT}/exp/ddd/3dop/results 看到我们得到的结果,只不过运行得到的是点的坐标,而不是图像,如果需要图像的话可能还需要自己绘制一下。\n","permalink":"https://blog.zzsqwq.cn/posts/164/","summary":"CenterNet—Objects as Points介绍 ​CenterNet是一个anchor-free的目标检测网络,与YOLOv3相比,精度有所提升,此外他不仅能够用于2D目标检测,也能够用于人体姿态识别,3D目标检测等···\n安装CenterNet ​其实安装CenterNet的过程就是一个配置环境的问题,直接跟着官方给出的这里Install.md配置一下即可,十分推荐使用Conda来管理环境,这里给出我的环境给大家参考一下:\nUbuntu = 18.04 LTS\npytorch = 1.2.0\npython = 3.6.12\ntorchvision = 0.4.0\ncuda = 10.2\n​需要注意的是:\n官方给出的教程里面使用的是 pytorch 0.4.1,但是我个人在实测过程中遇到了一些问题,遂安装网上的教程更改为 pytorch 1.2.0,并且需要把 ${CenterNet_Root}/src/lib/models/networks/DCNv2 中的这个DCNv2网络更改为官方的最新版。 这里使用的cuda版本最好和你的显卡匹配,之前因为显卡驱动的一些问题导致重装了电脑,根据我们学长学姐的建议,最好直接去cuda官网那边去下载deb包直接安装。 遇到环境配置问题可以先去Google一下,一般作者都在CenterNet\u0026rsquo;s Issues中给出了回复,如果没有,可以发邮件给作者询问,当然也可以发消息/邮箱给我,大家一起探讨一下~ 运行CenterNet的demo ​想要运行demo,首先要去 Model zoo 中下载一下我们需要使用的model,2D目标检测使用的是 ctdet_coco_dla_2x.pth ,人体姿态评估使用的是 multi_pose_dla_3x.pth ,下载后统一将他们放在CenterNet根目录中的model文件夹中。\n​然后使用conda切换到CenterNet的环境,在终端中运行:\npython demo.py ctdet --demo ${CenterNet_Root}/images/17790319373_bd19b24cfc_k.jpg --load_model ../models/ctdet_coco_dla_2x.pth ​这里需要注意的是 --demo 后面的 ${CenterNet_Root}/images/17790319373_bd19b24cfc_k.jpg ,这里我使用的是官方给出的实例图片,它位于CenterNet根目录的images文件夹中,前面的 ${CenterNet_Root} 代表的是 CenterNet根目录,好比我的就位于 /home/zs/CenterNet 。\n​如果不出意外的话效果应该如下图所示:\n运行CenterNet的3D目标检测 配置数据集和模型 ​我们可以直接参考官方的 DATA.md 来配置我们的数据集。\n​然后到 Model zoo 下载3D检测使用的模型 ddd_3dop.","title":"如何使用CenterNet做3D目标检测测试"},{"content":"前言 最近在复习Git,因此顺手做个笔记分享出来,方便大家学习和查阅。相信无论是以后的课程作业还是工作,我们都会或多或少的接触/用到Git。\n什么是Git? Git你可能没听说过,但是我相信你应该听说过Github,毕竟是全球最大的同性交友网站。他和Git有着密不可分的联系,我们后续再详细介绍。\nGit的中文全称叫 分布式版本控制系统 ,版本控制系统是什么意思呢?我们举一个简单的例子,你在做一个大作业,很可能要写上千行的代码,但是你可能写完一个功能以后,对他不够满意,但是又害怕改了以后后悔了,又找不回来了,所以你可能就有很多版本,版本1,版本2,版本3等等等。Git就是解决这个问题的,让你文件能够保持最新,但是又能恢复到之前的版本。\n那么既然有分布式版本控制系统,就有 集中式版本控制系统,前者的代表是 Git ,后者的代表有 SVN、CVS 等。\n关于两者的区别,对于集中式版本控制系统,如果你想要对做一个项目的内容做修改,那么你要先从中央服务器把最近的版本拉取(Pull)下来,然后修改完以后,把修改后的版本推送(Push)上去,你本地只有最新的版本,而没有完整的版本库,分布式版本控制系统所作的工作与集中式的相差不大,只是它的本地会有一个完整的版本库,因此它十分的安全。\n这里贴一个他人总结的区别,供大家参考。\nGit的安装 Linux系统\n因为我只用过Ubuntu,所以我只会Ubuntu的QAQ..\nUbuntu中安装Git只需要在终端中输入 sudo apt-get install git 即可。\n如果是其他的linux系统,我猜你在终端中输入git即可获得安装提示,不然的话借助搜索引擎也可以。\nWindows系统\n直接去 Git官网 下载安装程序然后安装即可。关于安装时候的选项,我都是用的默认的。\nMac OS\n太穷了,没用过Mac,但是参考链接中给出了方法,大家有需求可以参考。\nGit的基本使用 Git可以做许多事情,好比版本更新,版本修改,提交到远程仓库等等,这里我们只写一写大概以后用的会比较多的。\n需要注意的是,我们安装以后大概会有一个 Git GUI 还有一个 Git Bash ,开发中多用 Git Bash,下面的教程也是基于Git Bash的。\n表明身份\n在Git所有仓库中我们都要有一个所有者的身份,用于标识是谁的仓库,用如下方式标识\ngit config --global user.name \u0026#34;Your Name\u0026#34; git config --global user.email \u0026#34;Your email\u0026#34; 创建版本库\n我们想要把一个文件夹的内容用git来管理,只需要在文件夹目录运行\ngit init 顾名思义这就是一个初始化的过程,运行以后在当前目录生成一个 .git 文件夹,里面是我们版本控制的数据,一般不要修改。\n把文件添加到Git的暂存区\n这里出现了 暂存区 这个名词,Git内部的逻辑大概把我们工作的过程分为了三部分\n一个是 工作区 ,这个就是我们本地的文件夹。 一个是 暂存区 ,这是我们把文件暂时放到暂存区里,没有决定更新我们的版本。 一个是 最终分支,这就是我们最终的版本存放的位置。 贴一张廖雪峰老师教程中的一张图,我觉得还挺形象的。\n我们清楚了上面的三个分区,那么考虑一下如何把文件夹中的文件从工作区推到暂存区,通过如下命令\ngit add filepath 我们就可以把文件推到暂存区,最后的filepath就是我们需要推送的文件的路径,一般都用相对路径。\n上面是添加单个文件的方法,我们也可以把目录中所有做过更改的文件都加到暂存区中,就用\ngit add . 从暂存区推送到最后分支\n我们可以把暂存区推送到最终分支,以完成我们的版本更新,通过\ngit commit -m \u0026#34;description\u0026#34; 其中description的内容是我们对该次版本更新的一次描述,好比增加什么功能。\n版本回退\n那么既然我们每次有更新版本,我们如何从最新的版本回退到之前的某个版本呢?\n这里我们需要了解到,我们有一个指针 HEAD 来指向我们当前的版本,因此我们只需要指定HEAD指针指向的版本,就可以做到更改版本。\ngit reset --hard 版本号 git reset --hard HEAD^ git reset --hard HEAD~cnt 这里三个命令都可以回退版本,每一个版本有一个版本号,可以指定版本号直接回到对应的版本。此外,通过 git reflog 可以查看每个版本的版本号。\n第二个和第三个有点像,都是往前回退几个版本,有几个^就是回退几个,后面cnt是几就回退几个。\n分支结构\nGit支持分支结构,可以使我们的版本管理变得十分有序,以不至于逻辑混乱。\nGit有一个初始主分支master,我们可以\n创建分支\ngit branch 分支名称 切换分支(两个命令都可以)\ngit switch 分支名称 git checkout 分支名称 创建并切换分支\ngit checkout -b 分支名称 好了,学了这些,其实就已经够让我们在日常生活中管理文件了,下面说一些用于团队合作的。\nGithub的作用 众所周知,一个大项目,想要一个人完成是很难的,大多数优秀的项目都是集思广益,大家一起出力建造出来的。\n我们上面提到的Github就是这样的一个平台,他是一个代码托管仓库,我们可以把新建一个仓库,然后把代码存储到上面,用的时候从上面Pull下来,而且只要经过你的同意,大家都可以为你的仓库贡献代码。由于这种开源的性质,Github有着许许多多优秀的项目,大家闲的没事可以去知乎搜搜Github上好玩的项目去玩一玩,好比 狗屁不通文章生成器 。\nGit与Github的协同 Git和Github密不可分,我们可以使用Git往Github上推送代码,从上面拉取代码等。\n从Github克隆代码\n我们如果想要从一个公有仓库中,把它的代码克隆到自己的本地,然后对他做一些应用。我们可以使用\ngit clone 仓库地址 这样就可以克隆仓库到本地,这里的仓库地址支持 https 或者 ssh 协议。\n推送本地仓库到Github\n首先我们要在Github上有一个自己的仓库,才能将自己的代码推送上去,因此需要在Github上创建自己的公有/私有仓库。\n然后我们在本地仓库做完修改,commit 以后,输入如下命令\ngit remote add origin 仓库地址 git push -u origin master 这两步一个是与远程仓库建立关联,一个是将代码push上去。\n通过这两步就可以把我们当地仓库推送到Github。\nGithub的Pull Request 项目需要团队合作,Pull Request就是为了团队协作而生的。\n你可以把他人的代码clone下来做完修改以后,向仓库所有者提交Pull Request,请求将自己的代码与他的代码合并,如果所有者同意,即可把你的代码合并到他的仓库中,以完成版本的更新,而你,就对这个项目做了一份贡献。\n那么如何提交Pull Request呢?\n对于对仓库有所有权的人来说,只需要把代码clone下来,然后创建并切换到自己的分支,对当前分支进行修改后,push到仓库中,然后创建合并请求即可。\n对于非仓库所有者而言,你需要先把代码 fork 下来,然后clone你 fork 的仓库,关联对方的远程仓库,修改后推上去,然后创建合并请求。\n大家对开源项目的贡献多是用第二种,自己团队内的协作多是第一种。\n一个总结 这篇文章讲的内容不多,QAQ只讲了部分我们可能用的比较多的。\n关于Git的基本使用,还有很多内容,好比 git merge ,git diff 啥的,我们用的可能比较少,我就没提。大家如果有需求可以翻下面的参考链接进行学习。\n之后的内容多是团队协作会用到的,大家可以有需要的时候再看。学会使用Git可以有效地帮助我们管理文件,进行团队协作,提高工作效率。\n关于后续的学习,大家可以选择 廖雪峰老师的Git教程 ,实例丰富、简单易懂,此外还有 Pro Git ,内容丰富,涵盖了基本所有的命令,以及Github上的一个开源项目 learnGitBranching ,有着可视化的界面与闯关机制,趣味十足。\n参考文档 廖雪峰的Git教程\nPro Git\n集中式(SVN)和分布式(Git)版本控制系统的简单比较\ngit学习-Github上如何进行PR(Pull Request)\npcottle/learnGitBranching: An interactive git visualization to challenge and educate! (github.com)\n","permalink":"https://blog.zzsqwq.cn/posts/157/","summary":"前言 最近在复习Git,因此顺手做个笔记分享出来,方便大家学习和查阅。相信无论是以后的课程作业还是工作,我们都会或多或少的接触/用到Git。\n什么是Git? Git你可能没听说过,但是我相信你应该听说过Github,毕竟是全球最大的同性交友网站。他和Git有着密不可分的联系,我们后续再详细介绍。\nGit的中文全称叫 分布式版本控制系统 ,版本控制系统是什么意思呢?我们举一个简单的例子,你在做一个大作业,很可能要写上千行的代码,但是你可能写完一个功能以后,对他不够满意,但是又害怕改了以后后悔了,又找不回来了,所以你可能就有很多版本,版本1,版本2,版本3等等等。Git就是解决这个问题的,让你文件能够保持最新,但是又能恢复到之前的版本。\n那么既然有分布式版本控制系统,就有 集中式版本控制系统,前者的代表是 Git ,后者的代表有 SVN、CVS 等。\n关于两者的区别,对于集中式版本控制系统,如果你想要对做一个项目的内容做修改,那么你要先从中央服务器把最近的版本拉取(Pull)下来,然后修改完以后,把修改后的版本推送(Push)上去,你本地只有最新的版本,而没有完整的版本库,分布式版本控制系统所作的工作与集中式的相差不大,只是它的本地会有一个完整的版本库,因此它十分的安全。\n这里贴一个他人总结的区别,供大家参考。\nGit的安装 Linux系统\n因为我只用过Ubuntu,所以我只会Ubuntu的QAQ..\nUbuntu中安装Git只需要在终端中输入 sudo apt-get install git 即可。\n如果是其他的linux系统,我猜你在终端中输入git即可获得安装提示,不然的话借助搜索引擎也可以。\nWindows系统\n直接去 Git官网 下载安装程序然后安装即可。关于安装时候的选项,我都是用的默认的。\nMac OS\n太穷了,没用过Mac,但是参考链接中给出了方法,大家有需求可以参考。\nGit的基本使用 Git可以做许多事情,好比版本更新,版本修改,提交到远程仓库等等,这里我们只写一写大概以后用的会比较多的。\n需要注意的是,我们安装以后大概会有一个 Git GUI 还有一个 Git Bash ,开发中多用 Git Bash,下面的教程也是基于Git Bash的。\n表明身份\n在Git所有仓库中我们都要有一个所有者的身份,用于标识是谁的仓库,用如下方式标识\ngit config --global user.name \u0026#34;Your Name\u0026#34; git config --global user.email \u0026#34;Your email\u0026#34; 创建版本库\n我们想要把一个文件夹的内容用git来管理,只需要在文件夹目录运行\ngit init 顾名思义这就是一个初始化的过程,运行以后在当前目录生成一个 .git 文件夹,里面是我们版本控制的数据,一般不要修改。\n把文件添加到Git的暂存区\n这里出现了 暂存区 这个名词,Git内部的逻辑大概把我们工作的过程分为了三部分\n一个是 工作区 ,这个就是我们本地的文件夹。 一个是 暂存区 ,这是我们把文件暂时放到暂存区里,没有决定更新我们的版本。 一个是 最终分支,这就是我们最终的版本存放的位置。 贴一张廖雪峰老师教程中的一张图,我觉得还挺形象的。","title":"Git的简易教程"},{"content":"前言 因为最近Ubuntu用的比较频繁,所以前一阵把Ubuntu16.04换成Ubuntu18.04了,并且囿于机械硬盘那启动速度,我忍痛割爱把我80G的固态硬盘分给了Ubuntu。\n后来,用着用着就觉得这个Ubuntu的原始界面确实不是特别的好看,配色偏基佬紫的感觉。“工欲善其事,必先利其器“,我们只有将自己的工作环境布置的舒心一些才能有做下去的动力!所以我想给Ubuntu换一个看起来舒服点的界面,然后上网找教程乱七八糟的倒腾了一会,感觉换完以后完全不一样了,这个界面真的好看!!用起来也特别的舒心,感觉自己马上就要告别Windows投奔Linux的怀抱了。后续还有一些其他的优化,例如装QQ、微信、配置终端等,一并写在这里吧。\nUbuntu界面的优化 具体效果 先放几张效果图上来,是我改后的界面。大概就是这样(自我感觉挺好看的),当然也有其他的主题可供选择。\n1.安装GNOME桌面环境主题配置工具 如果要改主题,那么首先要有一个利器,这里我用的Ubuntu18.04,桌面环境为 GNOME 3.28.2 ,因为我目前接触的只有GNOME桌面环境的,Ubuntu18.04本来的桌面环境就是GNOME,但是Ubuntu16.04好像没有自带,但是可以安装,这里大家可以自行百度了解。\n然后我们已经有了GNOME桌面环境后,安装主题配置工具 GNOME Tweaks ,在终端中输入如下内容:\nsudo apt-get update sudo apt-get install gnome-tweak-tool 我们先更新软件源,然后安装后直接打开他就行,在系统软件中中文大概叫 优化 。\n2.拓展上述工具 安装完上述工具后,我们可能发现了一个问题,就是外观那一栏目的Shell有一个感叹号,无法更改,这是因为我们没有安装拓展导致的。我们在终端中运行\nsudo apt-get install gnome-shell-extensions 然后重启一下电脑。再打开软件找到左侧的拓展,把 User themes 那一栏目打开。切换回去就可以发现Shell那边的感叹号无了。\n3.寻找自己喜欢的主题 这里我大家可以去这个网址去找自己喜欢的 GNOME-LOOK.ORG\n这里面包含了图标,主题这些,下面介绍一下如何安装。\n好比我们找到一个自己喜欢的主题,然后我们点击下面的 Files ,可能会有很多文件,但是多是同一个主题的不同风格,好比暗风格和亮风格这样的,还有不同的版本的,我多是安装那个下载量最多的,我们下载那个对应的文件(多是tar.xz安装包)。\n对于主题的安装,我们只需要把解压出来的文件,移动或复制到 /usr/share/themes/ 目录下,如果是光标\\图标的安装,那么就把文件夹移动到 /usr/share/icons 目录下。\n然后我们回到 GNOME Tweaks 软件中就可以发现,我们已经可以在主题\\图标\\光标\\Shell清单中找到我们移动到文件夹中的文件了,然后选择就可以切换了。这里需要注意的,很多主题都是自带Shell的,你下了一个主题,那么你可以在Shell和主题这两个栏目中都找到他们,是一个配套的。\n4.一些后续的调整 我们后续可以改变左边收藏夹的位置,我觉得放在左边有一丢丢的丑,所以我选择把它放在的下面。\n我们去Ubuntu软件中搜索 Dash to dock,然后安装这个拓展,然后打开 GNOME Tweaks 软件在拓展中找到他就可以随心所欲的调我们的收藏夹的位置了。\n5.我自己的配置 theme\u0026amp;shell Canta-light-compact icons 01-McMojave-circle 6.界面修改的参考链接 Ubuntu18.04美化主题(mac主题) Ubuntu18.04美化主题(完整版) GNOME-LOOK.ORG 30个非常不错的Ubuntu主题供你选择 ubuntu18.04更换鼠标游标主题 配置终端 前言 唔,终端本来用起来感觉也还行,感觉终端就是linux的灵魂,啥都能干。\n但是听说有更好用的终端,现在ubuntu普遍用的好像都是bash,但是好像还有zsh,fish这样的,他们可以有一些代码补全,功能更强,可拓展性也高,大家都zsh和fish哪个好用一直争执不停,但是我发现ROS对 zsh 支持的很好,但是对 fish 的支持有点拉胯,考虑到以后可能ros会用的比较多,因此我选择使用zsh。效果图如下\n1.下载zsh 直接在终端执行下列语句\nsudo apt-get update sudo apt-get install zsh 2.安装oh my zsh zsh其实配置起来很麻烦,这一点相比与fish不太行,fish下载下来就已经具备了常用的功能,例如代码补全等。\n但是我们有先人铺路,在Github上有一个开源的项目 oh my zsh,就是专门用来导入这个zsh的配置的,\n我们直接运行如下代码,就可以直接安装了\nwget sh -c \u0026#34;$(wget -O- https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)\u0026#34; 然后我们可以通过在终端中输入zsh来切换到zsh,也可以通过输入bash切换回去\n我们也可以通过如下命令来切换默认的终端系统,首先查找一下zsh的目录,然后切换过去。\nwhereis zsh chsh -s zsh路径 3.配置插件 在zsh里面有许多好用的插件,在这里推荐两个\n自动补全 zsh-autosuggestions 语法高亮 zsh-syntax-highlighting 关于下载的方法,在这两个项目里面都说了,我们只需要把下载的文件放到 ~/.oh-my-zsh/plugins 目录中,然后编辑 ~/.zshrc 在 plugin = (插件1 插件2) 写上你所要启用的插件名称即可。\n然后在终端中 source ~/.zshrc 更新一下配置即可。\n4.配置主题 zsh有许多可用的主题选择,我自己最喜欢的一个叫 pure\n我觉得害挺好看的,效果就跟上图一样吧。\n安装方法就是先把pure下载到一个路径,然后编辑 ~/.zshrc\n在下面加入\nfpath+=安装路径 autoload -U promptinit; promptinit prompt pure 然后我们source一下.zshrc 就可以使用了。\n但是如果是使用zsh本来自带的一些主题,和这个有些差别,只需要下载好主题然后放到 ~/.oh-my-zsh/themes ,然后在 .zshrc 中启用即可。\n5.参考链接 linux终端shell:zsh配置和使用\nzsh和oh-my-zsh的一些好用的主题和插件\nlinux安装oh my zsh终端及简单使用方法\n配置oh-my-zsh主题\nZsh 常用插件\n给Zsh添加主题和插件\n常用的oh-my-zsh插件\n还有一些其他的配置有时间再写吧……咕咕咕\n","permalink":"https://blog.zzsqwq.cn/posts/141/","summary":"前言 因为最近Ubuntu用的比较频繁,所以前一阵把Ubuntu16.04换成Ubuntu18.04了,并且囿于机械硬盘那启动速度,我忍痛割爱把我80G的固态硬盘分给了Ubuntu。\n后来,用着用着就觉得这个Ubuntu的原始界面确实不是特别的好看,配色偏基佬紫的感觉。“工欲善其事,必先利其器“,我们只有将自己的工作环境布置的舒心一些才能有做下去的动力!所以我想给Ubuntu换一个看起来舒服点的界面,然后上网找教程乱七八糟的倒腾了一会,感觉换完以后完全不一样了,这个界面真的好看!!用起来也特别的舒心,感觉自己马上就要告别Windows投奔Linux的怀抱了。后续还有一些其他的优化,例如装QQ、微信、配置终端等,一并写在这里吧。\nUbuntu界面的优化 具体效果 先放几张效果图上来,是我改后的界面。大概就是这样(自我感觉挺好看的),当然也有其他的主题可供选择。\n1.安装GNOME桌面环境主题配置工具 如果要改主题,那么首先要有一个利器,这里我用的Ubuntu18.04,桌面环境为 GNOME 3.28.2 ,因为我目前接触的只有GNOME桌面环境的,Ubuntu18.04本来的桌面环境就是GNOME,但是Ubuntu16.04好像没有自带,但是可以安装,这里大家可以自行百度了解。\n然后我们已经有了GNOME桌面环境后,安装主题配置工具 GNOME Tweaks ,在终端中输入如下内容:\nsudo apt-get update sudo apt-get install gnome-tweak-tool 我们先更新软件源,然后安装后直接打开他就行,在系统软件中中文大概叫 优化 。\n2.拓展上述工具 安装完上述工具后,我们可能发现了一个问题,就是外观那一栏目的Shell有一个感叹号,无法更改,这是因为我们没有安装拓展导致的。我们在终端中运行\nsudo apt-get install gnome-shell-extensions 然后重启一下电脑。再打开软件找到左侧的拓展,把 User themes 那一栏目打开。切换回去就可以发现Shell那边的感叹号无了。\n3.寻找自己喜欢的主题 这里我大家可以去这个网址去找自己喜欢的 GNOME-LOOK.ORG\n这里面包含了图标,主题这些,下面介绍一下如何安装。\n好比我们找到一个自己喜欢的主题,然后我们点击下面的 Files ,可能会有很多文件,但是多是同一个主题的不同风格,好比暗风格和亮风格这样的,还有不同的版本的,我多是安装那个下载量最多的,我们下载那个对应的文件(多是tar.xz安装包)。\n对于主题的安装,我们只需要把解压出来的文件,移动或复制到 /usr/share/themes/ 目录下,如果是光标\\图标的安装,那么就把文件夹移动到 /usr/share/icons 目录下。\n然后我们回到 GNOME Tweaks 软件中就可以发现,我们已经可以在主题\\图标\\光标\\Shell清单中找到我们移动到文件夹中的文件了,然后选择就可以切换了。这里需要注意的,很多主题都是自带Shell的,你下了一个主题,那么你可以在Shell和主题这两个栏目中都找到他们,是一个配套的。\n4.一些后续的调整 我们后续可以改变左边收藏夹的位置,我觉得放在左边有一丢丢的丑,所以我选择把它放在的下面。\n我们去Ubuntu软件中搜索 Dash to dock,然后安装这个拓展,然后打开 GNOME Tweaks 软件在拓展中找到他就可以随心所欲的调我们的收藏夹的位置了。\n5.我自己的配置 theme\u0026amp;shell Canta-light-compact icons 01-McMojave-circle 6.界面修改的参考链接 Ubuntu18.04美化主题(mac主题) Ubuntu18.04美化主题(完整版) GNOME-LOOK.ORG 30个非常不错的Ubuntu主题供你选择 ubuntu18.","title":"Ubuntu18.04优化教程"},{"content":"“程序星编程之路”第二次作业题解 A. Zs的回文质数 题目描述 读入一个整数 $n$ ,输出 $[1,n]$ 的所有回文质数,我们规定 $1\\sim9$ 也是回文数。\n思路 首先我们需要了解什么是回文数,以及什么是质数。\n简单点说,回文数就是正着读反着读都是一样的,也就是对称的,形如 $abcba $ 或者 $123321$ 这样的。\n质数的话,对于一个数 $n$ ,如果他是质数,那它除了 $1$ 和 $n$ 没有其他因子。例如 $2,3,5,7,11$ 这样的。\n那么接下来我们考虑一下解决这个问题应该怎么做,首先我们看一下数据范围,$[1,100000]$ ,还是挺小的,我们可以考虑直接枚举每一个数来判断它是不是回文数,然后再判断一下是不是质数,如果两个都满足,我们就输出它。\n判断回文数,我们可以考虑到 NOJ05 幸运数 一题的解题思路,也就是说我们把一个数倒置过来,好比一个数 $xyz$ 倒置成 $zyx$ ,然后判断是否 $xyz == zyx$ ,如果相等的话就是回文数,如果不相等就不是。\n判断质数,我们可以在 $[2,\\lfloor\\sqrt{n}\\rfloor]$ 枚举它的因子,这个的完备性我上课的时候证明过,不再赘述。这里需要注意 $1,2$ 需要特判一下。\n代码 #include\u0026lt;stdio.h\u0026gt; #include\u0026lt;math.h\u0026gt; //我们需要用到sqrt函数,因此需要引入数学库 int main() { int n; bool flag = false; // 标记 i 是否满足条件 scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { flag = true; int p=i,j=0; while(p) // 将 p 反转为 j { j=j*10+p%10; p/=10; } if(j==i) { if(j==1) continue; // 特判 1 if(j==2) // 特判 2 { printf(\u0026#34;2\\n\u0026#34;); continue; } int sqrtj = sqrt(j); for(int k=2;k\u0026lt;=sqrtj;k++) // 枚举 [2,sqrt(n)] { if(j%k==0) // 如果能够整除(余数为0),那么是 j 的因子 { flag = false; break; } } if(flag) { printf(\u0026#34;%d\\n\u0026#34;,j); } } } } 其他 因为我们讲到这里的时候,我们没讲函数,但是这道题如果我们把判断是否为回文数,判断是否为质数,都另成一个函数模块,将使得程序变得更加简洁。我在这里也将函数版本的贴出来,有兴趣的可以看一下。\n#include\u0026lt;stdio.h\u0026gt; #include\u0026lt;math.h\u0026gt; bool isprime(int k) //判断是否为质数,如果是质数返回true,如果不是返回false { if(k==1) return false; if(k==2) return true; for(int i=2;i\u0026lt;=sqrt(k);i++) { if(k%i==0) return false; } return true; } bool ishw(int k) //判断是否为回文数,如果是返回true,如果不是返回false { int ans=0; int temp = k; //temp作为一个k的复制版,因为后续需要用到k,新定义一个作为备份 while(k) { ans = ans*10 + k%10; k/=10; } if(temp == ans) { return true; } else return false; } int main() { int n; scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { if(isprime(i) \u0026amp;\u0026amp; ishw(i)) //如果既是质数也是回文数 { printf(\u0026#34;%d\\n\u0026#34;,i); } } } B. Wcx的杨辉三角 题目描述 读入一个整数 $n$ ,输出杨辉三角的前 $n$ 行。\n思路 首先这道题我们需要了解一下杨辉三角 ,大家小学到高中应该都了解过。\n那么如何计算杨辉三角,首先我们可以知道的是杨辉三角的第 $i$ 行就是$C_i^0\\sim C_i^i$ ,但是我们考虑一下如何计算组合数,是用阶乘对吧,但是阶乘就涉及到一个连乘,对于这个题,我数据范围写的是 $1\\le n \\le 40$ ,很明显,阶乘不可行。而且写起来挺麻烦的。\n那么我们考虑一个组合数的性质 $$ C_n^i = C_{n-1}^i + C_{n-1}^{i-1} $$\n看起来很高大上对吧,简单点说就是杨辉三角里面一个数的值等于两肩之和,那么基于这个性质,我们很容易想到,我们可以用一个二维数组,定义 $f[i][j]$ 为第 $i$ 行的第 $j$ 个数,那么可以得到\n当 $j==1$ 或 $j==i$ ,则 $f[i][j] = 1$ ,也就是,当它为这一行的第一个或者最后一个,那么它就是 $1$\n如果不是上述条件,则 $f[i][j] = f[i-1][j] + f[i-1][j-1]$ ,也就是等于两肩之和。\n还有一个需要注意的问题就是,这个题的 $n$ 最大值是 40,这个时候已经超出了 $int$ 的范围,因此我们需要将二维数组定义为 $long: :long$ 。\n代码 #include\u0026lt;stdio.h\u0026gt; int main() { long long a[105][105] = {0}; //全都初始化为 0 int n = 0; scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) //这里我用的是 1~n 而不是 0~n-1 { for(int j=1;j\u0026lt;=i;j++) { if(j==1 || j==i) { printf(\u0026#34;%lld \u0026#34;,a[i][j]=1); } else { printf(\u0026#34;%lld \u0026#34;,a[i][j]=a[i-1][j-1]+a[i-1][j]); } } printf(\u0026#34;\\n\u0026#34;); } } 其他 这道题主要是对二维数组的考察。\n注意我们遇到第五个点过不去的时候,应该试一下最大的值 $40$ ,会发现有负数,显然是溢出问题,我们就能知道问题的解决办法了。\nC. Zh的约瑟夫环问题 题目描述 有 $n$ 个人围成一圈,顺序排号,从第一个开始报数(从 $1$ 到 $m$ 报数),凡报到 $m$ 的人退出圈子,问最后留下的是几号.\n思路 约瑟夫问题是个很经典的问题,可能又叫什么猴子选大王什么的,特多变体。\n这个题其实就是一个纯模拟题,主要是对数组的考察。我们可以考虑开一个布尔数组 vis 用来标记某个人是否出圈,如果出圈了我们给他设置为 true ,如果没有出圈就是 false 。\n然后开一个报数到多少的变量cnt,开一个当前谁报数的变量pot,然后来模拟这个过程。如果 cnt 增长到了 m ,我们将 pot 出圈,也就是 vis[pot] = true ,然后在场的人数减一,当只剩下一人的时候,我们遍历 vis 数组中的每个元素,如果它的 vis 值为 false ,即没有出队,则将他输出。\n还有一个要注意的问题就是这是一个环,那么我们只需要判断一下当 pot 为 $n+1$ 的时候将他置为 $1$ 即可,这就模拟了一个环的性质。\n代码 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; int n,m; int vis[1005]; //vis[i] = true 已经淘汰 vis[i] = false 未被淘汰 int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;m); int cnt = 1; //报数到多少 int pot = 1; //当前是谁报数 int exist = n; //在场的人数 while(exist \u0026gt; 1) { cnt=0; while(1) { if(!vis[pot]) //如果没有出圈 { cnt++; if(cnt==m) { vis[pot] = true; exist--; break; } } pot++; if(pot==n+1) pot=1; //模拟环 } } for(int i=1;i\u0026lt;=n;i++) { if(vis[i] == false) printf(\u0026#34;%d\u0026#34;,i); } return 0; } 其他 上面的想法是比较好理解的形式。\n我们考虑一下模拟环,也就是使得 pot 指针处在一定的范围内,如果超出了将他重新置到头部,那么我们可以联想到取模,在模拟环时使用取模来实现,大家可以下去自己尝试,这有点像魏辰旭第一节课讲的那个字符串的问题。\n因为这道题只关心谁活了下来,所以还有一个比较简单的解法,我看在作业中也有几位同学给出了这个较简单的解法,如果理解了上述思想,看这个代码应该不难理解,大家可以对照代码自行思考。\n#include\u0026lt;stdio.h\u0026gt; int n,m; int pot = 0; int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;m); for(int i=2;i\u0026lt;=n;i++) { pot = (pot+m)%i; } printf(\u0026#34;%d\u0026#34;,pot+1); } 提示:n个人的约瑟夫环杀掉一个人后组成一个新的人数为 n-1 的约瑟夫环\n","permalink":"https://blog.zzsqwq.cn/posts/136/","summary":"“程序星编程之路”第二次作业题解 A. Zs的回文质数 题目描述 读入一个整数 $n$ ,输出 $[1,n]$ 的所有回文质数,我们规定 $1\\sim9$ 也是回文数。\n思路 首先我们需要了解什么是回文数,以及什么是质数。\n简单点说,回文数就是正着读反着读都是一样的,也就是对称的,形如 $abcba $ 或者 $123321$ 这样的。\n质数的话,对于一个数 $n$ ,如果他是质数,那它除了 $1$ 和 $n$ 没有其他因子。例如 $2,3,5,7,11$ 这样的。\n那么接下来我们考虑一下解决这个问题应该怎么做,首先我们看一下数据范围,$[1,100000]$ ,还是挺小的,我们可以考虑直接枚举每一个数来判断它是不是回文数,然后再判断一下是不是质数,如果两个都满足,我们就输出它。\n判断回文数,我们可以考虑到 NOJ05 幸运数 一题的解题思路,也就是说我们把一个数倒置过来,好比一个数 $xyz$ 倒置成 $zyx$ ,然后判断是否 $xyz == zyx$ ,如果相等的话就是回文数,如果不相等就不是。\n判断质数,我们可以在 $[2,\\lfloor\\sqrt{n}\\rfloor]$ 枚举它的因子,这个的完备性我上课的时候证明过,不再赘述。这里需要注意 $1,2$ 需要特判一下。\n代码 #include\u0026lt;stdio.h\u0026gt; #include\u0026lt;math.h\u0026gt; //我们需要用到sqrt函数,因此需要引入数学库 int main() { int n; bool flag = false; // 标记 i 是否满足条件 scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { flag = true; int p=i,j=0; while(p) // 将 p 反转为 j { j=j*10+p%10; p/=10; } if(j==i) { if(j==1) continue; // 特判 1 if(j==2) // 特判 2 { printf(\u0026#34;2\\n\u0026#34;); continue; } int sqrtj = sqrt(j); for(int k=2;k\u0026lt;=sqrtj;k++) // 枚举 [2,sqrt(n)] { if(j%k==0) // 如果能够整除(余数为0),那么是 j 的因子 { flag = false; break; } } if(flag) { printf(\u0026#34;%d\\n\u0026#34;,j); } } } } 其他 因为我们讲到这里的时候,我们没讲函数,但是这道题如果我们把判断是否为回文数,判断是否为质数,都另成一个函数模块,将使得程序变得更加简洁。我在这里也将函数版本的贴出来,有兴趣的可以看一下。","title":"“程序星编程之路”第二次作业题解"},{"content":"Windows 平台 Visual Studio 2019 中 OpenCV 配置教程 前言 我这里配置用的是4.5.0版本,但实际配置过程中需要的大部分时间只是路径,因此和版本基本无关。\n只有一个地方是和版本有关系的,在配置链接器的 opencv_wordxyzd.lib 时,大家一定要注意!!\n1.下载OpenCV 首先我们进入 https://opencv.org/releases/ 在这其中下载OpenCV ,我这里下载的4.5.0 ,选择Windows下载即可。\n下载结束后我们双击安装包,指定解压目录,我这里解压在了我的G盘,具体路径为 G:\\Opencv450\n2.设置OpenCV的环境变量 我们在 此电脑右键 -\u0026gt; 属性 -\u0026gt; 高级系统设置 -\u0026gt; 环境变量 -\u0026gt; 系统变量 -\u0026gt; 双击Path -\u0026gt;添加如下的环境\nG:\\Opencv450\\build\\x64\\vc15\\bin ,这里的路径是根据上面那个路径来看的,如果你上面那个跟我不同,也请看请自己的路径。\n配置Visual Studio 新建一个C++类型的空项目,随便你如何命名,将模式调节为 Debug x64 依次点击 视图 -\u0026gt; 其他窗口 -\u0026gt; 属性管理器\n在打开的 属性管理器 中添加新项目属性表,我是4.5.0的版本,为了好记,新建属性表命名为OpenCV450Debug\n建好以后在其上右键,选择属性 ,然后依次选择 VC++ 目录 -\u0026gt; 包含目录 -\u0026gt; 编辑\n添加下面两个路径,当然,这两个路径也是取决于你安装OpenCV的路径的。\nG:\\Opencv450\\build\\include\nG:\\Opencv450\\build\\include\\opencv2\n接下来选择 VC++ 目录 中的 库目录 -\u0026gt; 编辑 ,然后添加(与你OpenCV路径对应)\nG:\\Opencv450\\build\\x64\\vc15\\lib\n接下来选择 链接器 -\u0026gt; 输入 -\u0026gt; 附加依赖项 -\u0026gt; 编辑\n在其中加入 opencv_world450d.lib ! 大家这里请注意,不同的版本这里的添加名称不同,通常来说如果你的版本是 x.y.z 那么就是 opencv_worldxyzd.lib\n最后我们点击确定,然后退出属性编辑器。\n测试OpenCV的配置 在源文件中添加一个 C++ 源程序,我添加的为 main.cpp\n在其中输入如下测试代码\n#include \u0026lt;iostream\u0026gt; #include \u0026lt;opencv2/core.hpp\u0026gt; #include \u0026lt;opencv2/imgcodecs.hpp\u0026gt; #include \u0026lt;opencv2/highgui.hpp\u0026gt; using namespace std; using namespace cv; int main(int argc, char** argv) { String imageName(\u0026#34;HappyFish.jpg\u0026#34;); // by default if (argc \u0026gt; 1) imageName = argv[1]; Mat image = imread(samples::findFile(imageName), IMREAD_COLOR); // Read the file if (image.empty()) { // Check for invalid input cout \u0026lt;\u0026lt; \u0026#34;Could not open or find the image\u0026#34; \u0026lt;\u0026lt; endl; return -1; } namedWindow(\u0026#34;Display window\u0026#34;, WINDOW_AUTOSIZE); // Create a window for display. imshow(\u0026#34;Display window\u0026#34;, image); // Show our image inside it. waitKey(0); // Wait for a keystroke in the window return 0; } 接下来我们随便找一张 jpg 图片文件,命名为 HappyFish.jpg ,保存在你的工程的根目录下/和 cpp 文件一个路径。这里我放一张 jpg 图片供大家使用~\n然后在我们的 Visual Studio 2019 中按下快捷键 Ctrl + F5 编译运行程序,会发现我们成功打开了这张图片,配置就成功了~\n参考链接 VS2019 上配置 OpenCV4.2.0\n","permalink":"https://blog.zzsqwq.cn/posts/114/","summary":"\u003ch2 id=\"windows-平台-visual-studio-2019-中-opencv-配置教程\"\u003eWindows 平台 Visual Studio 2019 中 OpenCV 配置教程\u003c/h2\u003e\n\u003ch3 id=\"前言\"\u003e前言\u003c/h3\u003e\n\u003cp\u003e我这里配置用的是4.5.0版本,但实际配置过程中需要的大部分时间只是路径,因此和版本基本无关。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e只有一个地方是和版本有关系的,在配置链接器的 \u003ccode\u003eopencv_wordxyzd.lib\u003c/code\u003e 时,大家一定要注意!!\u003c/strong\u003e\u003c/p\u003e","title":"Visual Studio 2019 中 OpenCV 配置教程"},{"content":"了解SQL 一.什么是SQL SQL是结构化查询语言(Structured Query Language)的缩写。是一种专门用来与数据库通信的语言。\n二.什么是数据库? 数据库(Database):保存有组织的数据的容器(通常是一个文件或一组文件)。 ​[scode type = \u0026ldquo;yellow\u0026rdquo;]需要注意的是,有时候我们把数据库软件也简称为数据库,但是数据库软件和数据库有本质区别,数据库软件应称为DBMS(数据库管理系统),我们通过数据库软件对数据库进行删减等操作,他代替你操作和访问数据库。[/scode]\n三.数据库的组成 表\n数据库中通常有多张表,这类似于一个清单。就好像我们管理两个班级就可以用两个表单。\n表单之间用表名区分,在同一个数据库中不能有两个具有相同表名的表单。\n行(又称记录)\n在表中可以有很多行,我们可以把表看成一个二维数组。每一行代表了一个成员。\n列\n每一行有好多列,一列可以代表着成员的一个属性,例如id,班级,姓名等等······\n数据类型\n每一列都有着特定的数据类型,例如字符串和数字就是两种不同的数据类型。\n主键(primary key)\n对于表中的每一行,我们都有一个唯一标识他的记号,这称作他的主键。\n可以发现,主键有以下特征:1.每一行都必须有一个主键,不能为空。2.不同行的主键不同。\n我们可以用多列作为主键,这样只需要确保多列组合起来的标识是唯一的。\n外键(foreign key)\n外键为某个表中的一列,它包含另一个表的主键值,定义了两个表之间的值,通过DBMS的操作可以将两个表联结起来。\n通俗点讲,好比有两张表,分别存储了所有供应商的信息,和所有产品的信息,在前面那张表定义了每个供应商的id,作为其主键。然后我们为每个产品定义外键的id,填上对应供应商的id,然后通过连结,我们就能知道每个产品供应商的详细信息了。\n可伸缩性(scale)\n能够适应不断增加的工作量而不失败。设计良好的数据库或应用程序称之为可伸缩性好(scale well)。\n四.数据库的连结 ​在上面我们讲外键的时候有讲到联结,连结的意思大概就是把多个表,根据一些命令串在一起。\n等值连结(内部连结)\n顾名思义,等值连结就是通过两个表之间元素值的相同来把两个表连结起来。\n自联结\n这个用于查找在同一表中某一特性相同的所有成员。有的时候自联结要比子查询快很多。\n自然联结\n在自然联结中,排除相同的列多次出现,使每个列只返回一次。\n外部联结\n联结包含了那些在相关表中没有关联行的行。这种类型的联结称为外部连结。\n五.数据库设计范式 范式:当一个关系中的所有分类都是不可再分的数据项时,该关系是规范化的。不可再分的数据项,即不存在组合数据项和多项数据项。一个低一级的关系模式,通过模式分解可以转换为若干高一级范式的关系模式的集合,这个过程就叫规范化。\n第一范式:当关系模式R的所有属性都不能在分解为更基本的数据单位时,称R是满足第一范式的,简记为1NF。满足第一范式是关系模式规范化的最低要求,否则,将有很多基本操作在这样的关系模式中实现不了。\n第二范式:如果关系模式R满足第一范式,并且R得所有非主属性都完全依赖于R的每一个候选关键属性,称R满足第二范式,简记为2NF。\n第三范式:设R是一个满足第一范式条件的关系模式,X是R的任意属性集,如果X非传递依赖于R的任意一个候选关键字,称R满足第三范式,简记为3NF。\n用我们学长的一句话,范式不是必须满足的,但是我们尽量按照范式来设计数据库,毕竟这是这么多程序员实战经验总结出来的。\n参考链接 数据库设计三大范式_dosthing 数据库设计三大范式_张龙豪 mysql必知必会 ","permalink":"https://blog.zzsqwq.cn/posts/107/","summary":"了解SQL 一.什么是SQL SQL是结构化查询语言(Structured Query Language)的缩写。是一种专门用来与数据库通信的语言。\n二.什么是数据库? 数据库(Database):保存有组织的数据的容器(通常是一个文件或一组文件)。 ​[scode type = \u0026ldquo;yellow\u0026rdquo;]需要注意的是,有时候我们把数据库软件也简称为数据库,但是数据库软件和数据库有本质区别,数据库软件应称为DBMS(数据库管理系统),我们通过数据库软件对数据库进行删减等操作,他代替你操作和访问数据库。[/scode]\n三.数据库的组成 表\n数据库中通常有多张表,这类似于一个清单。就好像我们管理两个班级就可以用两个表单。\n表单之间用表名区分,在同一个数据库中不能有两个具有相同表名的表单。\n行(又称记录)\n在表中可以有很多行,我们可以把表看成一个二维数组。每一行代表了一个成员。\n列\n每一行有好多列,一列可以代表着成员的一个属性,例如id,班级,姓名等等······\n数据类型\n每一列都有着特定的数据类型,例如字符串和数字就是两种不同的数据类型。\n主键(primary key)\n对于表中的每一行,我们都有一个唯一标识他的记号,这称作他的主键。\n可以发现,主键有以下特征:1.每一行都必须有一个主键,不能为空。2.不同行的主键不同。\n我们可以用多列作为主键,这样只需要确保多列组合起来的标识是唯一的。\n外键(foreign key)\n外键为某个表中的一列,它包含另一个表的主键值,定义了两个表之间的值,通过DBMS的操作可以将两个表联结起来。\n通俗点讲,好比有两张表,分别存储了所有供应商的信息,和所有产品的信息,在前面那张表定义了每个供应商的id,作为其主键。然后我们为每个产品定义外键的id,填上对应供应商的id,然后通过连结,我们就能知道每个产品供应商的详细信息了。\n可伸缩性(scale)\n能够适应不断增加的工作量而不失败。设计良好的数据库或应用程序称之为可伸缩性好(scale well)。\n四.数据库的连结 ​在上面我们讲外键的时候有讲到联结,连结的意思大概就是把多个表,根据一些命令串在一起。\n等值连结(内部连结)\n顾名思义,等值连结就是通过两个表之间元素值的相同来把两个表连结起来。\n自联结\n这个用于查找在同一表中某一特性相同的所有成员。有的时候自联结要比子查询快很多。\n自然联结\n在自然联结中,排除相同的列多次出现,使每个列只返回一次。\n外部联结\n联结包含了那些在相关表中没有关联行的行。这种类型的联结称为外部连结。\n五.数据库设计范式 范式:当一个关系中的所有分类都是不可再分的数据项时,该关系是规范化的。不可再分的数据项,即不存在组合数据项和多项数据项。一个低一级的关系模式,通过模式分解可以转换为若干高一级范式的关系模式的集合,这个过程就叫规范化。\n第一范式:当关系模式R的所有属性都不能在分解为更基本的数据单位时,称R是满足第一范式的,简记为1NF。满足第一范式是关系模式规范化的最低要求,否则,将有很多基本操作在这样的关系模式中实现不了。\n第二范式:如果关系模式R满足第一范式,并且R得所有非主属性都完全依赖于R的每一个候选关键属性,称R满足第二范式,简记为2NF。\n第三范式:设R是一个满足第一范式条件的关系模式,X是R的任意属性集,如果X非传递依赖于R的任意一个候选关键字,称R满足第三范式,简记为3NF。\n用我们学长的一句话,范式不是必须满足的,但是我们尽量按照范式来设计数据库,毕竟这是这么多程序员实战经验总结出来的。\n参考链接 数据库设计三大范式_dosthing 数据库设计三大范式_张龙豪 mysql必知必会 ","title":"数据库的一些基础知识总结"},{"content":"引言 本来之前是用的 Hexo + Github 搭建的,虽然用的是 Github 的服务器,但是我用家里的移动网访问起来还是没什么压力,就是慢一点,可以接受。\n后来到了学校,我们学校网访问 Github 的速度简直可以用龟速来形容,白天可以说不开代理根本进不去,只有晚上了才能勉强进得去。然后我就寻思,能不能换成国内的服务器,然后就发现了 Gitee ,这个可以算是中国版的 Github ,他具有的服务 Gitee Pages 在国内可以飞速的访问,But如果想要自定义域名/每次推送自动更新需要开 Github Pages Pro ,还挺贵的,一年大概 120¥ 吧。此外,如果想要将域名解析到国内的服务器必须要备案,备案又必须有服务器,那我有服务器了还费那些事了,于是考虑自己买服务器重构一下博客。\n一些博客系统 搭博客,首先我们需要构思一下用什么博客系统,市面上比较广泛的有如下几个。\nWordpress\n这个绝对是重量级的,在全球范围内也是十分出名的,他的作用也不仅仅局限于搭建个人博客,也有很多例如电商等官网也是基于此系统的,据说全球 37% 的网站都是基于 Wordpress 的,这统治地位,可见一斑。\n优点:博客主题多样,十分的大气,插件也是各种各样的应有尽有。里面的设置也是十分的多,特别特别多,这个可以说是既是优点又是缺点,很多东西如果是个人博客的话根本用不到。\n缺点:不是原生支持markdown,并且对LaTeX的支持十分拉胯。需要安装插件,但是显示效果也是不尽人意。此外,Wordpress相比于下面推出的几个十分的臃肿,因为多了很多东西,安装包挺大的(虽然也就几MB的感觉),而且我没有找到我喜欢的主题,于是装载后卸掉了。\nEmlog\nEmlog 博客系统十分的简洁轻巧,安装包只有几百KB。\n优点:比较轻巧方便,主题和插件也还算多。\n缺点:其实主题我觉得,没有太好看的。所以没有考虑,大家可以去翻翻看看有没有钟意的主题再考虑是否安装这一个。\nTypecho\n这个博客系统是我现在正在用的,也是十分的轻巧简洁,是一个国产的博客系统。\n优点:自身对markdown的支持十分的友好,而且有一款插件对LaTeX的支持也是超级棒!因为我比较喜欢之前Hexo里面的NexT主题,而Typecho里面有这个的移植主题,所以最终还是选择的这个系统这个主题。而且他还有好几款例如 Handsome,Aria 这样的我觉得不错的主题。Ps: Handsome主题需要收费,而且现在还在更新,我觉得超值!\n缺点:正式版好久没更新了,上一次更新还是2017年。\n搭建过程 1. 购买服务器 首先我们去阿里云那边买一台学生机,一年也就 120¥ 的样子,很实惠。本来一年大概 1600¥ 的样子。\n买学生机的话就买 轻量应用服务器 ,然后应用镜像选一下 BT-Panel 即可。\n2. 登录服务器 进去之后点击应用详情,看一下 BT-Panel使用步骤。\n根据上面的指示获取登陆服务器的密码。然后点击左侧的 防火墙 ,在那里开启 8888 端口。如下图所示。\n3. 配置服务器 我们登录进入服务器后,点击左侧应用商城。依次安装 Apache、PHP-7.4、Mysql5.6。可能要等挺长时间。\n4. 开启网站 安装完成后,我们去面板设置那边看一下自己的 服务器ip ,记下来。\n点击左侧网站,添加站点。域名那里写自己的 服务器ip ,然后提交即可。\n然后点击左侧数据库,建立一个新的数据库,用于存放我们之后网站的信息。\n我们访问到我们网站的根目录,然后将自己心仪的博客程序拷入,访问 服务器ip/install.php 即可开启安装!\n安装完成后我们就可以通过 服务器ip 来访问我们的网站了!然后可以去网上找一下心仪的主题和插件来安装~\n一些后续工作 如果我们要自定义域名,首先我们可以去阿里云 / 腾讯云那边买一个域名,然后进行域名备案,你服务器是在哪边买的就在哪边备案即可。后续备案结束后在云解析那边添加域名解析(具体操作可以百度),然后在 BT-Panel 这边也添加域名解析,这样即可使用我们的自定义域名访问博客了!\n还有一些后续的优化例如安装 https安全证书(我自己现在还没搞好QAQ) ,加入 SEO优化 ,提交申请让 搜索引擎收录 等等……大家有兴趣的可以自行探索!\n","permalink":"https://blog.zzsqwq.cn/posts/77/","summary":"\u003ch2 id=\"引言\"\u003e引言\u003c/h2\u003e\n\u003cp\u003e本来之前是用的 \u003cstrong\u003eHexo + Github\u003c/strong\u003e 搭建的,虽然用的是 \u003cstrong\u003eGithub\u003c/strong\u003e 的服务器,但是我用家里的移动网访问起来还是没什么压力,就是慢一点,可以接受。\u003c/p\u003e\n\u003cp\u003e后来到了学校,我们学校网访问 \u003cstrong\u003eGithub\u003c/strong\u003e 的速度简直可以用龟速来形容,白天可以说不开代理根本进不去,只有晚上了才能勉强进得去。然后我就寻思,能不能换成国内的服务器,然后就发现了 \u003cstrong\u003eGitee\u003c/strong\u003e ,这个可以算是中国版的 \u003cstrong\u003eGithub\u003c/strong\u003e ,他具有的服务 \u003cstrong\u003eGitee Pages\u003c/strong\u003e 在国内可以飞速的访问,But如果想要自定义域名/每次推送自动更新需要开 \u003cstrong\u003eGithub Pages Pro\u003c/strong\u003e ,还挺贵的,一年大概 \u003cstrong\u003e120¥\u003c/strong\u003e 吧。此外,如果想要将域名解析到国内的服务器必须要备案,\u003cstrong\u003e备案又必须有服务器\u003c/strong\u003e,那我有服务器了还费那些事了,于是考虑自己买服务器重构一下博客。\u003c/p\u003e","title":"自买服务器建站教程"},{"content":"Day 3 A. 黑妹的游戏Ⅰ 题意 给出三个不同的初始数字$a,b,c$,黑妹每次选择两个不同的数字,计算出差的绝对值后如果黑板上没有就写在黑板上。问黑妹最多能添加多少个数字。\n思路 考虑到辗转相除法的那种过程(其实我也是突发奇想,严谨证明不会),最后黑板上所有的数字是 $$ ans = \\frac{max(a,b,c)}{gcd(a,b,c)} $$ 然后就需要减去黑板上原来的三个数就行。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; int t; long long a,b,c; long long gcd(long long a,long long b) { if(b == 0) return a; return gcd(b,a%b); } int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { scanf(\u0026#34;%lld%lld%lld\u0026#34;,\u0026amp;a,\u0026amp;b,\u0026amp;c); long long p = max(max(a,b),c); long long k = gcd(gcd(a,b),c); printf(\u0026#34;%lld\\n\u0026#34;,p/k-3); } return 0; } B. 御坂美琴 题意 有 $n$ 个玩偶堆成一堆。$(1\\le n \\le 10^{18})$\n你可以指定某一有 $x$ 个玩偶的玩偶堆将他分成 $\\lfloor \\frac{x}{2}\\rfloor$ 和 $x-\\lfloor \\frac{x}{2} \\rfloor$ 两堆。\n现给定有 $m$ 个数的序列 $a$ ,问能否通过若干次操作使得第 $i$ 堆玩偶数为 $a_i$ 。如果可以输出 misaka 否则输出 ham 。$(1\\le m\\le 10^5) , (1\\le a_i\\le 10^{18})$\n思路 首先我们可以想到,我们输入序列 $a$ 的时候可以将他累加起来成 $sum$ ,然后考虑最后$sum$ 是否和 $n$ 相同,不同的话肯定是不满足条件的,直接输出ham退出即可。\n否则我们就用 $dfs(n)$ 分割这个 n个玩偶的玩偶堆。因为 $n$ 比较大,考虑开一个map映射 $p$ 记录是否已经有为 $i$ 个玩偶的玩偶堆,如果有的话 $p[i] = 1$。如果没有 $p[i] = 0$ 。\n然后加一个递归结束的条件,就是当 $dfs(k)$ 的时候 $k == 1$ ,那么就不可再分了,直接返回。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; #include\u0026lt;queue\u0026gt; #include\u0026lt;map\u0026gt; using namespace std; #define ll long long const long long maxn = 1e18+5; const int maxm = 1e5+5; ll n,m; ll a[maxm]; ll sum; map\u0026lt;ll,bool\u0026gt; mp; int cmp(ll a,ll b) { return a\u0026gt;b; } void dfs(ll p) { if(mp[p] == 1 || p==1) return ; else { mp[p] = 1; dfs(p\u0026gt;\u0026gt;1); dfs(p-(p\u0026gt;\u0026gt;1)); } } int main() { scanf(\u0026#34;%lld%lld\u0026#34;,\u0026amp;n,\u0026amp;m); for(int i=1;i\u0026lt;=m;i++) { scanf(\u0026#34;%lld\u0026#34;,\u0026amp;a[i]); sum += a[i]; } if(sum != n) { printf(\u0026#34;ham\\n\u0026#34;); return 0; } // sort(a+1,a+1+m,cmp); dfs(n); mp[1] = 1; for(int i=1;i\u0026lt;=m;i++) { if(mp[a[i]] == 0) { printf(\u0026#34;ham\\n\u0026#34;); return 0; } } printf(\u0026#34;misaka\\n\u0026#34;); return 0; } Day 4 A. Distance 题意 给定有 $n$ 个数的序列 $A$ ,第 $i$ 个位置对应的值为 $A_i$ 。$(n\\le 10^5 ,A_i \\le 10^9)$\n定义 $FST$ 距离为 $|i^2 - j^2| + |A_i^2 - A_j^2|$ ,现在 $fst$ 想在序列 $A$ 中找到距离最大的一对元素,他不关心是哪一对,只想要求出最大的距离。\n思路 我们分情况讨论一下\n当 $i \u0026gt; j$ 并且 $A_i \u0026gt; A_j$ ,我们去掉绝对值后 $dis = i^2 + A_i^2 - (j^2 + A_j^2)$ 当 $i \u0026gt; j$ 并且 $A_i \u0026lt; A_j$ ,我们去掉绝对值后 $ dis = i^2 -A_i^2 -(j^2-A_j^2)$ 所以我们只需要在输入的时候维护两个数组,分别为 $p[i] = i^2+A_i^2 ,q[i] = i^2-A_i^2$ ,排序一下,然后在上面两个 $dis$ 中取一个最大值即可。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; #define ll long long const int maxn = 1e5+5; int n; long long a[maxn]; long long f1[maxn]; long long f2[maxn]; int cmp(long long a,long long b) { return a\u0026gt;b; } int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%lld\u0026#34;,\u0026amp;a[i]); f1[i] = (long long)i*i + (long long)a[i]*a[i]; f2[i] = (long long)i*i - (long long)a[i]*a[i]; } sort(f1+1,f1+1+n,cmp); sort(f2+1,f2+1+n,cmp); ll p = f1[1] - f1[n]; ll k = f2[1] - f2[n]; if(p \u0026gt; k) { printf(\u0026#34;%lld\u0026#34;,p); } else printf(\u0026#34;%lld\u0026#34;,k); } B. 字典序最小的中序遍历 题意 给一个有根二叉树,可以无限次的交换任意节点的左右子树,问最少交换多少次使得该树的中序遍历的字典序最小?\n思路 首先这题我上来觉得他就是个贪心题。。不然真的无从下手。\n那么字典序最小,只能是左边小于右边,如果不是的话就直接交换就完事了,然后 $ans++$ 即可。\n然后最后利用 $dfs$ 进行树的中序遍历即可。看代码还是比较好懂的。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; int n,m; const int maxn = 500005; int a[maxn],b[maxn]; int ans = 0; int rev(int p) { int l = p ,r = p; if(a[p]) l = rev(a[p]); if(b[p]) r = rev(b[p]); if(l \u0026gt; r) { swap(a[p],b[p]); ans++; } return l\u0026lt;r?l:r; } void dfs(int p) { if(a[p]==0 \u0026amp;\u0026amp; b[p] ==0) { printf(\u0026#34;%d \u0026#34;,p); return ; } if(a[p]) dfs(a[p]); printf(\u0026#34;%d \u0026#34;,p); if(b[p]) dfs(b[p]); } int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;m); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;a[i],\u0026amp;b[i]); } int k = rev(m); printf(\u0026#34;%d\\n\u0026#34;,ans); dfs(m); return 0; } ","permalink":"https://blog.zzsqwq.cn/posts/68/","summary":"\u003ch1 id=\"day-3\"\u003eDay 3\u003c/h1\u003e\n\u003ch2 id=\"a-黑妹的游戏httpsacnowcodercomacmcontest6956a\"\u003eA. \u003ca href=\"https://ac.nowcoder.com/acm/contest/6956/A\"\u003e黑妹的游戏Ⅰ\u003c/a\u003e\u003c/h2\u003e\n\u003ch3 id=\"题意\"\u003e题意\u003c/h3\u003e\n\u003cp\u003e给出三个不同的初始数字$a,b,c$,黑妹每次选择两个不同的数字,计算出差的绝对值后如果黑板上没有就写在黑板上。问黑妹最多能添加多少个数字。\u003c/p\u003e","title":"排位三和四记录"},{"content":"Day 1 A. 兔子的区间密码 题意 给定一个区间$[L,R]$ ,求从这个区间任意取两个整数(可以相同),两者异或后能得到的最大值是多少?\n思路 首先我们想一下特例,当 $L==R$ 的时候,那么只能是L和他自己异或,就是0了。\n然后可以分两部分来想,设区间端点 $L,R$ 的二进制最高位,从右往左开始数位置分别为 $p_1,p_2$\n如果 $p_1 \\neq p_2 $ ,那么必然是 $p_1 \u0026lt; p_2$ ,我们很容易发现这时候肯定可以取到 $2^{p_2-1}-1 和 2^{p_2-1}$ ,那么两者异或一下就是最大的,答案为 $2^{p_2}$ 如果 $p_1 == p_2$ ,那么我们可以转化为更小规模的问题,就是区间为 $[L-2^{p_1-1},R-2^{p_1-1}]$ 。 代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; #define ll long long ll l,r; int t; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { ll l,r; scanf(\u0026#34;%lld%lld\u0026#34;,\u0026amp;l,\u0026amp;r); if(l == r) { printf(\u0026#34;0\\n\u0026#34;); } else { int p1 = log2(l),p2 = log2(r); while(p1 == p2 \u0026amp;\u0026amp; l != 0) { l^=(1LL\u0026lt;\u0026lt;p1); r^=(1LL\u0026lt;\u0026lt;p1); p1 = log2(l),p2=log2(r); } printf(\u0026#34;%lld\\n\u0026#34;,((1LL\u0026lt;\u0026lt;(p2+1))-1)); } } return 0; } B. 猴子排序的期望 题意 有 $N$ 张卡片,每个上面都写着一个大写字母,问随便扔一次这 $N$ 张的卡片就已经按字典序排好的概率,答案用分字为1的形如 $1/x$ 的形式表示。$( 1\u0026lt;N \u0026lt; 100)$\n思路 这题很显然是道数学排列组合题,我们设每个字母重复出现的次数为 $p[i]$ ,好比字母为$A$的卡片出现了两次,那么就 $p[\u0026lsquo;A\u0026rsquo;]$ 为2。\n那么答案就是如下 $$ ans = \\frac{N!}{\\Pi_{i=\u0026lsquo;A\u0026rsquo;}^{i=\u0026lsquo;Z\u0026rsquo;}(p[i]!)} $$ 这题主要难点大概是在高精,因为可能会涉及到 $100!$ 这种丧心病狂的东西,所以就用笨比的方法写了一发python。其实是高级的算法不会用python写,C++乘法的高精忘掉了。\n代码实现 n = int(input()) s = input() s[0:n:1] ans = 1 for i in range(1,n+1): ans = ans*i for i in range(0,n): count = 0 for j in range(i,n): if s[i] == s[j]: count = count + 1 if count \u0026gt;= 0: ans = ans//count #这里本来//写成了/,连WA3发 print(\u0026#34;1/\u0026#34;,end=\u0026#34;\u0026#34;) print(int(ans)) Day 2 A. 愤怒的巨巨 题意 已知香蕉的次品率为 $p(0\\le p\\le 1)$ ,如果想要买到好香蕉则买香蕉个数的期望值是多少。如果买不到好香蕉,输出”Sorrry,JuJu!”(忽略双引号)。否则输出期望值的最简分数形式:c/d. $p$ 的最多位数为6。\n思路 首先理解一下题意,好比次品率 $p$ 为0.5,则期望的个数为2个。如果次品率 $p$ 为 0.25,则可以说平均买四个有一个次品,那么最少需要的买的个数其实是 $3/4$ 。\n再者特判一下 $p == 0$ 以及 $p==1$ 的情况,分别输出 1/1 和 Sorrry,JuJu! 。\n然后其实可以看一下非次品率 $k = 1-p$ ,然后其实就是一个最大公约数问题了。只需要把 $k$ 转换成分数形式,然后用最大公约数约分一下,再取一个倒数即可。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; char str[100]; int k = 0; int mod = 1; bool flag = false; int gcd(int a,int b) { if(b==0) return a; return gcd(b,a%b); } int main() { scanf(\u0026#34;%s\u0026#34;,str); int len = strlen(str); if(str[0] == \u0026#39;0\u0026#39;) { for(int i=2;i\u0026lt;len;i++) { if(str[i] != \u0026#39;0\u0026#39;) flag = true; } if(flag == false) { printf(\u0026#34;1/1\u0026#34;); return 0; } } if(str[0] == \u0026#39;1\u0026#39;) { printf(\u0026#34;Sorrry,JuJu!\u0026#34;); return 0; } for(int i=2;i\u0026lt;len;i++) { k = k*10+str[i]-\u0026#39;0\u0026#39;; mod *= 10; } int m = mod - k; int p = gcd(m,mod); printf(\u0026#34;%d/%d\u0026#34;,mod/p,m/p); return 0; } B. 兔子的逆序对 题意 给定一个区间 $[L,R]$ ,然后给出 $m$ 次翻转操作,通过给出子区间左右端点,反转该区间。每翻转一次,要求给出区间 $[L,R]$ 逆序对的奇偶性,如果是奇数,输出 dislike ,如果是偶数,输出 like 。\n思路 首先用归并 / 树状数组的方法,求出来区间 $[L,R]$ 的逆序对 $ans$。\n然后我们考虑每一次翻转带来的影响。我们考虑一个子区间 $[l,r]$ ,设该区间逆序对为 $x$ ,那么反转后该区间的逆序对为 $C_n^2 -x$ 。翻转区间 $[l,r]$ 导致答案 $ans = ans + C_n^2 -x - x = ans + C_n^2-2x$\n因为只需要奇偶性,那么 $2x$ 需要考虑,那么就每次看看 $C_n^2$ 的奇偶性即可。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; #define lowbit(x) (x)\u0026amp;(-x) typedef struct Node { int val; // value int pos; //postion }node; int cmp(node a,node b) { return a.val\u0026lt;b.val; } const int maxn = 1e5+5; const int maxm = 2e6+5; node num[maxn]; int tree[maxm]; int n,m; int l,r; void add(int x) { for(int i=x;i\u0026lt;=n;i+=lowbit(i)) { tree[i]++; } } int find(int x) { int sum=0; for(int i=x;i\u0026gt;0;i-=lowbit(i)) { sum+=tree[i]; } return sum; } int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;num[i].val); num[i].pos=i; } sort(num+1,num+n+1,cmp); int ans = 0; for(int i=1;i\u0026lt;=n;i++) { ans+=find(num[i].pos); add(num[i].pos); } scanf(\u0026#34;%d\u0026#34;,\u0026amp;m); for(int i=1;i\u0026lt;=m;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;l,\u0026amp;r); int k = ((r-l+1)*(r-l))\u0026gt;\u0026gt;1; if(k\u0026amp;1) { if(ans%2 == 0) { printf(\u0026#34;dislike\\n\u0026#34;); ans++; } else { printf(\u0026#34;like\\n\u0026#34;); ans++; } } else { if(ans%2 == 0) { printf(\u0026#34;like\\n\u0026#34;); } else { printf(\u0026#34;dislike\\n\u0026#34;); } } } } C. Butterfly 题意 这题描述起来有点难,还是直接点链接去看比较好。\n大概就是给定一个 由 X 和 O 构成的$n\\times m$ 的矩阵,让你找出里面由 X 构成的蝴蝶的最大对角线长度。\n思路 这题第一时间让我想到了我 2020/2/12 写的dp练习中的创意吃鱼法。\n一开始想要考虑从中心开始考虑,但是需要维护的东西有点多,而且周围的判别不好判。因此可以考虑从右上/右下/左上/左下 这四个位置考虑,我这里是从左下考虑的。设我们要求的答案为 $ans$ 。\n考虑维护三个数组,看 X 向上延伸,左上延伸,右上延伸的长度。所以我们依次遍历矩阵中的每一个元素,判定他是否可以作为蝴蝶的左下角,首先取一个向上延伸和右上延伸的最小值 $p$,然后从 $p$ 到 $ans$ 遍历,每次判定一下该答案是否合法,判定的话无非是从右下角判定一下就行,比较简单。如果答案合法,那么更新 $ans$。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn = 2005; int lr[maxn][maxn],rr[maxn][maxn],str[maxn][maxn]; //分别为按左上、右上,向上延伸 char x; int n,m; int ans; int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;m); for(int i=1;i\u0026lt;=n;i++) { for(int j=1;j\u0026lt;=m;j++) { cin\u0026gt;\u0026gt;x; if(x == \u0026#39;X\u0026#39;) { lr[i][j] = lr[i-1][j-1] + 1; rr[i][j] = rr[i-1][j+1] + 1; str[i][j] = str[i-1][j] + 1; ans = 1; } } } for(int i=1;i\u0026lt;=n;i++) { for(int j=1;j\u0026lt;=m;j++) { int p = min(str[i][j],rr[i][j]); for(int k = p;k\u0026gt;ans;k--) { if(k\u0026amp;1) { if(str[i][j+k-1]\u0026gt;=k \u0026amp;\u0026amp; lr[i][j+k-1]\u0026gt;=k) ans = max(ans,k); } } } } printf(\u0026#34;%d\u0026#34;,ans); } ","permalink":"https://blog.zzsqwq.cn/posts/5/","summary":"\u003ch1 id=\"day-1\"\u003eDay 1\u003c/h1\u003e\n\u003ch2 id=\"a-兔子的区间密码httpsacnowcodercomacmcontest6954a\"\u003eA. \u003ca href=\"https://ac.nowcoder.com/acm/contest/6954/A\"\u003e兔子的区间密码\u003c/a\u003e\u003c/h2\u003e\n\u003ch3 id=\"题意\"\u003e题意\u003c/h3\u003e\n\u003cp\u003e给定一个区间$[L,R]$ ,求从这个区间任意取两个整数(可以相同),两者异或后能得到的最大值是多少?\u003c/p\u003e","title":"排位一和二记录"},{"content":"高精度计算PI值 题目描述 使用双向链表作为存储结构,请根据用户输入的一个整数(该整数表示精确到小数点后的位数,可能要求精确到小数点后 500 位),高精度计算PI值。提示:可以利用反三角函数幂级展开式来进行计算。\n解题思路 求PI的算法 首先这道题是要求必须使用双向链表作为存储结构的,这个需要注意,而且也不能用数组计算完了之后挨个赋值给链表的每个节点,这是耍赖 。\n那么我们开始再想,用什么公式来求 PI 呢?这是一个问题。先没管题目的提示,我去百度了一通,发现了一个很神奇的算法,用三行就可以计算到圆周率小数点后800+位。\n#include\u0026lt;cstdio\u0026gt; using namespace std; long a=1000,b,c=2800,d,e,f[2801],g; int main(){ for(;b-c;) f[b++]=a/5; for(;d=0,g=c*2;c-=14,printf(\u0026#34;%.3d\u0026#34;,e+d/a),e=d%a) for(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b); } ​实验了一下发现居然真的是,而且效率还挺高的?看了一会实现的原理一直没看懂,作罢。\n​最后发现是找不到什么除了幂级展开还有啥高效率的算法了好像,还是考虑题目提示的 三角函数幂级展开。然后继续在网上搜索了一下,在学长的一个博客里发现了公式。 $$ f_{i} = \\begin{cases} 1 \u0026amp; {i=1}\\\\ f_{i-1}\\times \\frac{i-1}{2\\times i-1} \u0026amp; {i\u0026gt;1} \\end{cases} $$\n那么拿到了这个式子,我们就可以分析一下,怎么和链表结合起来做了。\n链表的设计 双向链表,也就是每个节点有一个数据域,有前和后两个指针。我考虑到我们做加法和乘法是需要从后往前做,除法是需要从前往后做。因此需要双向遍历,我又添加了一个尾指针,记录当前链表的尾节点的地址,方便从后往前遍历,头节点可以保证从前往后遍历。设计如下:\ntypedef struct node { int data; struct node *nxt; struct node *pre; struct node *tail; node() //构造函数,用于初始化 { nxt = NULL; pre = NULL; tail = this; data = 0; } } 数据域就用来存储每一位数字,好比 3.1415926 就从第一个节点到第八个节点依次存 31415926 。\n乘法的实现 另出一个函数,函数声明类似于 void Multi(List L,int k)\n乘法我们模拟竖式的乘法运算,考虑到这是一个 高精度大数 * 低精度整数 ,因此我们只需要从尾部到头部依次对每一位做乘法即可,考虑到进位问题,可以有两种办法\n可以是先做完乘法,然后再回到尾部,再从尾到头依次处理进位,这样的好处是这两种操作分隔开了,操作起来难度不大,也比较好想。 可以是边做乘法边进位,我们定义一个 temp 用来存储低位到高一位的进位,这里要注意的是,对于某一位的操作不是先加上进位再做乘法,是先做乘法,再加低位的进位。 但是有一个问题我们需要注意,就是好比 52 * 3 ,这时候原来的两位数变成三位数了,因此需要我们在头节点和第一个节点之间增加新的节点,并且可能增加的不只是一个,只要 temp 这个进位大于等于10就需要一直创建新的节点来保证进位。\n除法的实现 另出一个函数,函数声明类似于 void Division(List L,int k)\n除法也是模拟竖式运算,这个是从头到尾进行处理,这一位的数据做完除法,余数作为下一位的**“进位”** ,这里可以边做边 “进位” 。这里这个进位不是乘法的那种进位,注意区分。\n需要注意的是最后可能有除不尽的情况,这样我们就可以一直在尾部插入节点,然后处理一直处理数据到最大位数 或者 到 “进位” 为0为止 。最后不要忘记重置一下尾指针,指向新的尾节点。\n加法的实现 函数声明类似于 void Sum(List L,List p) 。\n加法的实现也是需要从后往前遍历,然后依次对每一位做加法。先取两个链表的尾节点出来,然后依次向前遍历相加,我们可以把相加的答案放在前面那个链表里面,注意这样是不需要返回值的,因为链表内部是通过地址索引的,我们改变的就是传入链表的值。\n最后的整合 最后我们总共需要一个和链表,一个 $f_{i}$。 和链表用于计算所有式子的累加和,而 $f_{i-1}$ 其实就是 $f_i$ 的上个阶段 。我们每次把 $f_i$ 和 和链表进行累加即可。\n最后再对和链表乘2 即可。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; #include\u0026lt;algorithm\u0026gt; using namespace std; const int maxsize = 600; // 设定求小数点后多少位 typedef struct node // 双向链表的结构体 { int data; struct node *nxt; struct node *pre; struct node *tail; node() //构造函数,用于初始化 { data = 0; tail = this; nxt = NULL; pre = NULL; } }Node,*List; void Mult(List Head,int k); // 对链表每一位 *k void Divi(List Head,int k); // 对链表每一位 ÷k void Sum(List a,List b); // 对两个链表的数求和,所得数放在前面链表中 void InitList(List \u0026amp;L); // 初始化链表,并把第一个节点值设为 1 void InitSum(List \u0026amp;L); // 初始化最后存和的链表,并把第一个节点置为1 void Output(List L,int k); // 输出一个链表,保留 k 位小数 int main() { int n = 0; scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); List Head,S; InitList(Head); InitSum(S); for(int i=2;i\u0026lt;=3000;i++) //计算pi值 { Mult(Head,i-1); Divi(Head,2*i-1); Sum(S,Head); } Mult(S,2); Output(S,n); return 0; } void Mult(List Head,int k) // 对以Head为头节点的链表中的每一位做乘法 { List p = Head-\u0026gt;tail; // 先把指针指向链表的末尾,方便从后往前做乘法 while(p != Head) // 从前往后开始算乘法 { p-\u0026gt;data *= k; p = p-\u0026gt;pre; // printf(\u0026#34;I have done Multi.\\n\u0026#34;); } p = Head-\u0026gt;tail; while(p != Head-\u0026gt;nxt) //开始处理进位 { p-\u0026gt;pre-\u0026gt;data += p-\u0026gt;data /10; p-\u0026gt;data %= 10; p = p-\u0026gt;pre; } while( p-\u0026gt;data \u0026gt; 10) //一直处理最高位的进位 { List s = (List)malloc(sizeof(Node)); s-\u0026gt;data = p-\u0026gt;data/10; p-\u0026gt;data %= 10; s-\u0026gt;pre = Head; s-\u0026gt;nxt = p; p-\u0026gt;pre = s; Head-\u0026gt;nxt = s; p = s; } } void Divi(List Head,int k) // 对链表每一位除k { int temp = 0,depth = 0; //temp用于进位计算 ,depth 用于计算链表长度 List p = Head-\u0026gt;nxt; List t; // 存尾部节点 while(p != NULL) //模拟做除法 { depth++; p-\u0026gt;data += temp*10; temp = p-\u0026gt;data % k; p-\u0026gt;data /= k; t = p; p = p-\u0026gt;nxt; } p = t; while(temp!=0 \u0026amp;\u0026amp; depth \u0026lt;= maxsize) // 如果除不尽,就一直往后拓展节点,但注意不要超过最大位数 { // printf(\u0026#34;I have done Division!\\n\u0026#34;); depth++; List s = (List)malloc(sizeof(Node)); s-\u0026gt;data = temp*10; s-\u0026gt;nxt = NULL; s-\u0026gt;pre = p; temp = s-\u0026gt;data % k; s-\u0026gt;data /= k; p-\u0026gt;nxt = s; p = s; } Head-\u0026gt;tail = p; } void Sum(List a,List b) // 对两个链表的数求和,所得数放在前面链表中 { List p = a-\u0026gt;tail,k = b-\u0026gt;tail; // 先指向各自的尾部,开始从前往后加 while(p!=a \u0026amp;\u0026amp; k!=b) // 遍历到有一个到头节点为止 { p-\u0026gt;data += k-\u0026gt;data; p-\u0026gt;pre-\u0026gt;data += p-\u0026gt;data / 10; p-\u0026gt;data %= 10; p = p-\u0026gt;pre; k = k-\u0026gt;pre; } } void InitList(List \u0026amp;L) // 初始化链表,并把第一个节点值设为 1 { L = (List)malloc(sizeof(Node)); L-\u0026gt;data = 0; List s = (List)malloc(sizeof(Node)); s-\u0026gt;data = 1; s-\u0026gt;pre = L; L-\u0026gt;nxt = s; L-\u0026gt;pre = NULL; L-\u0026gt;tail = s; s-\u0026gt;nxt = NULL; } void InitSum(List \u0026amp;L) // 初始化最后存和的链表,并把第一个节点置为1 { L = (List)malloc(sizeof(Node)); L-\u0026gt;nxt = NULL; L-\u0026gt;pre = NULL; L-\u0026gt;data = 0; List p = L; int depth = 0; while(depth \u0026lt;= maxsize) { List s = (List)malloc(sizeof(Node)); s-\u0026gt;data = 0; s-\u0026gt;pre = p; p-\u0026gt;nxt = s; s-\u0026gt;nxt = NULL; p = s; depth++; } L-\u0026gt;nxt-\u0026gt;data = 1; L-\u0026gt;tail = p; } void Output(List L,int k) //输出一个列表,保留 k 位小数 { List p = L-\u0026gt;nxt; printf(\u0026#34;%d.\u0026#34;,p-\u0026gt;data); p = p-\u0026gt;nxt; int t = 0; while(p != NULL \u0026amp;\u0026amp; t\u0026lt;k) { t++; printf(\u0026#34;%d\u0026#34;,p-\u0026gt;data); p = p-\u0026gt;nxt; } printf(\u0026#34;\\n\u0026#34;); } 参考链接 数据结构实验:高精度计算圆周率 圆周率高精度算法 ","permalink":"https://blog.zzsqwq.cn/posts/67/","summary":"\u003ch2 id=\"高精度计算pi值\"\u003e高精度计算PI值\u003c/h2\u003e\n\u003ch3 id=\"题目描述\"\u003e题目描述\u003c/h3\u003e\n\u003cp\u003e使用双向链表作为存储结构,请根据用户输入的一个整数(该整数表示精确到小数点后的位数,可能要求精确到小数点后 \u003cstrong\u003e500\u003c/strong\u003e 位),高精度计算PI值。\u003cstrong\u003e提示:可以利用反三角函数幂级展开式来进行计算。\u003c/strong\u003e\u003c/p\u003e","title":"高精度计算pi"},{"content":"Python学习笔记 Python的不同解释器 CPython\n这是自带的用C语言开发的解释器,因此叫CPython。它也是使用最广的Python解释器。\nIPython\n这是基于CPython之上的一个交互式解释器,只是相比于CPython多了交互上的优化。\nPyPy\n它的目标是执行速度。PyPy采用JIT技术,对Python代码进行动态编译(注意不是解释),所以可以显著提高Python代码的执行速度。他与CPython略有不同。\nJython\n这是运行在Java平台上的Python解释器,可以直接把Python代码编译成Java字节码执行。\nIronPython\n这是运行在微软.Net平台上的Python解释器,可以直接把Python代码编译成.Net的字节码。\nPython基础 简单的输入和输出(I/O) 输入 python提供了一个 input() 函数供我们输入使用,这读入的是字符串数据,并返回,可以将返回值存放在一个变量中。input函数中可以带字符串,这段字符串在输入前会打印在屏幕上,这使得我们具有很好的交互性,好比我们写:\nname = input(\u0026#34;hello,friend! please input your name\u0026#34;) print(\u0026#34;The input name is \u0026#34;,name) 那么这时候我们运行上述程序,就会提示 hello , friend! please input your name ,这就提示我们应该输入名字。\n这里需要注意的是,input() 函数读入的是一个字符串 str ,就算我们输入了整数他也是一个字符串,如果我们要用真正的整数,那么就需要用 int() 进行类型强制转换。如果其中不是合法的整数,那么会报错。\n输出 python中的输出函数是 print() ,这和 C++ 的printf 差了一个f。我们在函数的参数中传入什么,他就会打印什么。好比我们写 print(\u0026quot;heelo,world\u0026quot;) ,那么运行就会打印 hello,world 在屏幕上。print 支持我们传入多个参数,好比 printf(\u0026quot;my name is\u0026quot;,\u0026quot;zs\u0026quot;) ,两两之间用逗号隔开,这在输出时会被解析成空格,也就是说两段字符串之间有一个空格。当然此函数也可以打印整数等。\n一些规则 缩进 Python中对代码块的区分,不是用C++的大括号,而是用缩进。处于连续同一缩进的是一个代码块,这也是为什么Python又被戏称为游标卡尺语言的原因。当语句以冒号:结尾时,缩进的语句视为代码块。我们通常用一个Tab / 四个空格 的缩进。\n注释 Python的注释用的是 # ,而 C++ 中的注释用的是 \\\\ 。\nCase Sensitive Python中是大小写敏感的,也就是 a 和 A 不是同一个东西。\n数据类型 1. 整数 Python一个很大的好处就是可以处理任意大小的整数,包括负整数。这也是为什么很多大数题大家都喜欢用Python,hhhh。多数地方都用十进制,但是也是支持其他进制的哈~好比 0x 前缀就是16进制。\n2. 浮点数 浮点数是小数,之所以称为浮点数,是因为小数点位置在科学计数法中是可变的。这里需要注意,整数和浮点数在计算机内部存储方式不同,浮点数应该都是 IEEE754 标准吧?整数之间的运算永远都是精确的,包括除法。而浮点数的运算则会有一定的误差。Python的浮点数也没有大小限制,但是超出一定范围就直接表示为inf(无限大)。\n3. 字符串 字符串是以单引号 '' 或者双引号 \u0026quot;\u0026quot; 括起来的任意文本。我们注意到Python中没有单个字符的概念,就算是单个字符也是一个字符串。如果'' 括起来的字符串内部出现 '' 需要使用\\转义,相同的,如果 \u0026quot;\u0026quot; 括起来的字符串内部出现 \u0026quot;\u0026quot; 需要转义。好比下面的程序\nprint(\u0026#34;My name is \u0026#39;zs\u0026#39;\u0026#34;) #合法 My name is \u0026#39;zs\u0026#39; print(\u0026#34;My name is \u0026#34;zs\u0026#34;\u0026#34;) #不合法 invalid syntax print(\u0026#34;My name is \\\u0026#34;zs\\\u0026#34;\u0026#34;) #合法 My name is \u0026#34;zs\u0026#34; print(\u0026#39;My name is \u0026#34;zs\u0026#34;\u0026#39;) #合法 My name is \u0026#34;zs\u0026#34; print(\u0026#39;My name is \u0026#39;zs\u0026#39;\u0026#39;) #不合法 invalid syntax print(\u0026#39;My name is \\\u0026#39;zs\\\u0026#39;\u0026#39;) #合法 My name is \u0026#39;zs\u0026#39; Python中也有很多转义字符,跟C++的很类似。\\n,\\t,\\\\ 分别代表换行,横向制表,字符\\ 。在python中还支持用 r' ' 表示 '' 内部的字符默认不转义。\nPython在输出多行语句时,可以用 print('''content''') 其中content中的内容,支持用直觉上的换行。\nprint(\u0026#39;\u0026#39;\u0026#39;python name zs\u0026#39;\u0026#39;\u0026#39;) # The output python name zs 4. 布尔值 含有 Ture 和 False 两种类型,代表真和假。支持 and , or ,not 三种运算。\n5. 空值 空值是Python中的一个特殊值,用 None 表示。 None不能理解为0,因为0是有意义的,而None是一个特殊的空值。\n变量 变量在程序中就是用一个变量名表示了,变量名必须是大小写英文、数字和_的组合,且不能用数字开头。\n变量命名时最好能做到顾名思义,当然也有很多规范的命名规则,可以自行百度。\n在 Python 中我们不需要指定一个变量是特定的类型,它可以在不同的类型之间变来变去,这确实很方便,不过感觉也是很占内存和时间的。\n这种变量本身类型不固定的语言称之为动态语言,与之对应的是静态语言。静态语言在定义变量时必须指定变量类型,如果赋值的时候类型不匹配,就会报错\n常量 Python中没有C++中的const来限制常量,但是通常用变量名全大写来代表这个变量为一个常量,但是这玩意是个约定俗成的,并不是说你这么写他就真是个常量了。\n字符串和编码 字符编码 字符编码有很多种,不同的语言也对应着不同的字符编码。常见的几个是 ASCII ,Unicode ,UTF-8,GB2313 他们分别是英文和特殊字符的编码,统一的一套编码,可变长的统一编码,常用的中文编码。\nPython的字符串存储 Python 3的的字符串是 Unicode 编码的,也就是说Python的字符串支持多语言,因为这是一套统一的编码。\n对于单个字符的编码,Python提供了 Ord() 函数获取字符的整数表示,chr() 函数通过整数获取对应字符。\nPython中的字符串类型为 str ,一个字符对应若干字节。**如果要在网络上传输,或者保存到磁盘上,就需要把str变为以字节为单位的bytes。**Python对bytes类型的数据用带b前缀的单引号或双引号表示。\n我们可以通过encode('编码方式') 将 str 转变成 bytes 。我们也可以通过 decode('编码方式') 将 bytes 转变为 str 。\nPython为我们提供了一个 len() 函数,如果字符串是 str ,那么计算出的是字符数,如果是 bytes ,那么计算的是字节数。我们为了防止乱码问题,在两者相互转换时推荐用 utf-8 编码。\n由于Python源代码也是一个文本文件,所以,当你的源代码中包含中文的时候,在保存源代码时,就需要务必指定保存为UTF-8编码。当Python解释器读取源代码时,为了让它按UTF-8编码读取,我们通常在文件开头写上这两行:\n#!/usr/bin/env python3 # -*- coding: utf-8 -*- 第一行注释是为了告诉Linux/OS X系统,这是一个Python可执行程序,Windows系统会忽略这个注释;\n第二行注释是为了告诉Python解释器,按照UTF-8编码读取源代码,否则,你在源代码中写的中文输出可能会有乱码。而且需要你的编辑器支持 UTF-8编码。\n字符串的格式化输出 第一种方式 Python的 print() 格式化输出和C语言的很像,也是 %d 代表整数,%f 代表浮点数, %s 代表字符串,%s代表十六进制整数。关于格式的指定,好比补0什么的也和C的很像。具体格式如下:\nprint(\u0026#39;%2d-%02d\u0026#39; % (3,1)) # 输出 3-01 print(\u0026#39;my name is %s\u0026#39; % \u0026#34;zs\u0026#34;) # 输出 my name is zs 如果我们要在字符串里面输出 % ,那么就需要用 %% 来转义表示 % 。\nprint(\u0026#34;This is a common %% %s \u0026#34; % \u0026#34;字符\u0026#34;) # 输出 This is a common % 字符 第二种方式 除了上面的方法,print 还可以用 .format 的方法进行格式化输出。例如下例子\nprint(\u0026#39;{0} name is {1}\u0026#39;.format(\u0026#34;who\u0026#34;,\u0026#34;zs\u0026#34;)) #输出 who name is zs List \u0026amp; tuple (列表和元组) List(列表) List像是一个大杂烩,里面可以有各种类型的东西,是一个有序的集合,也就是说可以通过下标索引。\n我们创建一个列表可以用中括号, Mylist = [\u0026quot;zs\u0026quot;,\u0026quot;wx\u0026quot;] ,这就创建了具有两个元素的列表,第一个元素是字符串 zs 第二个元素是字符串 wx 。这个列表的名字就是 Mylist 。\n我们可以通过 len() 来获取列表中元素的个数,也可以通过下表索引列表的元素,但是要注意下标是从0开始计数的,如果索引出界会报 IndexError 。有趣的是,我们可以通过负的下表来访问元素,是倒着访问的,好比上述列表中 Mylist[-1] 就代表元素 \u0026ldquo;wx\u0026rdquo; 。\n我们可以通过 listk = [] ,来创建一个空列表 listk ,如果用 len() 查看长度那么长度为0.\n此外列表中的元素也可以是列表,可以通过类似于二维数组的形式索引。\n列表中,有许多的方法。就像是相对于这个类型内置的一些函数,用法如下:\nMylist = [\u0026#34;zs\u0026#34;,\u0026#34;wx\u0026#34;] print(Mylist) # 输出 [\u0026#39;zs\u0026#39;, \u0026#39;wx\u0026#39;] Mylist.append(\u0026#39;Better\u0026#39;) # 用于在列表后面追加一个元素 print(Mylist) # 输出 [\u0026#39;zs\u0026#39;, \u0026#39;wx\u0026#39;, \u0026#39;Better\u0026#39;] Mylist.insert(1,\u0026#39;Good\u0026#39;) # 用于在下标为1的位置,插入一个元素 print(Mylist) # 输出 [\u0026#39;zs\u0026#39;, \u0026#39;Good\u0026#39;, \u0026#39;wx\u0026#39;, \u0026#39;Better\u0026#39;] popx = Mylist.pop() # 用于删除列表中最后一个元素,并返回元素的值 print(Mylist,popx) # 输出 [\u0026#39;zs\u0026#39;, \u0026#39;Good\u0026#39;, \u0026#39;wx\u0026#39;] Better popx = Mylist.pop(1) # 用于删除列表中下标为1的元素,并返回元素的值 print(Mylist,popx) # 输出 [\u0026#39;zs\u0026#39;, \u0026#39;wx\u0026#39;] Good L = [] # 创建了一个空列表 L print(len(L)) #输出0 Tuple(元组) 元组跟上面的链表差不多,只不过是不可变的,一旦初始化就不能修改,也是可以通过下标访问元素。\n不同的的是,我们定义一个元组是用 () ,好比我们定义 Mytuple = (\u0026quot;zs\u0026quot;,\u0026quot;wx\u0026quot;) ,这是含有两个字符串元素的元组,我们可以通过 Mytuple = () 来定义一个空的元组。\n需要注意的是,当我们定义一个只有一个元素的元组,如果我们写成 Mytuple = (\u0026quot;zs\u0026quot;) ,那么Python会默认解析为这是一个字符串,把括号当初普通的括号,不解释成元组。 那么我们如何定义只有一个元素的元组呢,我们应该写 Mytuple = (\u0026quot;zs\u0026quot;,) 这样就是只有一个元素的元组。\n元组中的不可变,是指它的指向不变,那么如果好比元组的元素中有一个列表,那么其实这个元组中的列表的元素还是可以改变的。\n条件判断 条件判断是一个经典的语句。用于分支结构。\n用法跟C很像,不过 else if 可以缩写为 elif ,并且因为 if ,else , elif 后面接的都是语句块,因此要加 : 。\nweight = 120 if weight\u0026gt;=200: print(\u0026#34;too fat\u0026#34;) elif weight\u0026lt;=100: print(\u0026#34;too thin\u0026#34;) else: print(\u0026#34;Good\u0026#34;) 循环语句 循环结构也是三大结构之一。\nfor for语句是我C++中最喜欢循环语句。在Python中,他的写法变成了 for x in something: ,下面接相应的循环语句块。这个 x 是变量的名字,something 是某一个容器,可以是列表可以是元组啥的,这个写法的意思就是 遍历 something 中的每个元素,带入变量 x 中,执行循环操作。\n我们通常配合 range() 函数来执行循环操作,通过 range(n) 可以生成从 [0,n) 的整数。\nfor x in list(range(11)): print(x) #输出 0~10 while while语句也是和C语言差不多,当型循环,当满足条件时就执行循环,也记住不要忘记加 : 。\nbreak \u0026amp; continue break 的作用是结束整个循环。\ncontinue 的作用是跳过这一次循环。\nDict \u0026amp; Set (字典和集合) Dict 这个字典其实就是C语言中的 map ,人家 Python 直接内置了,属实业界良心。其实就是利用键值对匹配,一个键对应一个值。实现方式为哈希 (Hash) 。\n创建就是 Mydict = {\u0026quot;zs\u0026quot;:250 , \u0026quot;wx\u0026quot;:666} 这样第一个元素的键为 \u0026ldquo;zs\u0026rdquo; ,对应值为 250 。第二个值与这个的解读类似。我们也可以通过类似于数组的形式往字典里面加元素. Mydict[\u0026quot;jjh\u0026quot;] = 100 ,那么这时候就往里面加入了一个键值对。\n字典中每个键值是唯一的,但是值可以相同,类似于函数。我们也可以通过类似于数组的形式,下标为键来访问值。当我们下标在字典中不存在,利用下标访问就会直接报错。Python 为我们提供了另一种方法来满足我们的需求,利用 Mydict.get(键) 可以获得对应的值,当不存在这个键,会返回 None 。此外,我们也可以指定其返回值,Mydict.get(键,something) ,这样当不存在的时候就会返回这个 something 。\n最后,字典中的 Key 只能是不可变对象。\nSet set 就是数学中的集合,具有无序性和唯一性。里面元素不重复,并且无序导致没法通过下标访问。可以用来给一组数据去重。通过 add(key) remove(key) 等函数去除对应值的元素。\n可以通过 \u0026amp; 求交集, | 求并集, - 求差集等。\nset 中的元素也只能是不可变对象。\n函数 调用函数 调用函数的时候要保证参数个数、参数顺序、参数类型满足函数的定义。然后正确的处理好返回值。\n定义函数 函数的定义 普通函数的定义通过 def 来进行,好比我们要写一个求绝对值的函数,那么就可以如下定义\ndef myabs(x): if x\u0026gt;=0: return x else: return -x 这样我们就可以类似调用 myabs(-5) 来获得 -5 的绝对值。\n如果我们想要定义一个空的函数,也就是什么都不做,那么函数内部的语句可以写 pass 。这类似于C++中的分号的作用?大概是。\n通过 函数.__name__ 可以获得函数的真实名字。\n多个返回值的函数 我们可以在 return 后面写多个参数,这样在返回的时候会返回一个元组。我们接受返回值的时候,也可以并拍写多个变量,这样就会把返回值的元组中的各个值依次赋给每个变量。\n函数的参数 Python的函数定义非常简单,但灵活度却非常大。除了正常定义的必选参数外,还可以使用默认参数,可变参数,关键字参数,这使得函数定义出来的接口,不但能处理复杂的参数,还可以简化调用者的代码。\n默认参数 当我们调用一个函数,有几个参数大多数情况下是一个默认的值,少数时候是变的,那么我们可以用到默认参数,默认参数的使用我们可以在那个参数的后面加上 =something ,这意思说是,这个参数默认为 something\ndef poww(x,n=2): k = 1 while n\u0026gt;0: n = n-1 k = k*x return k 例如上面这个例子,我们要求 $2^5$ ,那么可以调用 poww(2,5) 。那么我们如果要求 $2^2$ ,那么就可以直接调用poww(2) ,另一个参数可以不写,那么就是默认的2。\n需要注意的是,必选参数在前,默认参数要在后。否则话会产生歧义,因为解释器不知道你到底传入的参数是默认参数还是必选参数。\n此外,当我们有多个默认参数的时候,我们要在前面几个默认参数使用默认值,而后面那个用传入参数的时候,我们需要加上参数名,也就是 参数名 = value 这样传入。例子如下:\ndef poww(x,n=2,z=3): k = 1 f = n+z while n\u0026gt;0: f = f-1 k = k*x return k 这时候,我们如果要调用 poww(5,4) ,代表求的是 $5^{4+3}$ ,如果我们要求 $5^{2+7}$ ,可以按照如下方法调用,使用 poww(5,z=7) 。\n最后还有一点很重要,默认参数要指向 不变对象 。否则当我们重复调用会发生错误。\n可变参数 我们很多时候可能需要一个函数内传入不定量个数的参数,这就要用到可变参数,可变参数就是数量可变。\n我们很容易想到,可以往里面传列表或者元组 ,不过这样当我们传之前还有要把所有的参数归到一个列表和元素中,这样太麻烦。Python给出了一个简便写法,我们只需要在参数面前加一个 * ,这样我们就可以传入可变个参数。而且调用的时候,按普通的调用方法来即可,不需要传入元组。\ndef test(*numbers): sum = 0 for i in numbers: sum = sum + i*i return sum print(test(1,2,3)) # 输出 14 那么当这时候我们想往里面传一个元组,或者列表。当然可以挨个用数组访问然后写,不过Python也给了我们一个简便做法,只需要在列表或者元组前面加一个 * ,就可以把它结构解开,然后挨个元素传入函数中。\ndef test(*numbers): sum = 0 for i in numbers: sum = sum + i*i return sum Mylist = list(range(5)) print(test(*Mylist)) #输出30 关键词参数 可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。\ndef myfun(**kw): print(kw) myfun(city = \u0026#34;jz\u0026#34;,name = \u0026#34;zs\u0026#34;) # 输出 {\u0026#39;city\u0026#39;: \u0026#39;jz\u0026#39;, \u0026#39;name\u0026#39;: \u0026#39;zs\u0026#39;} Mydict = {\u0026#34;city\u0026#34;:\u0026#34;jz\u0026#34;,\u0026#34;name\u0026#34;:\u0026#34;zs\u0026#34;} myfun(**Mydict) # 输出 {\u0026#39;city\u0026#39;: \u0026#39;jz\u0026#39;, \u0026#39;name\u0026#39;: \u0026#39;zs\u0026#39;} 参数前面加 ** 即是关键词参数。当然我们也可以传入参数时,用dict,然后加 ** 解开结构传入。\n命名关键词参数 我们可以在上述的基础上,传入特定的参数,给相应的参数命名。这需要我们在定义各个参数之前,在参数之前加上 * ,好比 def person(name,age,*,city,job) 规定了,我们传入的两个关键词参数名字只能是 city 和和 job 。不过,当我们前面有一个参数是可变参数,那么就可以不用加那个 * 。好比像如下方法定义上面那个函数, def person(name,age,*city,job) 。在这里 city 是一个可变参数,后面的 job 就是一个命名关键词参数。\n参数调用顺序 在函数的参数中,上述各类参数可以组合使用。但是要注意顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。\n函数的递归调用 函数的递归调用就是自己调用自己,QAQ,C++里面搞得也挺多的,就不赘述了。\n高级特性 切片 切片操作感觉真的是Python很方便的一个特性了。\n字符串,列表,元组支持切片。\n好比我们有一个列表,里面有数,0~100,我们要取其中的奇数,那么我们就需要每隔一个数取一个数,我们可以通过for循环来实现这个操作,但是呢,Python有一种更便利的方法来实现,那就是切片。他的用法类似于matlab中的冒号表达式,begin:end:step 这三个变量分别代表起始,终止和步长,也就是每个多少取一个,这三个参数都可以省略,省略时默认为序列起始点,序列终止点,1。这里要注意,序列范围为 [begin,end) ,前闭后开,例子:\nL = list(range(101)) print(L[1:100:2]) # 输出0~100所有的奇数 print(L[-10::2]) # 从倒数第十个数开始输出奇数,输出 [91, 93, 95, 97, 99] print(L[-50:0:-2]) # 从倒数第50个数,往前开始输出奇数,为 51~0中所有奇数 迭代 迭代就是类似于遍历吧,通过 for 可以迭代遍历一个容器内的所有元素。\n字符串和列表,元组,集合,字典这些都是可以用for遍历的,这也叫做可迭代对象。需要注意的是,我们在遍历字典和集合时,因为是无序的,所以两次遍历顺序可能不太一样。\n当我们遍历字典时,默认遍历的是键值。例如下面这样\nL = {\u0026#34;zs\u0026#34;:\u0026#34;rj\u0026#34;,\u0026#34;jjh\u0026#34;:\u0026#34;nb\u0026#34;} for key in L: print(key) # 输出 zs jjh for value in L.values(): print(value) # 输出 rj nb for k,v in L.items(): print(k,v) # 输出 zs rj jjh nb 可以注意到,可以同时迭代两个数,或者多个数。\n列表生成器 列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。\n好比我们生成 [1*1,2*2,3*3,···,n*n] 这样的列表,可以用循环实现,也可以用列表生成式。\n列表生成式格式大概是 [元素 规则] 就是前面是要往里面加的元素的表达式,后面是生成的规则。\nL = [x*x for x in range(1,11)] print(L) # 输出[1, 4, 9, 16, 25, 36, 49, 64, 81, 100] D = [x*x for x in range(1,11) if x % 2 == 0] print(D) # 输出[4, 16, 36, 64, 100] 生成器 我们将上述列表生成式外面的 [] 改成 () ,就变成了一个列表生成器。列表生成器里面每个元素不是原来就存在的,而是你要用的时候他按照规则去生成,可以节省空间。他也是一个可迭代对象,可以通过for循环来访问,此外也可以用 next(迭代器) 来获取下一个元素。\n除了上述方法,我们也可以用函数的方法来定义生成器,当一个函数中有了关键字 : yield 他就不是一个普通的函数了,就变成了一个生成器,按照函数的规则来生成相应数据。规则如下:当我们进入函数的时候,开始从头开始执行,执行到 yield ,函数结束,返回 yield 后面接的内容。然后下次进入函数的时候,从上次结束的地方继续开始,然后这样一直循环,直到再不能取数为止。\n迭代器 凡是可作用于for循环的对象都是Iterable类型,就是可迭代对象;\n凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列,这感觉就像是一个指针呀其实(自我认为),可以通过指针访问可迭代对象中的元素;\n集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。\nPython的for循环本质上就是通过不断调用next()函数实现的,例如:\nfor x in [1, 2, 3, 4, 5]: pass 实际上完全等价于:\n# 首先获得Iterator对象: it = iter([1, 2, 3, 4, 5]) # 循环: while True: try: # 获得下一个值: x = next(it) except StopIteration: # 遇到StopIteration就退出循环 break 函数式编程 高阶函数 map/reduce map() 函数包括两个参数,第一个参数是一个函数,第二个参数是一个序列。map 的作用就是将序列中的每个元素代入到函数中并且求出每个元素对应的值,然后会返回一个相应的 Iterator ,我们可以通过对应的语句,好比 list() ,tuple() 啥的转成对应的序列。\nreduce() 函数也是包括两个参数,一个是函数,一个是序列。reduce 的作用是类似于一个递归的感觉吧大概,好比序列是 L = [1,2,3,4,5] ,有一个函数是 f ,我们暂且不管这个函数的作用是什么,那么如果我们现在调用 reduce(f,L) ,他返回一个 f 函数的返回值,值为 f(f(f(1,2),3),4) 。就是类似于这种嵌套的结构。\nfilter filter() 函数也包括两个参数,一个是函数,一个是序列。他是通过那个函数的返回值是 True or False 来判断是否保留那个序列中的每个元素。返回值也是 Iterator 。\nsorted sorted() 顾名思义,这是一个排序函数,我们往里面传入一个序列,那么他就会默认的对序列按升序排序,并且返回一个这个排序后序列。但是我们传入的序列不会有变动。\n此外,sorted() 里面还可以加关键词 key 键值来确定规则,好比我们可以加 key=abs 这样就可以将序列中所有的元素按照绝对值从小到大的顺序。我们也可以加 reverse=True 来变成降序排序。\n返回函数 我们知道,函数名只是一个指向函数的变量,我们也可以用另一个变量指向这个函数来引用函数,相当于起了一个别名。因此,我们也可以在函数的返回值中返回一个函数,然后将返回值赋值给一个变量,这样就可以通过这个变量来调用返回的函数。\n我们在一个函数中又定义了一个函数,并且,内部函数可以引用外部函数的参数和局部变量,当外部函数返回内部函数时,相关参数和变量都保存在返回的函数中,这种称为“闭包**(Closure)**”的程序结构拥有极大的威力。\n返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。因为这个变量相当于一个静态变量,现在变了,前面相应的结果也会变。\n返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。\n通过 函数.__name__ 可以获得函数的真实名字。\n匿名函数 通过 lambda 可以创建匿名函数,这个就类似于matlab里面的那个 @ 创建的匿名函数。\n格式为: lambda 变量: 返回值\nprint(list(map(lambda x: x*x,range(1,11)))) # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] 我们也可以把匿名函数当作函数的返回值返回。\n装饰器 我们可能想在调用函数之前在前面打印一下函数的运行日志,或者其他的一些内容,其他的操作。\n这样我们就可以通过装饰器来实现,装饰器是为了给函数加一些其他的修饰,但是不需要在原本函数的基础上做改变。\n本质上,装饰器(decorator) 是一个返回函数的高阶函数,一个能打印日志的 decorator 可以如下定义:\ndef log(func): def wrapper(*args,**kw): print(\u0026#34;call %s()\u0026#34; % func.__name__) return func(*args,**kw) return wrapper 调用如下:\n@log def now(): print(\u0026#39;2020-4-18\u0026#39;) print(now()) # 输出 call now() 2020-4-18 在这里, @log 可以等效为 now = log(now) ,那么我们应该怎么理解呢,首先,在我们调用之前,我们就把这个函数传入这个log函数,然后进入 wrapper 函数,先输出了日志,然后返回了一个 func() 函数,然后结束这个函数的定义,又返回了 wrapper 函数,这样就是将日志和原函数组合在一起了。所以最后一起输出\n偏函数 偏函数可以看做一个函数其中某一个参数固定,然后另成一个新函数,这样到时候我们重复调用的时候就会比较方便了。\n当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单。\n当用 functools.partial 之前我们需要引入 functools 模块。\nimport functools int2 = functools.partial(int,base=2) print(int(\u0026#39;10110\u0026#39;,base=2)) # 以二进制来转化这个字符串,得到22 print(int2(\u0026#39;10110\u0026#39;)) # 和上述等价 模块 这个就是类似于头文件的感觉,模块里面包含了很多别人已经写好了的函数,你引入之后可以直接拿来用,能够大大提高自己的编程效率。\n模块是放在包里的,这样可以避免不同模块之间的冲突,包中可以有很多的模块,并且所有包里都有一个相同名字的模块 , __init__.py ,这个文件说明这个目录是一个包,里面的其他的内容是模块。\n模块命名为 包名.模块名 ,这样就有效避免了模块与模块之间的冲突\n模块是一组Python代码的集合,可以使用其他模块,也可以被其他模块使用。\n创建自己的模块时,要注意:\n模块名要遵循Python变量命名规范,不要使用中文、特殊字符; 模块名不要和系统模块名冲突,最好先查看系统是否已存在该模块,检查方法是在Python交互环境执行import abc,若成功则说明系统存在此模块。 使用模块 在使用模块之前只需要 import 模块名 ,就可以通过 模块名.方法 的方式来调用这个模块里面的方法。\n当我们在命令行运行模块文件时,Python解释器把一个特殊变量__name__置为__main__,而如果在其他地方导入模块时,if判断将失败,因此,这种if测试可以让一个模块通过命令行运行时执行一些额外的代码,最常见的就是运行测试。\n封装 在一个模块中,我们可能会定义很多函数和变量,但有的函数和变量我们希望给别人使用,有的函数和变量我们希望仅仅在模块内部使用。在Python中,是通过_前缀来实现的。\n正常的函数和变量名是公开的(public)。但是外部不需要引用的函数全部定义成private,只有外部需要引用的函数才定义为public。\n安装第三方模块 我们用包管理工具 pip 来安装第三方模块。\n安装一个模块只需要 pip install 库名 ,这样就成功安装了一个包了。\n此外,我们也可以直接安装 Anaconda ,这是一个基于Python的数据处理和科学计算平台,它已经内置了许多非常有用的第三方库,我们装上Anaconda,就相当于把数十个第三方模块自动安装好了,非常简单易用。\n下载地址为 : Anaconda官网\n模块搜索路径 当我们加载一个模块时,Python会在指定路径搜索对应的模块文件,如果找不到就会返回错误。\n默认情况下,Python解释器会搜索当前目录,所有已安装的内置模块和第三方模块,搜索路径存放在 sys 模块的 path 变量中。我们可以通过 sys.path 来查看。\n我们要改动这个目录,往里面添加我们需要的,有两个方法。\n直接通过 sys.path.append() 添加对应的路径,但是运行结束后会失效。 设置环境变量PYTHONPATH,该环境变量的内容会被自动添加到模块搜索路径中。设置方式与设置Path环境变量类似。注意只需要添加你自己的搜索路径,Python自己本身的搜索路径不受影响。 资料补充 廖雪峰的Python教程 Anaconda介绍、安装及使用教程 ","permalink":"https://blog.zzsqwq.cn/posts/66/","summary":"\u003ch1 id=\"python学习笔记\"\u003ePython学习笔记\u003c/h1\u003e\n\u003ch2 id=\"python的不同解释器\"\u003ePython的不同解释器\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eCPython\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e这是自带的用C语言开发的解释器,因此叫CPython。它也是使用最广的Python解释器。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eIPython\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e这是基于CPython之上的一个交互式解释器,只是相比于CPython多了交互上的优化。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003ePyPy\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e它的目标是执行速度。PyPy采用\u003ca href=\"http://en.wikipedia.org/wiki/Just-in-time_compilation\"\u003eJIT技术\u003c/a\u003e,对Python代码进行动态编译(注意不是解释),所以可以显著提高Python代码的执行速度。他与CPython略有不同。\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e","title":"Python初步学习"},{"content":"C++大数类设计思路 洛谷大数类的评测结果(开了氧气优化) 这个第四个点真的优化不过去了QAQ,24W的数据,丧心病狂\n整体构思 构造大数类名为 BigNumber ,首先想法是用字符串读入大数,然后将其转化为vector数组倒序分位存储的整数,然后通过一个 len 来记录数字的位数,便于做运算。还设计了一个标记变量,用于标记这数为正数还是负数。\n构造函数 我用了两种构造函数,一个是无参构造函数,一个是拷贝构造函数,当然还有一个有参构造函数,但是实际过程中我没有用到。无参构造函数用于上述类成员的初始化,拷贝构造函数用于复制一个相同的大数类进行运算。有参构造函数可以用于对类成员的复制。\n重载运算符 重载 \u0026ldquo;+\u0026rdquo; 首先在类中进行了声明, BigNumber operator + (const BigNumber \u0026amp;b); ,用当前类 *this 来和引入的类 b 进行加法运算,返回值为一个 BigNumber 类。 在类的外部进行重载的定义,先将用拷贝构造函数将当前的类 *this 拷贝为 a ,然后对 a 和 b 进行加法运算,模拟竖式,对应位相加,大于10则进位,最后去掉尾部的 0 即可。 BigNumber BigNumber::operator + (const BigNumber \u0026amp;b) //重载 \u0026#34;+\u0026#34; 定义 { BigNumber Result; BigNumber a(*this); Result.len = max(a.len,b.len)+1; int add=0; for(int i=0;i\u0026lt;Result.len||add!=0;i++) { int p=add; if(i\u0026lt;a.len) p+=a.v[i]; if(i\u0026lt;b.len) p+=b.v[i]; add=p/10; Result.v.push_back(p%10); } while(Result.v[Result.v.size()-1]==0 \u0026amp;\u0026amp; Result.v.size() \u0026gt; 1) { Result.v.pop_back(); } Result.len=Result.v.size(); return Result; } 重载 \u0026ldquo;\u0026lt;\u0026rdquo; 因为进行减法前需要比较两个大数类的大小,我就先重载了 \u0026lt; 。思路就是先比较a、b两个大数的长度,长的那个肯定比较大,如果两个长度相等。从尾部开始依次向前比较,如果不相等的话,就看两个数的相对大小,大的那个肯定整体比较大。如果总是相等,到了最后,就返回相应的值表示他们相等。这里我的返回值为int类型,用的标记是:如果两个相等,返回-1,如果前者小于后者,返回1,如果前者大于后者,返回0.\nint BigNumber::operator \u0026lt; (const BigNumber \u0026amp;b) // 重载 \u0026#34;\u0026lt;\u0026#34; 定义 { BigNumber a(*this); if(a.len \u0026lt; b.len) return 1; if(a.len \u0026gt; b.len) return 0; for(int i=a.len-1;i\u0026gt;=0;i--) { if(a.v[i]!=b.v[i]) { return a.v[i] \u0026lt; b.v[i]; } } return -1; } 重载 \u0026ldquo;-\u0026rdquo; 首先在类中进行了声明, BigNumber operator - (BigNumber \u0026amp;b); ,用当前类 *this 来和引入的类 b 进行减法运算,返回值为一个 BigNumber 类。 在类的外部进行重载的定义,先将用拷贝构造函数将当前的类 *this 拷贝为 a ,然后对 a 和 b 进行减法运算。如果 a\u0026lt;b ,那么我们就把 flag 设为 true ,标志得数为一个负数,然后用 swap 交换两个类,保证总是大数减小数。减法的话就是从前往后扫,对应位相减,如果不够减的就进行借位。如果借完位当前位置小于0了,那么就再向前借位。最后要去掉结尾多于的0. BigNumber BigNumber::operator - (BigNumber \u0026amp;b) // 重载 \u0026#34;-\u0026#34; 定义 { BigNumber Result; BigNumber a(*this); if(a\u0026lt;b==1) { swap(a,b); Result.flag=true; } Result.len=a.len; for(int i=0;i\u0026lt;a.len;i++) { if(a.v[i]\u0026lt;0) { a.v[i]+=10; a.v[i+1]--; } if(a.v[i] \u0026lt; b.v[i]\u0026amp;\u0026amp;i\u0026lt;b.len) { a.v[i]+=10; a.v[i+1]--; } if(i\u0026lt;b.len) Result.v.push_back(a.v[i]-b.v[i]); else Result.v.push_back(a.v[i]); } while(Result.v[Result.len-1]==0 \u0026amp;\u0026amp; Result.len \u0026gt; 1) { Result.v.pop_back(); Result.len--; } return Result; } 重载 \u0026ldquo;*\u0026rdquo; 首先在类中进行了声明, BigNumber operator * (BigNumber \u0026amp;b);,用当前类 *this 来和引入的类 b 进行乘法运算,返回值为一个 BigNumber 类。 在类的外部进行重载的定义,先将用拷贝构造函数将当前的类 *this 拷贝为 a ,然后对 a 和 b 进行乘法运算。乘法也是模拟竖式运算,两个位数相乘对应的得数中的哪一位不难发现,因此只需要边乘边进位即可,一开始想的是所有乘完之后再进位,后来想了想运算的次序不会影响除和模的运算,所以就可以边乘边取商和模,可以少掉两层循环。算是一个小小的优化。最后要去掉结尾多于的0. BigNumber BigNumber::operator * (BigNumber \u0026amp;b) // 重载 \u0026#34;*\u0026#34; 定义 { BigNumber Result; BigNumber a(*this); Result.len=a.len+b.len; for(int i=0;i\u0026lt;Result.len;i++) Result.v.push_back(0); for(int i=0;i\u0026lt;a.len;i++) { for(int j=0;j\u0026lt;b.len;j++) { Result.v[i+j]+=a.v[i]*b.v[j]; Result.v[i+j+1]+=Result.v[i+j]/10; Result.v[i+j]%=10; } } while(Result.v[Result.v.size()-1]==0 \u0026amp;\u0026amp; Result.v.size() \u0026gt; 1) { Result.v.pop_back(); } Result.len=Result.v.size(); return Result; } 重载 \u0026ldquo;/\u0026rdquo; 首先在类中进行了声明,BigNumber operator / (BigNumber \u0026amp;b);,用当前类 *this 来和引入的类 b 进行除法运算,返回值为一个 BigNumber 类。\n在类的外部进行重载的定义,先将用拷贝构造函数将当前的类 *this 拷贝为 a ,然后对 a 和 b 进行除法法运算。我选择了做除法的时候大数类中同时存储商和余数,这样可以加快效率,因为我自己的想法是把除法和取模一起处理,求得商的同时,模也能求出来。因此他们的框架肯定是相差无几的,所以我选择了一次性算出来两个,在大数类中用两个vector数组分别存商和余数,求商和余数我用的是减法的策略,分下面三种情况来讨论\na\u0026lt;b :很显然商为0,余数为a。 a==b :很显然商为1,余数为0。 a\u0026gt;b :这个是最难处理的,我们想想一下模拟除法的竖式运算,先在b的后面填0,让a和b的位数相同,然后再一直对a进行减法运算,将得到的数排列起来即可。里面细节还是挺多的,具体的看代码。最后要去掉结尾多于的0. BigNumber BigNumber::operator / (BigNumber \u0026amp;b) // 重载 \u0026#34;/\u0026#34; 定义 { BigNumber Result; BigNumber a(*this); if(a\u0026lt;b==1) { Result.v.push_back(0); for(int i=0;i\u0026lt;a.v.size();i++) { Result.m.push_back(a.v[i]); } return Result; } if(a\u0026lt;b==-1) { Result.v.push_back(1); Result.m.push_back(0); Result.len=1; } if(a\u0026lt;b==0) { int size = a.len-b.len; for(int i=size;i\u0026gt;=0;i--) { BigNumber p(b); int cnt=0; for(int j=1;j\u0026lt;=i;j++) { p.v.insert(p.v.begin(),0); } p.len = p.v.size(); while((a-p).flag==false) { a=a-p; cnt++; } if(i==size) { for(int j=1;j\u0026lt;=size;j++) { Result.v.push_back(0); } Result.v.push_back(cnt); } else { Result.v[i] = cnt; } } while(Result.v[Result.v.size()-1]==0 \u0026amp;\u0026amp; Result.v.size() \u0026gt; 1) { Result.v.pop_back(); } Result.len=Result.v.size(); for(int i=0;i\u0026lt;a.v.size();i++) { Result.m.push_back(a.v[i]); } } return Result; } 重载 \u0026ldquo;%\u0026rdquo; 这个和除法的类似,我们除法的其实已经求出来模了,这个只是象征性的搞一搞。QAQ。\nBigNumber BigNumber::operator % (BigNumber \u0026amp;b) //重载 \u0026#34;%\u0026#34; 定义 { BigNumber Result; BigNumber a(*this); if(a\u0026lt;b) { Result.v.push_back(0); return Result; } else { int size = a.len-b.len; for(int i=size;i\u0026gt;=0;i--) { BigNumber p(b); for(int j=1;j\u0026lt;=i;j++) { p.v.insert(p.v.begin(),0); } p.len = p.v.size(); while((a-p).flag==false) { a=a-p; } } for(int i=0;i\u0026lt;a.v.size();i++) { Result.v.push_back(a.v[i]); } } return Result; } 其中遇到的问题 在做减法的时候,会出现莫名奇怪的数据,后来发现是由于访问b数组的时候越界,而且vector数组的clear只是将数组的size置为了0,而不是将所有数据都莫抹除,而且vector通过下标访问越界还不会报错,我整个人都傻了,调了巨长时间。 在做除法的时候,一度自闭。本来是只是一直减,这样效率真的巨tm慢。后来想到了用这个办法好像可以优化到 log 级别的,但是好难调试啊。。从昨天下午一直搞到现在。 因为swap这个东西,好像会影响到类的源数据,所以我就多定义了几个数,分别对他们进行操作,这样就不会相互影响,虽然看起来挺丑的。 整体的代码实现 /* Name: BigNumber Class Copyright: Zs Author: Zs Date: 04/04/20 09:08 Description: A BigNumber Class */ #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; #include\u0026lt;vector\u0026gt; using namespace std; class BigNumber { private: vector\u0026lt;int\u0026gt; v; // 和,差,积,商 vector\u0026lt;int\u0026gt; m; // 余数,当无余数的时候 size 为0 int len; // 数字的长度 = v.size() bool flag; //是否为负数的标志 public: BigNumber();//无参构造函数 BigNumber(string s) //带参数的构造函数 { *this=s; } BigNumber(const BigNumber \u0026amp;); // 拷贝构造函数 BigNumber operator = (const string s); // 重载 \u0026#34;=\u0026#34; 声明 BigNumber operator = (int k); // 重载输入的数为整型的时候的 \u0026#34;=\u0026#34; 声明 int operator \u0026lt; (const BigNumber \u0026amp;b); // 重载 \u0026#34;\u0026lt;\u0026#34; 声明 BigNumber operator + (const BigNumber \u0026amp;b); // 重载 \u0026#34;+\u0026#34; 声明 BigNumber operator - (BigNumber \u0026amp;b); // 重载 \u0026#34;-\u0026#34; 声明 BigNumber operator * (BigNumber \u0026amp;b); // 重载 \u0026#34;*\u0026#34; 声明 BigNumber operator / (BigNumber \u0026amp;b); //重载 \u0026#34;/\u0026#34; 声明 BigNumber operator % (BigNumber \u0026amp;b); //重载 \u0026#34;%\u0026#34; 声明 void print() //输出函数 { if(flag) { printf(\u0026#34;-\u0026#34;); flag=false; } for(int i=v.size()-1;i\u0026gt;=0;i--) printf(\u0026#34;%d\u0026#34;,v[i]); printf(\u0026#34;\\n\u0026#34;); for(int i=m.size()-1;i\u0026gt;=0;i--) printf(\u0026#34;%d\u0026#34;,m[i]); } }; BigNumber::BigNumber() //无参构造函数 { v.clear(); m.clear(); len = 0; flag=false; } BigNumber::BigNumber(const BigNumber \u0026amp;T) // 拷贝构造函数 { v.assign(T.v.begin(),T.v.end()); len = T.len; flag = T.flag; } BigNumber BigNumber::operator = (const string s) // 重载 \u0026#34;=\u0026#34; 定义 { len = s.length(); for(int i=0;i\u0026lt;len;i++) { v.push_back(s[len-1-i]-\u0026#39;0\u0026#39;); } return *this; } BigNumber BigNumber::operator = (int k) // 重载输入的数为整型的时候的 \u0026#34;=\u0026#34; 定义 { while(k) { v.push_back(k%10); k/=10; len++; } len--; return *this; } int BigNumber::operator \u0026lt; (const BigNumber \u0026amp;b) // 重载 \u0026#34;\u0026lt;\u0026#34; 定义 { BigNumber a(*this); if(a.len \u0026lt; b.len) return 1; if(a.len \u0026gt; b.len) return 0; for(int i=a.len-1;i\u0026gt;=0;i--) { if(a.v[i]!=b.v[i]) { return a.v[i] \u0026lt; b.v[i]; } } return -1; } BigNumber BigNumber::operator + (const BigNumber \u0026amp;b) //重载 \u0026#34;+\u0026#34; 定义 { BigNumber Result; BigNumber a(*this); Result.len = max(a.len,b.len)+1; int add=0; for(int i=0;i\u0026lt;Result.len||add!=0;i++) { int p=add; if(i\u0026lt;a.len) p+=a.v[i]; if(i\u0026lt;b.len) p+=b.v[i]; add=p/10; Result.v.push_back(p%10); } while(Result.v[Result.v.size()-1]==0 \u0026amp;\u0026amp; Result.v.size() \u0026gt; 1) { Result.v.pop_back(); } Result.len=Result.v.size(); return Result; } BigNumber BigNumber::operator - (BigNumber \u0026amp;b) // 重载 \u0026#34;-\u0026#34; 定义 { BigNumber Result; BigNumber a(*this); if(a\u0026lt;b==1) { swap(a,b); Result.flag=true; } Result.len=a.len; for(int i=0;i\u0026lt;a.len;i++) { if(a.v[i]\u0026lt;0) { a.v[i]+=10; a.v[i+1]--; } if(a.v[i] \u0026lt; b.v[i]\u0026amp;\u0026amp;i\u0026lt;b.len) { a.v[i]+=10; a.v[i+1]--; } if(i\u0026lt;b.len) Result.v.push_back(a.v[i]-b.v[i]); else Result.v.push_back(a.v[i]); } while(Result.v[Result.len-1]==0 \u0026amp;\u0026amp; Result.len \u0026gt; 1) { Result.v.pop_back(); Result.len--; } return Result; } BigNumber BigNumber::operator * (BigNumber \u0026amp;b) // 重载 \u0026#34;*\u0026#34; 定义 { BigNumber Result; BigNumber a(*this); Result.len=a.len+b.len; for(int i=0;i\u0026lt;Result.len;i++) Result.v.push_back(0); for(int i=0;i\u0026lt;a.len;i++) { for(int j=0;j\u0026lt;b.len;j++) { Result.v[i+j]+=a.v[i]*b.v[j]; Result.v[i+j+1]+=Result.v[i+j]/10; Result.v[i+j]%=10; } } while(Result.v[Result.v.size()-1]==0 \u0026amp;\u0026amp; Result.v.size() \u0026gt; 1) { Result.v.pop_back(); } Result.len=Result.v.size(); return Result; } BigNumber BigNumber::operator / (BigNumber \u0026amp;b) // 重载 \u0026#34;/\u0026#34; 定义 { BigNumber Result; BigNumber a(*this); if(a\u0026lt;b==1) { Result.v.push_back(0); for(int i=0;i\u0026lt;a.v.size();i++) { Result.m.push_back(a.v[i]); } return Result; } if(a\u0026lt;b==-1) { Result.v.push_back(1); Result.m.push_back(0); Result.len=1; } if(a\u0026lt;b==0) { int size = a.len-b.len; for(int i=size;i\u0026gt;=0;i--) { BigNumber p(b); int cnt=0; for(int j=1;j\u0026lt;=i;j++) { p.v.insert(p.v.begin(),0); } p.len = p.v.size(); while((a-p).flag==false) { a=a-p; cnt++; } if(i==size) { for(int j=1;j\u0026lt;=size;j++) { Result.v.push_back(0); } Result.v.push_back(cnt); } else { Result.v[i] = cnt; } } while(Result.v[Result.v.size()-1]==0 \u0026amp;\u0026amp; Result.v.size() \u0026gt; 1) { Result.v.pop_back(); } Result.len=Result.v.size(); for(int i=0;i\u0026lt;a.v.size();i++) { Result.m.push_back(a.v[i]); } } return Result; } BigNumber BigNumber::operator % (BigNumber \u0026amp;b) //重载 \u0026#34;%\u0026#34; 定义 { BigNumber Result; BigNumber a(*this); if(a\u0026lt;b) { Result.v.push_back(0); return Result; } else { int size = a.len-b.len; for(int i=size;i\u0026gt;=0;i--) { BigNumber p(b); for(int j=1;j\u0026lt;=i;j++) { p.v.insert(p.v.begin(),0); } p.len = p.v.size(); while((a-p).flag==false) { a=a-p; } } for(int i=0;i\u0026lt;a.v.size();i++) { Result.v.push_back(a.v[i]); } } return Result; } int main() { //\tfreopen(\u0026#34;test.in\u0026#34;,\u0026#34;r\u0026#34;,stdin); //\tfreopen(\u0026#34;test.out\u0026#34;,\u0026#34;w\u0026#34;,stdout); string s1,s2; cin\u0026gt;\u0026gt;s1\u0026gt;\u0026gt;s2; BigNumber a,b,c,e,f,k,j; a=s1,b=s2; e=s1,f=s2; k=s1,j=s2; c=a+b; c.print(); c=a-b; c.print(); c=k*j; c.print(); c=e%f; c.print(); return 0; } ","permalink":"https://blog.zzsqwq.cn/posts/64/","summary":"\u003ch1 id=\"c大数类设计思路\"\u003eC++大数类设计思路\u003c/h1\u003e\n\u003ch3 id=\"洛谷大数类httpswwwluogucomcnproblemu111551的评测结果开了氧气优化\"\u003e\u003ca href=\"https://www.luogu.com.cn/problem/U111551\"\u003e洛谷大数类\u003c/a\u003e的评测结果(开了氧气优化)\u003c/h3\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"https://blog.zzsqwq.cn/usr/uploads/2020/08/4200651250.png\" alt=\"BigNumber.png\" /\u003e\n\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e这个第四个点真的优化不过去了QAQ,24W的数据,\u003cdel\u003e丧心病狂\u003c/del\u003e\u003c/strong\u003e\u003c/p\u003e","title":"C++大数类的实现"},{"content":"Linux系统常见命令 基本操作 **cd (Change Directory)**命令:跳转目录\ncd path : path为路径,进入相应目录 cd # 或 cd ~ :回到主目录 cd - : 回到上次所在目录 cd !$ :将上个命令的参数做为输入 cd .. :回到上层目录 ls (List) 命令:列出当前目录文件\nls : 显示当前目录文件\nls -a:显示全部的文件及文件夹,包括隐藏的文件和文件夹。\nls -l : 显示较全的文件信息,包括权限,用户,用户组。\nTab 键:通过按Tab可以进行自动补全。如果当前目录有前缀相同的文件,则按两下Tab可以显示出所有以具有该前缀的文件。\nmv (Move) 命令:移动(剪切)文件,也可以用作一个等效给文件或目录的重命名。\n通过 mv 文件x 目录a 可以将当前目录下的文件x移入目录k。\ncp (Copy) 命令:拷贝,将一个文件或目录拷贝到另一个文件或目录。\n通过 cp [options] 文件x 目录a 可以将当前目录下的文件x复制到目录a。\n-a:此选项通常在复制目录时使用,它保留链接、文件属性,并复制目录下的所有内容。其作用等于dpR参数组合。 -d:复制时保留链接。这里所说的链接相当于Windows系统中的快捷方式。\n-f:覆盖已经存在的目标文件而不给出提示。 -i:与-f选项相反,在覆盖目标文件之前给出提示,要求用户确认是否覆盖,回答\u0026quot;y\u0026quot;时目标文件将被覆盖。\n-p:除复制文件的内容外,还把修改时间和访问权限也复制到新文件中。 -r:若给出的源文件是一个目录文件,此时将复制该目录下所有的子目录和文件。\n-l:不复制文件,只是生成链接文件。 pwd(Print Working Directory) 命令:打印出当前工作目录\nmkdir 命令 : mkdir name创建一个名为name的文件夹\nrm (Remove) 命令 :删除文件,删除文件后不可恢复。特殊的 ,**rmdir ** 为删除文件夹命令,rm -r是先删除目录内的内容,再删除目录。 rm -i 为交互式进行删除,一个个确定。rm -f 为强制删除(慎用)。\ngedit 命令:gedit path 打开编辑某个文件。path为绝对路径或相对路径。\ntouch 命令:touch name 创建一个文件,name包含拓展名。\ncat 命令:打开指定文件, 并显示其中内容在终端,并且可以将其复制到一个另文件中。如果cat后面加多个文件名,那么就会打开多个文件。\ntar 命令:压缩或解压命令。tar [参数] 打包文件名 要打包的各个文件 。\n参数表:\n参数 含义 -c 生成档案文件,创建打包文件 -v 列出归档解档的详细过程,显示进度 -f 指定档案文件名称,f后面一定是.tar文件,所以放选项最后 -t 列出档案中包含的文件 -x 解开档案文件 打包实例: tar -cvf 文件名 要打包的文件 解压实例:tar -xvf 压缩包名\n不同的查找方式 find :使用方法为find \u0026lt;指定目录\u0026gt;\u0026lt;指定条件\u0026gt;\u0026lt;指定动作\u0026gt; ,如何find后面不加任何参数,那么就默认搜索当前目录及其子目录,并显示在屏幕上。\n\u0026lt;指定目录\u0026gt;:用于指定要搜索的目录,默认为当前所在目录。\n\u0026lt;指定条件\u0026gt;:指定所要搜索文件的特征。\n-name :按文件名查找 -perm:按文件权限查找 -depth:查找时先在当前目录查找,然后查找其他子目录。 -prune:不在当前指定路径查找。如果同时指定-depth,则此选项被忽略。 -user/-nouser:按照文件属主查找/查找无效属主文件 -group/-nogroup:按照文件属组查找/查找无效属组文件 -newer file1 !file2:查找更改时间比file1新比file2旧的文件。 -type:查找某一类型文件,b:块设备文件,d:目录,c:字符设备文件,P:管道文件,l:符号链接文件,f:普通文件。 locate :等价于 find -name ,但是速度要快,因为locate在一个本地数据库中存放了所有本地文件信息,每天自动更新,我们查找之前需要通过 updatedb 手动更新其中内容,不然可能会导致新改动的文件查找不到。\nwhereis :whereis可以用于程序名的搜索,可以通过参数 -s,-m,-s 分别搜索二进制文件,man说明文件,和源代码文件。如果省略参数,则返回所有信息。不过这个也是从本地数据库里面进行搜索。\nwhich :只能用于寻找可执行文件,并通过path变量寻找。\n关于查找方式的总结,find命令非常强大,搜索全盘,而且可以配合多种参数进行各种各样的搜索。 而locate能做到搜索的更快,因为一种特殊的搜索位置,但是功能要略逊于find。whereis和which都是对于指定类型的搜索,专精某一方面。\n软链接和硬链接 首先我了解到,linux文件系统中,每一个文件都会有一个编号,称为索引节点号inode。也就是i节点。\n链接呢,我的感觉就是,建立一个源文件和链接文件的映射,两个之间会有一定的关系存在。\n创建链接的方式为 ln 源文件 目标文件 ,默认为硬链接,软链接为 ln -s 源文件 目标文件 。\n对于软链接,很像快捷方式,可以跨文件系统(也就是说可以存在于不同的文件系统中),而且他有一个单独的inode,然后通过软连接可以打开源文件。\n对于硬链接,就像是整了一个毛一样的东西出来,很像备份吧,而且两者名字可不同,他们的inode是同一个,只是把inode link count 域增加了1,也就是多了加了一个索引项,因为他们是一毛一样的东西,那么就肯定不能跨文件系统了,因为你这个东西在这个文件系统里面是代表这个东西,在另一个里面就不一定是了,会产生错误。\n关于他们的几点其他区别如下\n软链接可以对一个不存在的文件名进行链接,如果用编辑器打开这个目标文件,那么会默认创建一个名为filename的文件,而硬链接肯定不行了,因为你文件不存在,他也就没有inode,无从创建链接。\n软链接可以跨文件系统,硬链接不行。\n软链接可以链接目录,硬链接不行。百度了解到,因为硬链接和源文件用的一个inode,用硬链接链接可以会形成循环依赖,导致系统死机。\n硬链接在源文件删除后依然可以访问,因为它具有源文件的inode,而软链接在源文件删除后无法对源文件进行访问,因为inode没有了,索引不到了。\n我们对硬链接文件中的内容进行修改也会影响到源文件,因为他们是同一个文件。当然软链接也可以,因为他就是相当于打开了源文件。\n其他常见操作\n新建一个用户:通过sudo useradd -m name 会创建一个名为name的用户,看/home文件下会显示名为name的用户,可以通过 sudo passwd name 来为用户设置密码,通过su name来切换用户,如果想要删除则通过sudo userdel [-r] name 来删除,加上-r代表删除对应文件夹。我们可以通过命令来查看etc中的passwd文件,就能够看到是否创建成功。\n权限的修改:我们可以通过sudo gedit /etc/sudoers 打开sudoers文件修改 # User privilege specification 下的目录,添加\u0026lt;用户名\u0026gt; ALL=(ALL:ALL) ALL 来为用户添加sudo权限。\n连接网络\n无线网 nmcli dev wifi 查看可连接的无线网络 nmcli dev wifi connect name password password name为对应的wifi名称,而后面的password则是对应的密码。 有线网拨号上网 sudo ifconfig eth0 down/up 为关闭或者开启网卡驱动。 sudo pppoeconf 建立拨号连接,对于有线网卡输入 sudo pppoeconf eth0 然后输入拨号的用户名以及密码即可连接到网络。 sudo和su一些区别\nsu(substitute user):切换用户。 sudo:sudo是通过另一个用户来执行命令,也就是说一个命令需要root权限,你并不需要直接跑到root用户下执行,只需要通过sudo然后输入root的密码即可执行相应的命令。 apt-get\napt-get,是一条linux命令,适用于deb包管理式的操作系统,主要用于自动从互联网的软件仓库中搜索、安装、升级、卸载软件或操作系统。通常搭配sudo命令使用。 Vim的常用操作 首先通过 sudo apt-get install vim 来安装Vim 通过 vim name 来编辑name这个文件,如果不存在那么就会创建一个。\nVim的使用\nVim分为了三种模式,分别是命令模式(Command mode),输入模式(Insert mode),底线命令模式(Last line mode)。\n命令模式\n我们刚进入vim就是进入了命令模式,可以通过输入 i或a或o 来切换到输入模式,也可以通过输入x来删除当前光标后的字符,还有一系列操作可以进行,也可以输入 : 来进入底线命令模式。\n一些常用命令\n/word 或 ?word :向光标之下 / 光标之上搜索word这个字符串。 n / N :继续上一个搜索操作 / 进行与上一个搜索操作相反的搜索 ZZ :按两下大写的Z,那么就是直接保存后离开。 输入模式\n输入模式也就是对文本进行编辑,和普通的类似。里面好像有挺多快捷键的,可以通过Page Up/Page Down 来上下翻页,可以通过 HOME/END 来将光标移到行首/行尾。通过 Insert 可以将光标切换为输入/替换模式,光标相应的变为竖线/下划线。通过 Esc 可以退出输入模式,切换到命令模式。\n底线命令模式\n输入 :命令 可以执行非常多的操作,一些常用命令如下。\n:set nu / :set nonu : 设置行号,取消行号。 :n1,n2s/word1/word2/g :将n1~n2行中所有的word1替换为word2,g后加c则每次替换前需要用户手动确认,如果加上i则忽略大小写。 :1,$s/word1/word2/g 或 $s/word1/word2/g :将第一行到最后一行中的word1替换为word2,g后加 c 则每次替换前需要用户确认,如果加上 i (ignore) 则忽略大小写。 :w / :w! :分别为保存,强制保存。 :q / :q! :分别为离开vim,强制离开vim,后者是不需要保存的时候可以选择直接退出。 :wq / :wq! : 分别为存储后离开,强制存储后离开,我们发现加个叹号!一般就是强制的意思。 :w [filename] :将文本保存成一个叫filename的文件,类似于另存为。 :r [filename] :将文本文件filename读入写在光标之后。 :n1,n2 w filename :将文本n1~n2行保存在的filename中(新建一个文件保存)。 :! command :暂时离开vim到终端中 ","permalink":"https://blog.zzsqwq.cn/posts/63/","summary":"\u003ch2 id=\"linux系统常见命令\"\u003eLinux系统常见命令\u003c/h2\u003e\n\u003ch3 id=\"基本操作\"\u003e基本操作\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e**cd (Change Directory)**命令:跳转目录\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003ecd path\u003c/strong\u003e : path为路径,进入相应目录\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003ecd #\u003c/strong\u003e 或 \u003cstrong\u003ecd ~\u003c/strong\u003e :回到主目录\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003ecd -\u003c/strong\u003e : 回到上次所在目录\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003ecd !$\u003c/strong\u003e :将上个命令的参数做为输入\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003ecd ..\u003c/strong\u003e :回到上层目录\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"https://blog.zzsqwq.cn/usr/uploads/2020/08/1228769729.png\" alt=\"image-20200330164354765.png\" /\u003e\n\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e","title":"Linux和Vim入门"},{"content":"4.1 二维曲线 plot函数 基本用法:plot(x,y) ,x和y分别代表横纵坐标,plot函数会将各个点连接起来,形成线,x和y一般为长度相等的向量。 最简单的调用格式:plot(x) 当x为实向量时,则以该元素下表为横坐标,元素的值为纵坐标绘制曲线。 当x为复向量时,则以实部和虚部分别为横纵坐标绘制曲线。 plot(x,y)函数参数的变化形式 当x为向量,y为矩阵:这时x的长度和y的列数(或行数)必须相等。这时候绘制多条曲线,分别是x为横坐标,取与x长度相等的那一个参数作为纵坐标,另一个参数为曲线的条数。如果y的行、列两个参数相等,那么用y的每一列作为纵坐标,曲线条数等于矩阵列数。 当x和y为同型矩阵:这时以x,y对应列元素为横、纵坐标绘制曲线,曲线条数等于矩阵列数。 含多个输入参数:形如 plot(x1,y1,x2,y2,···,xn,yn) ,那么就是以每一个向量对组成一个点,绘制曲线。 含选项的plot函数,plot(x,y,选项) 线型 :通过\u0026quot;-\u0026quot;,\u0026quot;:\u0026quot;,\u0026quot;-.\u0026quot;,\u0026quot;--\u0026quot; 等参数来实现实线,虚线,点画线,双画线。 颜色 :通过 \u0026quot;r\u0026quot;,\u0026quot;g\u0026quot; 等实现曲线颜色的切换。当颜色选项省略,绘图自动循环使用。 数据点标记 :通过 \u0026quot;*\u0026quot;,\u0026quot;o\u0026quot;,\u0026quot;s\u0026quot; 等来实现将数据点用星号,圆圈,方块标记。 fplot函数 可根据参数函数的变化特性自适应地设置采样间隔,当函数值变化缓慢,采样间隔大,当变化快的时候,采样间隔小。\n基本用法:fplot(f,lims,选项) ,参数分别函数(一般采用函数句柄表示),lims为x轴的取值范围,采用二元向量 [xmin,xmax] 来表示,默认值为 [-5,5] 。选项参数与plot函数相同。\n双输入参数函数的用法:fplot(funx,funy,tlims,选项) ,前两个分别为x,y的参数表示,通常以函数句柄的形式给出。tlims为前方函数参数 t 的取值范围,用二元向量 [tmin,tmax] 表示,默认的值为 [-5,5] ,选项参数与上述相同。\n例程 利用不同的线型和颜色在同一坐标内绘制曲线 $y=2e^{-0.5x}sin(2\\pi x)$ 以及其包络线。(包络线:在几何学,某个曲线族的包络线(Envelope),是跟该曲线族的每条线都有至少一点相切的一条曲线。) x=(0:pi/50:2*pi)\u0026#39;; y1=2*exp(-0.5*x)*[1,-1]; %这里绘制的是上下两条包络线,是有两行的矩阵。 y2=2*exp(-0.5*x).*sin(2*pi*x); %这里绘制的是曲线本身 x1=0:0.5:6; y3=2*exp(-0.5*x1).*sin(2*pi*x1); %这里标记的是正弦函数和x轴的交点。 plot(x, y1, \u0026#39;k:\u0026#39;, x, y2, \u0026#39;b--\u0026#39;, x1, y3, \u0026#39;rp\u0026#39;) 利用fplot函数绘制 $y=sin{\\frac{1}{x}}$ 在区间 $[0,0.2]$ 的图像。 fplot(@x sin(1./x),[0,0.2]) 4.2 绘制图形的辅助操作 添加图形标注 title函数:用于给图形添加标题说明\n基本用法:title('图形标题') ,如果是有多行,就用逗号分隔,大括号{}括起来。 LaTeX排版:可在在图形标题中使用LaTeX格式控制符,要用LaTeX时将其控制字符用大括号{}括起来。 控制字体:用 \u0026quot;\\bf\u0026quot; ,\u0026quot;\\it\u0026quot;,\u0026quot;\\rm\u0026quot; 分别控制字体加粗,斜体以及正体。 设置title函数属性 : title(图形标题,属性名,属性值) 其中属性名和属性值对应成对出现。 Color属性:用于设置图形标题文本的颜色,缺省时为黑色。 FontSize属性 :用于设置标题文字字号,缺省时为11。 xlable和ylable函数:给x轴和y轴添加说明\n基本用法: xlable(x轴说明) ,ylable(y轴说明) ,同样还有 zlable等。 text函数和gtext函数:给特定位置说明\n基本用法: text(x,y,说明),x、y参数用来指明说明的位置,后面的说明和title函数类似。 gtext(说明) 这里没有坐标指定位置,通过鼠标的点击来指定位置。 legend函数:用于给图形添加图例\n基本用法:legend(图例1,图例2,···) 其中图例顺序要与plot函数中参数顺序相对应,图例的说明方式与tiele函数标题说明类似。 坐标控制 axis函数:用于设置坐标轴的范围\n基本用法:axis([xmin,xmax,ymin,ymax,zmin,zmax]) ,分别代表了x,y,z轴范围。\n其他用法:通过在axis函数下面加语句来实现控制其他格式。\naxis equal:横纵坐标刻度等长。 axis square:采用正方形坐标系(默认为矩形)。 axis auto:使用默认设置。 axis off/on:不显示/显示坐标轴。 给坐标系加网格和边框\n添加网格:通过 grid on/off 控制显示和不显示网格线,而直接用 grid 用于切换两种形式,如果是带网格则切换为不带,反之亦然。如果不添加语句,则默认不带。 添加边框:通过 box on/off 控制显示不显示边框,用法与 grid 类似,如果不添加语句,则默认带网格。 图形保持 一般情况下绘图命令每执行一次,图形界面就刷新一次,去掉原有图形,绘制新图形,如果要保留原有图形,可使用图形保持命令。通过hold on\\off 来控制是否保留,通过 hold 切换保留和不保留两种选择。\n图形窗口分割 子图:同一图形窗口中的不同坐标系下的图形称为子图。 subplot函数 :subplot(m,n,p) 意思是将图形窗口分成 $m\\times n$ 个子图区域,当前绘制的是第p个子图,区号按行编号。我们在一个图形窗口内,绘制不同的图可以采用不同的分割。 例程 绘制 $sinx$ 、$sin2x$ 、$sin(\\frac{x}{2})$ 的图像,并添加相应的图形标注。 x=linspace(0,6*pi,100); y=[sin(x);sin(2*x);sin(x./2)]; plot(x,y); axis([0,6*pi,-1.1,1.1]); title(\u0026#39;不同频率正弦函数曲线\u0026#39;); xlabel(\u0026#39;X-axis\u0026#39;); ylabel(\u0026#39;Y-axis\u0026#39;); text(2.5,sin(2.5),\u0026#39;sin(x)\u0026#39;); text(1.5,sin(3),\u0026#39;sin(2*x)\u0026#39;); text(5.5,sin(0.5*5.5),\u0026#39;sin(x/2)\u0026#39;); legend(\u0026#39;sin(x)\u0026#39;,\u0026#39;sin(2x)\u0026#39;,\u0026#39;sin(x/2)\u0026#39;); grid on 利用子图函数在不同区域绘出不同图形。 x=linspace(0,2*pi,100); subplot(2,2,1); plot(x,sin(x)); title(\u0026#39;sin(x)\u0026#39;); axis([0,2*pi,-1,1]); subplot(2,1,2); plot(x,cos(x)); title(\u0026#39;cos(x)\u0026#39;); axis([0,2*pi,-1,1]); subplot(4,4,3); plot(x,tan(x)); title(\u0026#39;tan(x)\u0026#39;); subplot(4,4,8); plot(x,cot(x)); title(\u0026#39;cot(x)\u0026#39;); axis([0,2*pi,-35,35]); 4.3 其他形式的二维曲线 其他坐标系下的二维曲线图 对数坐标图\nsemilogx 函数:调用形式与plot函数类似,semilogx(x,y,选项)为其中一种调用格式,其他的可参考plot函数,此函数绘图采用半对数坐标,x轴采用常用对数刻度,y轴为线性刻度。 semilogy 函数:调用形式与plot函数类似,semilogy(x,y,选项)为其中一种调用格式,其他的可参考plot函数,此函数绘图采用半对数坐标,y轴采用常用对数刻度,x轴为线性刻度。 loglog 函数:调用函数与上述类似,x和y都为常用对数刻度。 极坐标图\n基本调用格式:polar(theta,rho,选项) theta为极角,rho 为极径,选项与plot函数类似。 统计图 条形类图形\n条形图\nbar 函数:绘制二维垂直条形图\n调用格式为bar(y,style) :y如果为向量,则以每个元素值作为每一个柱的高度,元素下标代表横坐标。如果y为矩阵,则以每一行作为一组,以行号作为组号绘图。后方的 style 有 \u0026quot;grouped\u0026quot; 和\u0026quot;stacked\u0026quot; 两种模式,分别为簇状分组和堆积分组。默认为簇状分组。 调用格式为bar(x,y,style) :其中x存储横坐标,y为矩阵,存储每一个横坐标对应的数据,y的行数必须与x的长度相对应。 barh 函数:绘制二维水平条形图。调用格式与bar函数相同。\n直方图\nhist 函数:绘制直角坐标系下的直方图。\n调用格式为 hist(y) ,y为向量,绘图时将 $[miny,maxy]$ 区间等分成十组,并求出每个区间内对应元素的个数,然后绘出直方图。 调用格式为hist(y,x),如果x为标量,则将y区间分成x个区间,如果x为向量,则向量中的每一个数指定分组的中心值,元素的个数为指定分成的组数,x缺省默认均分十组。 rose 函数:用于绘制极坐标系下的直方图。\n调用格式为 rose(theta,x) 其中参数 theta 用于确定每一数据与圆点的角度,如果x为标量,则x代表均分组数,缺省默认为20。 面积类图形\n扇形图/饼图 pie 函数:调用格式为 pie(x,explode) 其中参数x为待统计的数据,通常为向量,其中每一个数据在整体中占用的比例在扇形图中表示出来,后续的 explode 为每个x对应的分离参数,如果非0,则将其分离出来。explode 缺省则饼图为一个整体。 面积图 area 函数:与plot函数类似,下方与坐标轴围成的区域进行填充。 散点类图形\n散点图 scatter 函数:scatter(x,y,选项,'filled') ,其中x和y通常为同等大小向量,代表了一定数量的点。选项与plot函数类似,用于限制颜色,线型,以及数据点标记,如果采用数据点标记,则可以用 \u0026lsquo;filled\u0026rsquo; 参数来填充数据点,如果缺省,则标记数据点为空心。 阶梯图 stairs 函数:使用方法与上述 scatter 函数类似。 杆图 stem 函数: 使用方法与上述 scatter 函数类似。 矢量类图形\n箭头图\nquiver 函数:常用此绘制磁力线,矢量。调用格式为quiver(x,y,u,v) , 其中 (x,y) 为矢量起点,(u,v) 为矢量终点,如果x,y省略,则均匀取若干个点作为起点。 罗盘图\ncompasser函数:与 plot 函数类似。 羽毛图\nfeather 函数:与 plot 函数类似。 例程 某次考试成绩优秀,良好,中等,及格,不及格人数分别为:7、13,23,9,4,用扇形统计图作成绩统计。 score = [7,13,23,9,4]; tag = [0,0,0,0,1]; pie(score,tag); legend(\u0026#34;Excellent\u0026#34;,\u0026#34;Good\u0026#34;,\u0026#34;Middle\u0026#34;,\u0026#34;Qualified\u0026#34;,\u0026#34;Bad\u0026#34;,\u0026#39;Location\u0026#39;,\u0026#39;eastoutside\u0026#39;); %上方legend中的location是用于指定图例出现位置的,如果不指定,会与统计图重合 不加location参数\n加入location参数\n4.4 三维曲线 plot3函数:绘制三维曲线最常用的函数。 基本用法:plot3(x,y,z) 其中三个参数分别为坐标对,一般为等长向量,plot3函数用直线将所有点连起来。\n变化形式:\n当plot(x,y,z) 当x,y,z为同型矩阵,则绘制多条曲线,曲线条数等于矩阵列数。\n当x,y,z中有向量也有矩阵的时候,向量的长度应与矩阵相符,如果是行向量,那么行向量的长度应与矩阵列数相同,如果是列向量,那么列向量的长度应与矩阵行数相同。\n也可以用多组向量对来绘制多组曲线,plot(x1,y1,z1,x2,y2,z2···,xn,yn,zn) ;\n含选项的plot3函数:plot(x,y,z,选项) 选项与功能与plot函数类似。\nfplot3函数 基本用法:与fplot函数类似 4.5 三维曲面 生成平面网格数据 meshgrid 函数:调用格式 [X,Y]=meshgrid(x,y) ,其中x,y为向量,X,Y为存储网格坐标系横纵坐标的矩阵。如果只填一个 x ,那么就相当于 x=y 。 绘制三维曲面的函数 mesh 函数 \u0026amp; surf 函数\n基本调用格式:mesh(x,y,z,c) \u0026amp; surf(x,y,z,c),两者可以用来绘制三维曲面,其中x,y为网格坐标矩阵,z 是网格点上的高度矩阵,c 用于指定在不同高度下的曲面颜色。如果 c 缺省,则默认 c=z ,也就是说颜色正比于高度。\n其他调用格式: mesh(z,c) \u0026amp; surf(z,c) 这样的话就用z矩阵的列,行坐标代表x,y的值,z的值代表高度,c的意义与上面相同。\n其他花里胡哨的 :\n带等高线的三维网格曲面函数 meshc 和 带底座的三维网格曲面函数meshz ,用法与 mesh 函数相同。前者带等高线,后者带底座(就是说下面是实体的)。 带等高线的曲面函数 surfc 和具有光照效果的曲面函数 surfl 。 标准三维曲面 sphere 函数:生成三维球面对应坐标。格式[x,y,z]=sphere(n) ,这将产生x,y,z三个(n+1)阶的方阵,通过这三个方针结合绘制三维曲面的函数 (surf或者mesh),可以绘制出圆心在圆点,半径为一的单位球面。如果不加输出参数x,y,z,则直接绘制球面。n的值代表圆滑程度,默认为20. cylinder 函数:生成三维柱面对应坐标。格式为 [x,y,z]=cylinder(R,n) R为一个向量,存放柱面各个等间隔高度上的半径,n表示圆柱圆周上的间隔点个数,默认为20。如果R为标量,则生成一个柱面。 fsurf和fmesh函数 用于绘制参数方程表示的函数,并且有两个变参。调用格式为 fsurf(funx,funy,funz,uvlims),其中前三个通常为函数句柄形式给出的函数,uvlims 表示前三个函数自变量取值范围,用四元向量组来进行描述,形如[umin,umax,vmin,vmax],默认值为[-5,5,-5,5] 。\n例程 绘制螺旋曲面。 funx = @(u,v) u.*sin(v); funy = @(u,v) -u.*cos(v); funz = @(u,v) v; fsurf(funx,funy,funz,[-5 5 -5 -2]) hold on fmesh(funx,funy,funz,[-5 5 -2 2]) hold off 绘制函数$z=(x-1)^2+(y-2)^2-1$ 的曲面图,分别用带等高线的mesh函数,带底座的mesh函数,带等高线的surf函数,带光照效果的surf函数绘制。$x\\in[0,2],y\\in[1,3]$ [x,y]=meshgrid(0:0.1:2,1:0.1:3); z=(x-1).^2+(y-2).^2-1; subplot(2,2,1); meshc(x,y,z);title(\u0026#39;meshc(x,y,z)\u0026#39;) subplot(2,2,2); meshz(x,y,z);title(\u0026#39;meshz(x,y,z)\u0026#39;) subplot(2,2,3); surfc(x,y,z);title(\u0026#39;surfc(x,y,z)\u0026#39;) subplot(2,2,4); surfl(x,y,z); title(\u0026#39;surfl(x,y,z)\u0026#39;) ","permalink":"https://blog.zzsqwq.cn/posts/51/","summary":"\u003ch2 id=\"41-二维曲线\"\u003e4.1 二维曲线\u003c/h2\u003e\n\u003ch3 id=\"span-idjumpplot函数span\"\u003e\u003cspan id=\"jump\"\u003eplot函数\u003c/span\u003e\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e基本用法\u003c/strong\u003e:\u003ccode\u003eplot(x,y)\u003c/code\u003e ,x和y分别代表横纵坐标,plot函数会将各个点连接起来,形成线,x和y一般为长度相等的向量。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e最简单的调用格式\u003c/strong\u003e:\u003ccode\u003eplot(x)\u003c/code\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e当x为实向量时\u003c/strong\u003e,则以该元素下表为横坐标,元素的值为纵坐标绘制曲线。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e当x为复向量时\u003c/strong\u003e,则以\u003cstrong\u003e实部\u003c/strong\u003e和\u003cstrong\u003e虚部\u003c/strong\u003e分别为横纵坐标绘制曲线。\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e","title":"专题四:MATLAB绘图"},{"content":"3.1 顺序结构程序 程序设计的基本步骤 程序 在matlab中程序文件扩展名为**.m** ,因此程序文件又叫 M文件。 程序文件分两种 脚本文件:是可以在命令行窗口直接执行的文件,也叫命令文件。 函数文件:定义一个函数,以函数调用方式来调用,不能单独执行。 文件的建立 可以在主页点击新建脚本,即可创建脚本文件,并且打开MATLAB编辑器。 在命令行窗口写 edit test 即可在当前文件下创建 test 脚本文件。 %利用脚本文件求两矩阵乘积 %脚本文件f1.m A=[1:3;4:6]; B=[1,2;3,4;5,6]; C=A*B; %在命令行窗口运行脚本文件 \u0026gt;\u0026gt; f1 C = 22 28 49 64 %利用函数文件求两矩阵乘积 %函数文件f1.m function C=f2(A,B) C=A*B; end \u0026gt;\u0026gt; C=f1(A,B) C = 22 28 49 64 顺序结构 数据的输入 : A=input(提示信息,参数选项) ,输入时会将提示信息打印出来,后面的参数选项用于限定输入数据的类型等。 数据的输出: disp(输出项) 程序的暂停: pause(延迟秒数) ,如果延迟秒数省略,那么就会一直暂停直到用户下次动作。如果程序运行中要强行暂停可以通过 Ctrl+C 实现。 例程 通过脚本文件和函数文件求一个向量的四舍五入向量。 脚本 A=[1.2,3.4,4.7,0.5]; B=round(A); disp(B) 函数 function B=f2(A) B=round(A); end 求两点之间距离以及黄金分割点坐标(其中点坐标通过复数形式输入)。 a=input(\u0026#39;a=\u0026#39;); b=input(\u0026#39;b=\u0026#39;); c=a+0.618*(b-a); s=abs(b-a); disp(s) disp(c) 3.2 用if语句实现选择结构 单分支if语句 如果成立执行语句组,如果不成立则跳出if,语句格式如下:\nif 条件(关系运算或逻辑运算) 语句组 end 双分支if语句 如果成立执行语句组1,不成立执行语句组2,然后跳出if,语句格式如下:\nif 条件(关系运算或逻辑运算) 语句组1 else 语句组2 end 多分支if语句 根据上述双分支的类推,依次判断条件1~n,成立则执行对应语句组,然后跳出if,不成立则往下寻找,语句格式如下:\nif 条件1 语句组1 elseif 条件2 语句组2 elseif 条件3 语句组3 ··· elseif 条件n-1 语句组n-1 else 语句组n end 条件成立的判断 当条件结果为标量,非零表示真,零表示假。 当条件为矩阵,如果矩阵非空且不包含零元素,则条件成立,否则不成立。 3.3 用switch语句实现选择结构 switch语句的基本格式 表示在C++里面就不喜欢用switch,感觉太麻烦了。这个和多分支if有点像吧,只是他的区别在于首先给出一个表达式,在下方每一个语句组对应着一个结果表,如果结果表对应着表达式的值,就执行当前语句组,执行完之后跳出switch语句,这个和C++的有所区别。此外,如果都不满足的话,我们还可以加入一个条件otherwise,顾名思义,如果上述结果都不满足,就执行这个otherwise下对应的语句,switch的语句格式如下:\nswitch 表达式 case 结果表1 语句组1 case 结果表2 语句组2 ··· case 结果表n 语句组n otherwise 语句组k end switch的使用规则 case结果表为switch表达式的取值,当取值有多个时,我们可以用单元数据表示。将这多个结果用大括号{}括起来,如果表达式值满足其中一个,就执行相应语句组。 用for语句实现循环结构 常用的for语句 % for语句格式: for 循环变量=表达式1:表达式2:表达式3 循环体语句 end 我们可以发现循环变量后面对应的是一个冒号表达式,分别是起始,步长,终止。 循环执行时,先求出冒号表达式对应的行向量,然后依次遍历行向量中的每一个元素,执行循环体语句。 for语句针对向量每一个元素执行一次循环体,有几个元素执行几次,当冒号表达式对应的向量为空向量,则一次也不执行。 当退出循环后,循环变量值为行向量组中的最后一个元素。 更一般的for语句 for 循环变量=矩阵表达式 循环体语句 end 更一般的for语句循环遍历后对应的是矩阵表达式,执行过程中将矩阵的各列元素,赋值给循环变量,这时候,循环变量为一个列向量,而不是上述常用for语句中的标量,可以发现,常用的for语句是一般格式下的特例。循环的次数为矩阵的列数。 例程 计算圆周率 $\\pi$\n利用循环求无穷级数展开求 $\\pi$ $$ 1-\\frac{1}{3}+\\frac{1}{5}-\\frac{1}{7}+\\cdots+(-1)^{n+1}\\frac{1}{2n-1} =\\frac{\\pi}{4} $$\ny=0; g=-1; n=input(\u0026#39;n=\u0026#39;); for i=1:n g=-g; y=y+g*1/(2*i-1); end disp(4*y) 利用矩阵求和求无穷级数展开求 $\\pi$ n=input(\u0026#39;n=\u0026#39;); x=1:2:(2*n-1); y=(-1).^(2:n+1)./x; disp(sum(y)*4) 3.5 用while语句实现循环结构 while语句 通过一个条件来判定是否执行循环体语句,当条件成立时,成立。不像是for循环先去设定循环多少次,循环变量依次取什么值,这个是根据条件限定,又叫条件循环语句。\nwhile 条件 循环体语句 end break语句和continue语句 break语句:当循环执行到break语句会跳出当前循环,进行循环外的语句。 continue语句:当循环执行到continue语句,会结束本次循环,进行下一次判断是否继续循环体。 循环嵌套 如果一个循环结构循环体又包括循环结构,那么就称为循环嵌套or多重循环结构。通过嵌套的层数不同来不同的命名,例如二重循环,三重循环等等。\n例程 从键盘输入若干数,当输入0时结束输入,求这些数的和和他们的平均值\nmsum=0; cnt=0; x=input(\u0026#39;Enter your numbers: \u0026#39;); while x~=0 msum=msum+x; cnt=cnt+1; x=input(\u0026#39;Enter your numbers: \u0026#39;); end if cnt\u0026gt;0 disp(msum); disp(msum/cnt); end 用筛法求 1~m 范围内的素数。\nm=input(\u0026#39;m=\u0026#39;); p=1:m; p(1)=0; for i=2:sqrt(m) for j=2*i:i:m p(j)=0; end end n=find(p~=0); p(n) 3.6 函数文件的定义与调用 函数文件的基本结构 function 输出参数表=函数名(输入形参表) 注释说明部分 函数体语句 end 当有多个形参时,形参之间用 , 逗号分隔,组成形参表。当输出形参多于一个,用方括号 [] 括起来,形成输出矩阵。 函数使用中的一些规定 函数文件名通常由 函数名再加上拓展名.m 组成,函数文件名与函数名也可以不同,当两者不同时,MATLAB默认忽视函数名,调用时使用函数文件名。但一般我们将函数名和函数文件名进行统一\n如果函数文件中有 return 语句,就结束函数的执行,返回栈底。\n函数调用 [输出实参表]=函数名(输入实参表) 匿名函数 MATLAB提供了一种特殊的函数,函数句柄变量相当于这个函数的别名,通过函数句柄可以间接的调用函数,多个参数之间用逗号分隔。\n函数定义的基本格式如下:\n函数句柄变量 = @(匿名函数输入参数) 匿名函数表达式 函数调用的基本格式如下:\n函数句柄变量(匿名函数输入实参) 特殊的,我们可以将一个已知的内部函数或者自定义函数,赋值给一个函数句柄变量,这样我们就可以通过函数句柄变量变量来简洁的调用函数。(类似于改个名字)\n例程 通过函数文件和匿名函数两个形式,求出 $x^2+y^2$ 的值。\n函数文件 function z=f2(x,y) z=x^2+y^2; end 匿名函数 f=@(x,y) x^2+y^2 3.7 函数的递归调用 函数的递归调用 如果一个函数在函数体内部调用自己本身称为递归调用(如果是其他函数称为嵌套调用)。递归是把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。\n直接递归调用:在一个函数体内部直接调用自己本身。 简介递归调用:在一个函数体内不嵌套调用其他函数,其他函数又调用自己。 例程 求 $n!=1\\times2\\times3\\cdots \\times n$ function f=fact(n) if n\u0026lt;=1 f=1; else f=fact(n-1)*n; end 3.8 函数参数与变量的作用域 函数参数的可调性 可调性顾名思义,就是可以调节的。MATLAB函数在调用过程中函数传递参数的数目是可以调节的。在调用时,函数有两个预定义变量,nargin 和 nargout ,前者记录调用函数时输入实参的个数,后者记录调用函数时输出实参的个数。通过这两个变量,可以针对不同的变量个数进行不同的处理。\n全局变量和局部变量 函数中定义的变量是局部变量,不能被其他函数引用 我们可以通过 global 变量名 来定义一个全局变量,如果不加 global ,默认是局部变量。 全局变量的作用域是整个MATLAB工作空间,全程有效,所有函数都可以对他进行存取和修改。 但是要注意的是,这里的全局变量使用方式和C++的有所区别,如果你要在函数中调用工作区中的全局变量,那么你需要在函数体内部定义相同的全局变量,这样才可以对其进行引用,函数体内部和工作区中的变量值是共享的。 例程 求 $x1\\times x+y1\\times y$ ,其中x1 和 y1 是全局工作区中全局变量的值。 %函数文件 function f=solve(x,y) global x1 y1 f=x1*x+y1*y %工作区 global x1 y1; x1=1; y1=2; s=solve(1,2) ","permalink":"https://blog.zzsqwq.cn/posts/36/","summary":"\u003ch2 id=\"31-顺序结构程序\"\u003e3.1 顺序结构程序\u003c/h2\u003e\n\u003ch3 id=\"程序设计的基本步骤\"\u003e程序设计的基本步骤\u003c/h3\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"https://blog.zzsqwq.cn/usr/uploads/2020/08/2521586228.png\" alt=\"step.png\" /\u003e\n\u003c/p\u003e","title":"专题三:MATLAB程序流程控制"},{"content":"2.1 特殊矩阵 通用的特殊矩阵 zeros函数: 产生全0矩阵,即零矩阵。\nones函数: 产生全1函数,即幺矩阵。\neye函数: 产生对角线为1的矩阵,当矩阵为方针时,为单位矩阵。\nrand函数: 产生 (0,1) 区间均匀分布的随机矩阵。\n通过 fix(a+(b-a+1)*rand(x)) 可产生[a,b]区间上均匀分布的随机整数。\nrandn函数: n为normal的意思,产生均值为0,方差为1的标准正态分布随机矩阵。\n通过 $\\mu+\\sigma x$ 来得到均值为 $\\mu$ ,方差为 $\\sigma{^2}$ 的随机数据。(高中数学知识,证明可百度) 对于上述函数的调用格式,我们都有如下规定,zeros(m)为产生 $m\\times m$ 的零矩阵,zeros(m,n)为产生类型为 $m\\times n$ 的零矩阵, zeros(size(A)) 为产生和 A 同类型的零矩阵,其余函数和此类似。 用于专门学科的特殊矩阵 魔方/幻方矩阵 (Magic Square)\nn阶幻方矩阵每行,每列,主副对角线的和相等。 n阶幻方矩阵每行每列的元素之和为 $(1+2+3+\\cdots+n^2)/n=(n+n^3)/2$ 范德蒙矩阵 (Vandermonde)\n利用 Vander(V) 生成以向量 V 为基础的**范德蒙(Vandermonde)**矩阵。 A=vander(1:5) A = 1 1 1 1 1 16 8 4 2 1 81 27 9 3 1 256 64 16 4 1 625 125 25 5 1 希尔伯特矩阵 (Hilbert)\n利用 hilb(n) 可以生成n阶希尔伯特矩阵。 伴随矩阵\n通过 compan(p) 可以生成向量p对应的多项式的伴随矩阵。p向量中高次系数在前,低次系数在后。(我感觉我学过伴随矩阵,但看了之后又感觉没学过QAQ) 帕斯卡矩阵\n通过 pascal(n) 生成一个n阶帕斯卡矩阵。 2.2 矩阵变换 对角阵 对角矩阵:只有对角线上有非0元素的矩阵是对角矩阵。如果对角线上元素相等,则称为数量矩阵。当对角线上元素相等且为1,称为单位矩阵。 提取矩阵的对角线元素 diag(A): 提取矩阵A主对角线元素,产生一个列向量。 diag(A,k): 提取矩阵A第k条对角线元素,产生一个列向量。主对角线为第0条,往上依次为1,2···n,往下依次为-1,-2 ··· -n。 构造对角矩阵 diag(V): 以向量V为主对角线元素,产生对角矩阵。 diag(V,k): 以向量V为第k条对角线元素,产生对角矩阵。 三角阵 矩阵对角线以上元素全为0为上三角矩阵,以下全为0为下三角矩阵。 上,下三角矩阵 (上 up,下 low),关于下三角的只需要把 triu 换为 tril triu(A): 提取矩阵A的主对角线及以上的元素。 triu(A,k): 提取矩阵A的第k条对角线及以上的元素。 矩阵的转置 普通转置运算符为 .' ,共轭转置为 ' ,它在转置的基础上还会求每个数的复共轭。 矩阵的旋转 rot90(A,k): 将矩阵A逆时针方向旋转 $90^{\\circ}$ 的k倍,当k为1时可以省略。 矩阵的翻转 fliplr(A): 对矩阵A实施左右翻转。 flipud(A): 对矩阵A进行上下反转。 矩阵的求逆 inv(A): 求A的逆阵。 矩阵的阶梯状 rref(A): 将矩阵A化为阶梯状(具体不再解释,不懂可百度) 2.3 矩阵求值 方阵的行列式 通过 det(A) 可以求A矩阵的行列式值。 矩阵的秩 通过 rank(A) 可以求A矩阵的秩。 矩阵的迹 矩阵的迹等于对角线元素之和,也等于特征值之和。通过 trace(A) 可以求A矩阵的迹。 向量和矩阵的范数 范数用来度量矩阵或向量在某种意义下的长度。\n向量的范数\n向量 1-范数 : 为向量元素的绝对值之和。通过 norm(V,1)计算V的1-范数 $$ ||V||{_1}=\\sum\\limits^n_{i=1}|v_i| $$\n向量 2-范数 : 为向量元素绝对值的平方和的平方根。通过norm(V)或者norm(V,2)计算向量V的2-范数 $$ ||V||_2=\\sqrt{\\sum\\limits^n_{i=1}|v_i|^2} $$\n向量 ∞-范数 : 所有向量元素绝对值中的最大值。通过norm(V,inf)计算向量V的∞-范数 $$ ||V||_{\\infty}=\\mathop{max}\\limits_{0\u0026lt;=i\u0026lt;=n}{|v_i|} $$\n矩阵的范数**(对不起我实在不想写latex了,直接截图了)**\n矩阵的范数求法和向量的一样一样滴 矩阵的条件数 用于描述矩阵性能的数,等于矩阵的范数乘逆阵的范数,条件数约接近一,矩阵性能越好。 通过 cond(A,1) ,cond(A)或cond(A,2) ,cond(A,inf) 分别求矩阵A三种范数下的条件数。 2.4 矩阵的特征值与特征向量 求矩阵的特征值 E=eig(A) :求矩阵A的全部特征值,构成向量E。 [X,D]=eig(A) :求矩阵A的全部特征值,构成对角阵D,并产生矩阵X,X各列为相应特征值对应的特征向量。 特征值的几何意义 这里没太听懂,回头来补,咕咕咕QAQ。\n2.5 稀疏矩阵 稀疏矩阵就是零元素个数远远大于非0元素个数的矩阵。\n矩阵的存储方式 完全存储方式:把所以元素按列依次存储 稀疏存储方式:只存储非0元素的行列下标和数值,不改变存储顺序,依次按列存储。 稀疏存储方式的产生 完全存储方式与稀疏存储方式的转化\n通过 A=sparse(S) 可以将矩阵S转化为稀疏存储方式的矩阵A 通过 S=full(A) 可以将矩阵A转化为完全存储方式的矩阵S。 直接建立稀疏存储矩阵\nsparse(m,n) 可以建立一个 $m\\times n$ 的所有元素都为0的稀疏矩阵。\nsparse(u,v,S) 其中u,v,S为3个等长向量,分别表示行下标,列下标,非零元素。\nB=spconvert(A) ,A是一个 $m\\times 3$ 或 $m\\times4$ 的矩阵,每一行元素依次表示一个稀疏矩阵的非零元素,从1~4列分别为,行下标,列下标,元素实部,元素虚部,若元素为实数,则第四列省略。\n单位矩阵的稀疏存储\nspeye(m,n) 可返回一个 $m\\times n$ 的稀疏存储单位矩阵。 ","permalink":"https://blog.zzsqwq.cn/posts/34/","summary":"\u003ch2 id=\"21-特殊矩阵\"\u003e2.1 特殊矩阵\u003c/h2\u003e\n\u003ch3 id=\"通用的特殊矩阵\"\u003e通用的特殊矩阵\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003ezeros函数\u003c/strong\u003e: 产生全0矩阵,即零矩阵。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eones函数\u003c/strong\u003e: 产生全1函数,即幺矩阵。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eeye函数\u003c/strong\u003e: 产生对角线为1的矩阵,当矩阵为方针时,为单位矩阵。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003erand函数\u003c/strong\u003e: 产生 \u003cstrong\u003e(0,1)\u003c/strong\u003e 区间均匀分布的随机矩阵。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e通过 \u003ccode\u003efix(a+(b-a+1)*rand(x))\u003c/code\u003e 可产生[a,b]区间上均匀分布的随机整数。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003erandn函数\u003c/strong\u003e: n为normal的意思,产生均值为0,方差为1的标准正态分布随机矩阵。\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e通过 $\\mu+\\sigma x$ 来得到均值为 $\\mu$ ,方差为 $\\sigma{^2}$ 的随机数据。\u003cstrong\u003e(高中数学知识,证明可百度)\u003c/strong\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e","title":"专题二:MATLAB矩阵处理"},{"content":"1.1 MATLAB系统环境 MATLAB操作界面的组成 MATLAB主窗口 命令行窗口 命令行窗口含有 \u0026gt;\u0026gt; 命令提示符,表示MATLAB处于准备状态,可以接受并执行命令,按下回车键后MATLAB会执行输入命令,并在后面显示执行结果 如果指令过长可以分行输入,在一行末尾写 ... 并按下回车键,在下个命令行继续输入,...称为续行符。 当前文件夹窗口 在MATLAB编程过程中生成的文件自动存放在当前文件夹,我们可以通过cd命令(例如我们要进入E盘下的work文件夹,可以cd e:\\work)或者选择文件工具栏中的文件夹来设置当前文件夹。 工作区窗口 可用于变量的显示和操作,可显示你当前创建的变量。并且可对其保存,修改,删除。 MATLAB的搜索路径 检索命令对象的顺序如下 设置文件搜索路径 用path命令设置文件搜索路径。例如: path{path,`e:\\work`} 用对话框设置文件搜索路径。在MATLAB主窗口的主页中设置。 1.2 MATLAB数值数据 数值数据类型的分类 整型\n无符号整数:含有8,16,32,64四种 带符号整数:含有8,16,32,64四种 范围和C语言一样,通过类型(数据) 来进行强转。\n浮点型\n单精度:占四字节 双精度:占八字节,数值数据默认为双精度 通过single和double函数进行强转。\n复型\n复型数据包括实部和虚部两部分,都默认为浮点型,虚数单位用i或j来表示。\n通过read和imag函数来求复型数据的实部和虚部。\n字符型\n字符在内部作为数字存储,而不会采用浮点格式存储。 数值数据的输出格式 format命令的格式,使用方法 format 格式符,不带格式符的format会恢复默认格式。ps:format只影响数据的输出,不影响数据的存储和计算。 常用数学函数 函数的调用格式为: 函数名(函数自变量的值)\n函数自变量规定为矩阵变量,也可以为标量(为矩阵的特例)。 函数在运算时将函数逐项作用在每个元素上,最后运算出来是一个与自变量同类型矩阵。 常用函数的应用\n三角函数有两类,例如sin和sind两种,前面是弧度制,后面是角度制,其余cos等类似。 abs函数可以求实数的绝对值、复数的模、字符串的ASCII码值。 用于取整的函数有fix,floor,ceil,round。分别为靠0取整,向下取整,向上取整,四舍五入取整。 判断是否为素数的函数isprime,是素数返回1,不是返回0。 \u0026gt;\u0026gt; x=[1:100]; \u0026gt;\u0026gt; k=isprime(x); \u0026gt;\u0026gt; k1=find(k); \u0026gt;\u0026gt; p=x(k1) p = 1 至 16 列 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 17 至 25 列 59 61 67 71 73 79 83 89 97 1.3 变量及其操作 变量与赋值语句 变量本质是一个内存单元的抽象,变量名以字母开头,后接数字、字母或下划线,最多63个字符。 变量名区分字母大小写(case sensitive),标准函数名以及命令名必须用小写字母。 赋值语句有两种格式 变量 = 表达式 表达式的值赋值MATLAB预定义变量ans 如果赋值后不加分号,会显示变量的结果,如果加了分号,则不显示。 预定义变量 预定义变量是系统自身定义的变量\nans 是默认赋值变量,命令行表达式值默认赋值给 ans i 和 j 代表虚数单位 pi 表示圆周率 NaN 代表非数 变量的管理 变量的删除和修改 在工作区进行变量的删除和修改 通过 who 和 whose 命令来查看变量清单,前者只显示名称,后者显示各种信息 内存变量文件 用于保存MATLAB工作区变量的文件交内存变量文件,扩展名为.mat,也叫MAT文件,是一种二进制文件。 save命令:创建内存变量文件,load命令:载入内存变量文件 1.4 MATLAB矩阵的表示 矩阵的建立 直接输入法建立矩阵\n将矩阵的元素用中括号[] 括起来,按行输入元素,同一行元素用逗号或者空格分隔,用分号换行。\n利用已有矩阵建立更大矩阵\n个人感觉类似于分块矩阵,例子如下:\n\u0026gt;\u0026gt; A=[1,2,3;4,5,6;7,8,9]; \u0026gt;\u0026gt; B=[-1,-2,-3;-4,-5,-6;-7,-8,-9]; \u0026gt;\u0026gt; C=[A,B;B,A] C = 1 2 3 -1 -2 -3 4 5 6 -4 -5 -6 7 8 9 -7 -8 -9 -1 -2 -3 1 2 3 -4 -5 -6 4 5 6 -7 -8 -9 7 8 9 用两个实矩阵矩阵通过矩阵的运算可以建立复数矩阵,要确保两个矩阵同类型\n\u0026gt;\u0026gt; B=[1,2,3;4,5,6]; \u0026gt;\u0026gt; C=[7,8,9;1,2,3]; \u0026gt;\u0026gt; D=B+i*C D = 1.0000 + 7.0000i 2.0000 + 8.0000i 3.0000 + 9.0000i 4.0000 + 1.0000i 5.0000 + 2.0000i 6.0000 + 3.0000i 冒号表达式 通过冒号表达式可以产生行向量\n一般格式为e1:e2:e3 分别是初始值,步长,终止值。可以省略e2,省略时步长为默认为1。\n\u0026gt;\u0026gt; t=0:1:5 t= 0\t1\t2\t3\t4\t5 \u0026gt;\u0026gt; s=0:5 s 0\t1\t2\t3\t4\t5 通过linspace函数产生行向量\nlinspace(a,b,n) 代表首元素为a,末尾元素为b,产生n个元素,相应的,步长为(b-a)/(n-1)。当n可以省略,省略时默认n为100。\n\u0026gt;\u0026gt; x=linspace(0,pi,5) x= 0 0.7854 1.5708 2.3562 3.1416 结构矩阵和单元矩阵 结构矩阵\n类似于C语言的结构体,把很多个数据写成一个结构体,矩阵里的每个元素个元素都是结构体变量。给对应元素赋值格式为 结构体元素.成员名=表达式 。我们应该注意到,当一个结构体内没有我们赋值的成员,那么他会自动扩充矩阵来满足你的要求。\n我们可以通过 s=struct('name',{'next','what'},'sex',{'male','unknow'}) 来创建一个包含 name 和 sex 两个成员的结构体。\n单元矩阵\n矩阵里的每个元素的类型可以不同,通过直接输入法建立,所有元素用大括号{}而不是中括号[]\n1.5 矩阵元素的引用 矩阵元素的引用方式 通过下标来引用矩阵,例如A(3,2)表示A矩阵第三列第二个元素。如果我们引用的元素超出矩阵范围,那么会默认扩充矩阵至满足要求,拓展元素默认为0。 \u0026gt;\u0026gt; A=[1,2,3;4,5,6]; \u0026gt;\u0026gt; A(4,5)=10 A= 1\t2\t3\t0\t0 4\t5\t6\t0\t0 0\t0\t0\t0\t0 0\t0\t0\t0\t10 通过序号来引用,注意矩阵元素按列存储,依次存放第一列,第二列···最后一列。\n矩阵元素的序号和下标可以通过 sub2ind 和 ind2sub 两个函数完成相互转化\nsub2ind 函数:将矩阵中指定元素的行列下标转换成存储的序号,格式为D=sub2ind(S,I,J),三个参数依次为行数和列数组成的二维向量(可以通过size函数获取),转换矩阵元素的行下标,转换矩阵元素的列下标。如果I,J为矩阵的话,那么就说明要将对应的一个下标矩阵求对应序号。注意结合下例来进行理解,我们注意到A(1,1)的序号为1,A(2,1)的序号为2,那么就是给定下标矩阵的顺序来生产的这个序号矩阵,类型相同。 \u0026gt;\u0026gt; A=[1:3;4:6] A= 1\t2\t3 4\t5\t6 \u0026gt;\u0026gt; D=sub2ind(size(A),[1,2;2,2],[1,1;3,2]) D= 1\t2 6\t4 ind2sub 函数:将矩阵元素的序号转换成下标,格式为 [I,J]=ind2sub(S,D) ,S,D分别为行数和列数组成的二维向量(可以通过size函数获取),要获取下标的元素的序号(可以是一个向量,标志要获取多个元素的下标) ,那么前方的 I和J就是对应的行下标和列下标,类似于一个 sub2ind 函数的逆用。 \u0026gt;\u0026gt; [I,J]=ind2sub([3,3],[1,3,5]) I= 1\t3\t2 J= 1\t1\t2 利用冒号表达式获得子矩阵 我们可以用冒号表达式作为矩阵的行或列下标,也可以用单个:来当行或列下标,这代表取遍全部行或列。end运算符: 表示某一维的末尾元素下标。 A(i,:)\t表示第i行的全部元素 A(:,j)\t表示第j行的全部元素 A(i:i+m,j:j+m)\t表示第i~i+m行和j~j+m列全部元素 A(i:i+m,:)\t表示第i~i+m行全部元素 A(1:3;1:end) 这代表取1~3行和1~最后一列元素 利用空矩阵删除矩阵元素 空矩阵就是不含任何元素的矩阵,例如x=[] 就建立了一个空矩阵x。 \u0026gt;\u0026gt; C=[4,5,6;1,2,3] C = 4 5 6 1 2 3 \u0026gt;\u0026gt; C(:,1:2)=[] C = 6 3 改变矩阵的形状 通过reshape函数可以在矩阵元素个数不变的情况下改变矩阵形状,例如 reshape(A,m,n) 就是将A矩阵变成m行n列的矩阵,不改变矩阵元素的存储顺序,也就是依次按列存储,对应序号相同。 特殊的约定 通过指令A(:) 可以将所有元素堆叠成一个列向量,不改变存储顺序。 1.6 MATLAB基本运算 算数运算 基本算术运算:+(加),-(减),*(乘),/(右除),\\(左除),^(乘方)\nMATLAB的算数运算在矩阵意义下进行,单个数据运算是矩阵的特例。 加减运算 两矩阵同型,对应元素相加减。不同型,发生错误。 一个标量可以和矩阵进行运算,这时把标量对全体矩阵元素进行操作。 乘法运算 很明显必须满足矩阵乘的条件,也就是当A*B时必须满足A的行数等于B的列数,此时称A,B矩阵是可乘的,或称两矩阵维数和大小相容。不相容就会发生错误 除法运算 如果A是**非奇异矩阵(A的行列式不为0) **,则B/A等效于B*inv(A),A\\B等效为inv(A)*B。inv(A)是指A的逆阵 。 乘法运算 A矩阵的x次方可以表示成A^x ,要求A为方阵,x为标量。 点运算\n点运算符:在相应算术运算符前面加.,有点乘,点右除,点左除,点乘方。 点运算:两个同型矩阵对应元素进行相关运算。 \u0026gt;\u0026gt; A=[1,2;3,4]; \u0026gt;\u0026gt; A^2 ans = 7 10 15 22 \u0026gt;\u0026gt; A.^2 ans = 1 4 9 16 关系运算 关系运算符: \u0026lt; ,\u0026lt;=,\u0026gt;,\u0026gt;=,==(等于),~=(不等于) 两个比较量为标量,直接比较两个数大小,如果成立表达式值为1,否则为0。 如果两个矩阵是同型矩阵,对每两个对应元素进行比较,形成一个由0,1构成的同型矩阵。 如果一个是标量一个是矩阵,则用标量和每个矩阵元素比较,形成一个同型矩阵。 逻辑运算 逻辑运算符: \u0026amp;(与),|(或),~(非)。各自对应的运算法则和C语言类似,不再赘述。 标量,矩阵之间进行运算,对应规则和关系运算类似,不再赘述。 运算符的优先级 算术运算优先级最高,逻辑运算优先级最低,但是逻辑非运算是单目运算符,优先级比双目运算符高。\n1.7 字符串处理 字符串的表达 用单引号括起来的字符序列就是字符串,MATLAB把他当成一个行向量。若字符串中含有单引号,则单引号字符要用两个单引号表示。 可以建立多行字符串,建立字符矩阵**(注意每一行的字符串长度要相等)**。和数值矩阵无异。 字符串的操作 字符串的执行\n通过eval(s) 函数可以执行字符串 s 对应的命令行命令。 字串与数值之间的转换\nabs 和 double 函数都可以获取字符串矩阵对应的ASCII码矩阵。 char 函数可以把ASCII码矩阵转换成字符串矩阵。 字符串的比较\n关系运算符比较:两个等长字符串比较,两两对应字符比较,成立为1,不成立为0,得到是一个含0,1的行向量。 字符串比较函数比较 strcmp(s1,s2):比较s1和s2是否相等,返回值为一个标量,相等为0,不等为1。后缀加i表示比较时忽略大小写。 strncmp(s1,s2,n):比较s1和s2前n个字符是否相等,返回值为一个标量。相等为0,不等为1。后缀加i表示比较时忽略大小写。 字符串的查找和替换\nfindstr(s1,s2):返回短字符串在长字符串中的开始位置。如果出现多次,则返回一个行向量。 strrep(s1,s2,s3):将s1中所有子字符串s2替换为s3。 数值转换为字符\n通过 num2str 或 int2str 等函数可以将数字转换为字符 ","permalink":"https://blog.zzsqwq.cn/posts/33/","summary":"\u003ch2 id=\"11-matlab系统环境\"\u003e1.1 MATLAB系统环境\u003c/h2\u003e\n\u003ch3 id=\"matlab操作界面的组成\"\u003eMATLAB操作界面的组成\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e\u003cstrong\u003eMATLAB主窗口\u003c/strong\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e命令行窗口\u003c/strong\u003e\n\u003cul\u003e\n\u003cli\u003e命令行窗口含有 \u003ccode\u003e\u0026gt;\u0026gt;\u003c/code\u003e 命令提示符,表示MATLAB处于准备状态,可以接受并执行命令,按下回车键后MATLAB会执行输入命令,并在后面显示执行结果\u003c/li\u003e\n\u003cli\u003e如果指令过长可以分行输入,在一行末尾写 \u003ccode\u003e...\u003c/code\u003e 并按下回车键,在下个命令行继续输入,\u003ccode\u003e...\u003c/code\u003e称为续行符。\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e当前文件夹窗口\u003c/strong\u003e\n\u003cul\u003e\n\u003cli\u003e在MATLAB编程过程中生成的文件自动存放在当前文件夹,我们可以通过cd命令(例如我们要进入E盘下的work文件夹,可以\u003ccode\u003ecd e:\\work\u003c/code\u003e)或者选择文件工具栏中的文件夹来设置当前文件夹。\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e工作区窗口\u003c/strong\u003e\n\u003cul\u003e\n\u003cli\u003e可用于变量的显示和操作,可显示你当前创建的变量。并且可对其保存,修改,删除。\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ol\u003e","title":"专题一:MATLAB基础知识"},{"content":"前言 学OI的时候就做过树形dp的题,不过那时候全在划水。看了看题解还不太懂就直接照着题解写了,现在再回来看还是不会QAQ,所以就再看看然后自己写了一遍。\nA. 没有上司的舞会 题意 有 $N$ 个职员被邀请去参加公司的舞会,他们每个人对应着一个快乐指数 $h_i$ ,如果该职员来了就会为舞会增加$h_i$ 点快乐指数。这 $N$ 个职员之间有从属关系,也就是说他们的关系就像一棵以顶级上司为根的树,父结点就是子结点的直接上司。如果一个职员的直接上司来到了舞会,那么他本人就不会再来。问邀请哪些职员可获得最大的快乐指数,最大为多少。\n思路 职员之间的关系是以树的形式给出的,所以先用链式前向星来存储数。存的时候我们用vis数组记录一下如何那个人有上司,就将他标记一下,最终没有标记的就是没有上司的,也就是顶级上司,也就是我们的根节点root。 树形dp,顾名思义,在树上进行dp,通过递归dfs,先算出子树的状态,再通过递归的回溯来合并。那么我们考虑一下设计状态,很明显一个人的状态有来和不来,两个情况。所以我们设计状态 $dp[i][0/1]$ 来表示职员 i 来或者不来,我们用u来表示当前节点,用v来表示当前节点的子节点,那么状态转移如下:\n$dp[u][0]=max(dp[v][0],dp[v][1]) $ (上司u没有来,那么下属v可以来,也可以不来,选一个大的策略)\n$dp[u][1]=dp[v][0]+h[u]$ (上司u来了,下属v肯定不来)\n最终的答案就是 $max(dp[root][0],dp[root][1])$ ,上司来和不来两种策略中的最大一种。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=6005; int head[maxn]; struct edge { int next; int to; }e[maxn]; int cnt,n,l,k,vis[maxn],root; int r[maxn]; int dp[maxn][2]; void add(int l,int k) { e[++cnt].next=head[l]; e[cnt].to=k; head[l]=cnt; } void dfs(int u) { dp[u][0]=0; dp[u][1]=r[u]; for(int i=head[u];i;i=e[i].next) { int v=e[i].to; dfs(v); dp[u][1]+=dp[v][0]; dp[u][0]+=max(dp[v][1],dp[v][0]); } } int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) scanf(\u0026#34;%d\u0026#34;,\u0026amp;r[i]); for(int i=1;i\u0026lt;n;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;l,\u0026amp;k); add(k,l); vis[l]++; } scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;l,\u0026amp;k); for(int i=1;i\u0026lt;=n;i++) { if(!vis[i]) root=i; } dfs(root); printf(\u0026#34;%d\u0026#34;,max(dp[root][0],dp[root][1])); return 0; } B. 战略游戏 题意 小姜老师要建立一个树,树节点两两之间通过道路连接,他要在这些节点上放一些小人,每个小人可监管与该节点相连的道路,问最少放置多少小人可以监管所有道路。(数据保证0为根节点)\n思路 这个题跟上个题有点像,首先我们也是用链式前向星把树给存下来,不过这个题的输入跟上道题有点不一样,本质都是一样的。因为我们只需要dfs下去,然后向上回溯的时候合并,所以只需要存单向边即可。 对于一个节点我们也是有两种策略,选或者不选,那么我们也可以把状态写成 $dp[i][1/0]$ ,对应着 i 这个节点选或者不选,我们把当前节点看作u,子节点看作v,状态转移如下:\n$dp[u][1]+=\\Sigma (dp[v][0],dp[v][1]) +1$ (u选了,v选不选都可以,加上自身的1)\n$dp[u][0]+=\\Sigma dp[v][1]$ (如果u没有选,那么v一定要选,才能监管到u的道路)\n很显然这个答案是 $min(dp[0][0],dp[0][1])$\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=1505; struct edge { int next,to; }e[maxn]; int u,v; int head[maxn]; int dp[maxn][2]; int num; int n,cnt; void add(int u,int v) { e[++cnt].next=head[u]; e[cnt].to=v; head[u]=cnt; } void dfs(int u) { dp[u][1]=1; for(int i=head[u];i;i=e[i].next) { int v=e[i].to; dfs(v); dp[u][1]+=min(dp[v][1],dp[v][0]); dp[u][0]+=dp[v][1]; } } int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=0;i\u0026lt;n;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;u,\u0026amp;num); for(int i=1;i\u0026lt;=num;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;v); add(u,v); } } dfs(0); printf(\u0026#34;%d\u0026#34;,min(dp[0][0],dp[0][1])); return 0; } C. 二叉苹果树 题意 有一颗二叉苹果树,也就是说树枝如果分叉,一定是分二叉。苹果树有 $n$ 个节点,树根编号为 1 。每个树枝上都有一定数量的苹果,如果最终保留 $q$ 根树枝,问最多能够保留多少苹果。\n思路 这个树形dp要比上面的还要难一些,因为我们的状态不能够只考虑是否保留当前的树枝了,因为保留当前树枝也会有很多种关于保留子树枝选择。看了题解大佬的说法是,可以定义成 $f[u][j]$ 来表示 u 的子树上保留 j 条边时所能获得最大的苹果数。所以我们考虑一下转移方程,首先我们能保留的最大边数是当前子树所具有的所有树枝,对于一个节点下的两个树枝,我们可以选择取,或者不取,那么这就类似于一个背包问题,对于一定的容量(一定量的树枝),我们取几个树枝才能获得最大的价值。但是我们注意,对于一个节点u,我们如果要取他的节点v,那么我们u-v之间这个树枝一定要保留,不然会不能取得v,这是一个隐藏的条件。 因此转移方程: $dp[u][i]=max(dp[u][i],dp[u][i-j-1]+dp[v][j]+w[u][v] $ ,$w[u][v]$为当前u-v树枝的苹果数。代码里面因为我懒得计算子树的树枝数了,所以就直接从最大的q来枚举了,就没考虑那么多,可能复杂度稍微高一点,但是高不到哪去其实QAQ\u0026hellip;\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=105; struct edge { int next,to,w; }e[maxn]; int n,cnt,q; int u,v,w; int dp[maxn][maxn]; int head[maxn]; void add(int u,int v,int w) { e[++cnt].next=head[u]; e[cnt].to=v; e[cnt].w=w; head[u]=cnt; } void dfs(int u) { for(int i=head[u];i;i=e[i].next) { int v=e[i].to; dfs(v); for(int j=q;j\u0026gt;=0;j--) { for(int k=0;k\u0026lt;=j-1;k++) { dp[u][j]=max(dp[u][j],dp[u][j-1-k]+dp[v][k]+e[i].w); } } } } int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;q); for(int i=1;i\u0026lt;n;i++) { scanf(\u0026#34;%d%d%d\u0026#34;,\u0026amp;u,\u0026amp;v,\u0026amp;w); add(u,v,w); } dfs(1); printf(\u0026#34;%d\u0026#34;,dp[1][q]); return 0; } ","permalink":"https://blog.zzsqwq.cn/posts/31/","summary":"\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003e学OI的时候就做过树形dp的题,不过那时候全在划水。看了看题解还不太懂就直接照着题解写了,现在再回来看还是不会QAQ,所以就再看看然后自己写了一遍。\u003c/p\u003e","title":"树形dp例题"},{"content":"A. Two Rabbits 题意 两个兔子分别位于 $(x,0)$ 和 $(y,0)$ ,两个人对头蹦,前者往前蹦 $a$ ,后者往前蹦 $b$ ,问两人是否能恰好相遇。\n思路 算一下两个人直接得距离 $s$ ,每次两者距离减少 $a+b$ ,看 $s$ 是否能被 $a+b$ 整除,如果可以就能够相遇。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; int t; int x,y,a,b; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { scanf(\u0026#34;%d%d%d%d\u0026#34;,\u0026amp;x,\u0026amp;y,\u0026amp;a,\u0026amp;b); int p=a+b; int f=y-x; if(f%p==0) { printf(\u0026#34;%d\\n\u0026#34;,f/p); } else printf(\u0026#34;-1\\n\u0026#34;); } return 0; } B. Longest Palindrome 题意 给出 $n$ 段长度为 $m$ 的字符串,从中挑选出一些组成最长的回文字串,输出这个回文子串的长度和内容,如果有多种情况输出一种即可。如果没有符合的,就输出0 。$(1\\le n\\le 100,1\\le m\\le 50)$\n思路 因为这个数据规模非常小,所以 $O(n^2m)$ 也是可以接受的(说实话我不是很会算,大概是个差不多的式子),那么我们可以选择暴力匹配,用每个字符串去匹配后面的,如果是两个互为回文串,那么就把其中任何一个计入到sub字符串中,然后用一个 vis 数组来标记他们两个已经被使用过了,最终一个字符串匹配完后面所有的发现没有合适的,那么就考虑他自己是不是一个回文串,如果是一个回文串,单独标记它是放在中间。最后我们的sub是存放了一半回文串。 统计答案的时候,先将sub加到答案ans中,检查一下是否中间有合适的回文串,如果有的话也加到ans里面,最后讲sub逆序一下,加到ans里面。最终输出答案的时候,看一下ans是不是空串,如果是空串,就输出0,否则输出长度和ans。(string是真的好用!!!)\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=105; int n,m; string ans,sub,mid; bool ifmid; string str[maxn]; bool vis[maxn]; int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;m); for(int i=1;i\u0026lt;=n;i++) cin\u0026gt;\u0026gt;str[i]; for(int i=1;i\u0026lt;=n;i++) { for(int j=i+1;j\u0026lt;=n;j++) { if(vis[j]) continue; bool flag=true; for(int k=0;k\u0026lt;m;k++) { if(str[i][k]==str[j][m-k-1]) { continue; } else { flag=false; break; } } if(flag) { vis[i]=vis[j]=true; sub+=str[i]; } } if(!vis[i]) { bool flag=true; for(int j=0;j\u0026lt;m;j++) { if(str[i][j]!=str[i][m-1-j]) { flag=false; break; } } if(flag) { mid=str[i]; ifmid=true; } } } ans+=sub; reverse(sub.begin(),sub.end()); if(ifmid) ans+=mid; ans+=sub; if(!ans.empty()) { cout\u0026lt;\u0026lt;ans.length()\u0026lt;\u0026lt;endl\u0026lt;\u0026lt;ans; } else cout\u0026lt;\u0026lt;0; return 0; } C. Air Conditioner 题意 餐厅老板有一个空调,餐厅初始温度为 $m$ ,会陆续来 $n$ 个顾客。餐厅老板每分钟可以控制空调的温度+1,-1,或者是不变。这 $n$ 个顾客会按来的时间顺序给出,每个人有一个感到舒适的温度范围,如果空调的温度在这个范围里面,那么顾客就会满意。问餐厅老板是否可以达到让每个人都满意。\n思路 首先我们先思考从餐厅开始到第一个客人来临的时候,假设第一个人来临的时间是 $t$ ,舒适区间为 $[l,r]$,那么我们可以很容易发现只要 $[l,r]$ 与 $[m-t,m+t]$ 有交集,那么就是可以满足第一个客人条件。如果第二个和第一人的时间差为 $\\Delta t$ ,那么这个时候要计算可达到的舒适区间就是在上次交集的区间上左右变化 $\\Delta t$ ,为什么是交集呢。我一开始想错了。。一直写成并集,然后一直调不出来。但实际上不是这样的,我们可以理解为只有交集那部分才是符合上个顾客要求的,如果超出那个范围,就不能够满足上个顾客要求。所以挨个顾客扫一遍就行了。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; int q,n,m; int last,l,h,t; int nowl,nowr,delt; int lef,righ; bool flag; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;q); while(q--) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;m); lef=righ=m; last=0; flag=true; for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d%d%d\u0026#34;,\u0026amp;t,\u0026amp;l,\u0026amp;h); delt=t-last; nowl=lef-delt; nowr=righ+delt; last=t; if(nowl\u0026gt;h||nowr\u0026lt;l) flag=false; else { lef=max(nowl,l); righ=min(nowr,h); } } if(flag) { printf(\u0026#34;YES\\n\u0026#34;); } else printf(\u0026#34;NO\\n\u0026#34;); } } ","permalink":"https://blog.zzsqwq.cn/posts/30/","summary":"\u003ch2 id=\"a-two-rabbitshttpscodeforcescomcontest1304problema\"\u003eA. \u003ca href=\"https://codeforces.com/contest/1304/problem/A\"\u003eTwo Rabbits\u003c/a\u003e\u003c/h2\u003e\n\u003ch3 id=\"题意\"\u003e题意\u003c/h3\u003e\n\u003cp\u003e两个兔子分别位于 $(x,0)$ 和 $(y,0)$ ,两个人对头蹦,前者往前蹦 $a$ ,后者往前蹦 $b$ ,问两人是否能恰好相遇。\u003c/p\u003e","title":"Codeforces#620 (Div.2)"},{"content":"A. 矩阵取数游戏 题意 给定一个 $n\\times m$ 的矩阵,其中每个元素为非负整数。每次你可以从每行的行首或行末取一个元素,得到的分数为当前元素的值 $a_{ij}\\times 2^k$ ,$k$ 为当前是第几次取该行上的元素。 问最大得分为多少。\n思路 首先我们发现,虽然答案问的是 $n$ 行,但是我们发现,不同行之间是不会相互影响的,我们只需要讨论一行的情况,然后对每行都处理一遍就可以了。 那么对于一行上的 $m$ 个元素,我们每一次取都有两种选择,一个是取行首,一个是取行尾。我们发现这是一个区间问题,对于区间 $[i,j]$ 的最优情况,我们可以从 $[i+1,j]$ 和 $[i,j-1]$ 这两个的最优情况转移过来,因此我们可以定义 $f[i][j]$ 是从第 $i$ 个元素到第 $j$ 的元素得分的最大值,然后从上述两个状态转移过来。 还有一个问题就是我们的 $2^k$ 问题,我们考虑到大区间的最优值是从小区间转移来,也就是说小区间乘的指数高,大区间乘的指数低,我们又是从小区间推到大区间,转移一次就乘一次,最后肯定是大区间的少,小区间的多了。qwq因为这个题的次数可能很高,会爆long long,实在是不想写高精度,就用了__int128,第一次用,感觉还不错QAQ..\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=85; int n,m; __int128 map[maxn][maxn]; __int128 dp[maxn][maxn],ans; void read(__int128 \u0026amp;x) { x=0; char ch; ch=getchar(); while(ch\u0026lt;\u0026#39;0\u0026#39;||ch\u0026lt;\u0026#39;0\u0026#39;) ch=getchar(); while(ch\u0026gt;=\u0026#39;0\u0026#39;\u0026amp;\u0026amp;ch\u0026lt;=\u0026#39;9\u0026#39;) { x=x*10+ch-\u0026#39;0\u0026#39;; ch=getchar(); } } void out(__int128 x) { if(x\u0026gt;=10) out(x/10); putchar(x%10+\u0026#39;0\u0026#39;); } int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;m); for(int i=1;i\u0026lt;=n;i++) { for(int j=1;j\u0026lt;=m;j++) read(map[i][j]); } for(int i=1;i\u0026lt;=n;i++) { for(int f=1;f\u0026lt;=m;f++) { for(int j=1;j\u0026lt;=m;j++) dp[f][j]=0; } for(int len=1;len\u0026lt;=m;len++) { for(int j=1;j+len-1\u0026lt;=m;j++) { int k=j+len-1; dp[j][k]=max(dp[j+1][k]*2+map[i][j]*2,dp[j][k-1]*2+map[i][k]*2); } } ans+=dp[1][m]; } out(ans); return 0; } B. 关路灯 题意 在一条街道上有 $n$ 个路灯开着,他们可以看作分布在 $x$ 轴上,每个路灯有一定的坐标,也就是代表他们的位置。每个路灯也有一定的功率 $x$ ,代表一秒钟消耗多少电能。姜大佬初始位置在 $c$ ,他每天早晨出来关掉路灯。它可以先关左边的也可以先关右边的,他的行走速率是 $1m/s$ ,问最少消耗多少电能能关掉所有路灯。\n思路 又是一道区间dp的题,那么我们可以思考一下,首先小姜老师肯定不能跳着关路灯,也就是说这个区间内中间的路灯都被关闭了,他会关一个区间的左端点或者右端点,而不会关这个区间外面的。那么我们就可以枚举区间长度来解决这个问题,从小的枚举到大的。 那么我们思考一下如何定义这个状态。我们可以定义关闭区间 $[i,j]$ 的路灯,最少消耗电能为 $f[i][j]$ ,如果需要转移状态的话,我们想到,对于一个方向,小姜老师可以继续往前走,关掉前面那盏灯,也可以返回去,关闭它屁股后面那盏灯。因为是有两个方向的,所以我们可以拓宽一维,用 $f[i][j][0/1]$ 来表示小姜老师现在是在往左走还是往右走,那么很明显 $f[i][j][0]$ 这个状态可以从 $f[i+1][j][0/1]$ 来转移分别对应着小姜老师继续往前走关眼前的,和返回关屁股后的。相应的 $f[i][j][1]$ 就可以从 $f[i][j-1][0/1]$ ,转移的时候再加上消耗的电能即可!\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=55; const int inf=100000000; int n,c; int lt[maxn]; //lantern pos int en[maxn]; //energy int sum[maxn]; //prefix sum int dp[maxn][maxn][2]; int calc(int i,int j) { return sum[n]-(sum[j]-sum[i-1]); } int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;c); for(int i=1;i\u0026lt;=n;i++) { for(int j=1;j\u0026lt;=n;j++) { for(int k=0;k\u0026lt;=1;k++) dp[i][j][k]=inf; } } for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;lt[i],\u0026amp;en[i]); sum[i]=en[i]+sum[i-1]; } dp[c][c][0]=dp[c][c][1]=0; for(int len=2;len\u0026lt;=n;len++) { for(int i=1;i+len-1\u0026lt;=n;i++) { int j=i+len-1; dp[i][j][0]=min(dp[i+1][j][0]+(lt[i+1]-lt[i])*calc(i+1,j),dp[i+1][j][1]+(lt[j]-lt[i])*calc(i+1,j)); dp[i][j][1]=min(dp[i][j-1][0]+(lt[j]-lt[i])*calc(i,j-1),dp[i][j-1][1]+(lt[j]-lt[j-1])*calc(i,j-1)); } } printf(\u0026#34;%d\u0026#34;,min(dp[1][n][0],dp[1][n][1])); return 0; } C. 小a和uim之大逃离 题意 给定一个 $n\\times m$ 的矩阵,每个格子中有 $0\\sim k$ 滴魔液,小姜老师和它朋友可以从任意地点开始,一起向右或者向下走,他们每个人有一个容量为 $k$ 的瓶子,由小姜老师开始轮流收集地上的魔液,当收集魔液大于 $k$ 的时候,会对 $k+1$ 取模,问他们有多少种方法使得收集的魔液数量相同。\n思路 很显然我们可以写一个5维dp,用 $f[i][j][p][l][0/1]$ 来表示,当到了坐标为 $(i,j)$ 的格子的时候,小姜老师拥有魔液 $p$ 滴,他的朋友拥有魔液 $l$ 滴,并且这一次是由小姜老师采集的/由他的朋友采集的。这样的话,感觉比较好些,但是。。空间占用非常的高,我们优化一下,因为问的是收集相等,所以只需要维护他们的差就可以了,也就是说,只需要将 $(p-l+k)\\%k$ 维护一下就可以了,因此循环枚举坐标以及他们的差,从低的向高的转移就可以了。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=805; int map[maxn][maxn]; int dp[maxn][maxn][16][2]; const int mod=1e9+7; int n,m,k; long long ans; int main() { //\tfreopen(\u0026#34;test.in\u0026#34;,\u0026#34;r\u0026#34;,stdin); scanf(\u0026#34;%d%d%d\u0026#34;,\u0026amp;n,\u0026amp;m,\u0026amp;k); k++; for(int i=1;i\u0026lt;=n;i++) { for(int j=1;j\u0026lt;=m;j++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;map[i][j]); dp[i][j][map[i][j]%k][0]=1; } } for(int i=1;i\u0026lt;=n;i++) { for(int j=1;j\u0026lt;=m;j++) { for(int t=1;t\u0026lt;=k;t++) { dp[i][j][t%k][0]+=dp[i-1][j][(t-map[i][j]+k)%k][1];dp[i][j][t%k][0]%=mod; dp[i][j][t%k][0]+=dp[i][j-1][(t-map[i][j]+k)%k][1];dp[i][j][t%k][0]%=mod; dp[i][j][t%k][1]+=dp[i-1][j][(t+map[i][j])%k][0];dp[i][j][t%k][1]%=mod; dp[i][j][t%k][1]+=dp[i][j-1][(t+map[i][j])%k][0];dp[i][j][t%k][1]%=mod; } } } for(int i=1;i\u0026lt;=n;i++) { for(int j=1;j\u0026lt;=m;j++) { ans+=dp[i][j][0][1]%mod; ans%=mod; } } printf(\u0026#34;%lld\u0026#34;,ans); } ","permalink":"https://blog.zzsqwq.cn/posts/29/","summary":"\u003ch2 id=\"a-矩阵取数游戏httpswwwluogucomcnproblemp1005\"\u003eA. \u003ca href=\"https://www.luogu.com.cn/problem/P1005\"\u003e矩阵取数游戏\u003c/a\u003e\u003c/h2\u003e\n\u003ch3 id=\"题意\"\u003e题意\u003c/h3\u003e\n\u003cp\u003e给定一个 $n\\times m$ 的矩阵,其中每个元素为非负整数。每次你可以从每行的行首或行末取一个元素,得到的分数为当前元素的值 $a_{ij}\\times 2^k$ ,$k$ 为当前是第几次取该行上的元素。 问最大得分为多少。\u003c/p\u003e","title":"dp练习"},{"content":"前言 STL之前只会用 stack 和 queue ,set 和 map 啥的也不太会用。学习一下。\n队列(queue) 概述 队列是一种特殊的线性表,是一种先进先出(FIFO)的数据结构。它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。\n用法 首先使用之前需要声明头文件 #include\u0026lt;queue\u0026gt; ,通过 queue\u0026lt;typename\u0026gt; q 的形式来进行定义队列,上述为定义了一个队列元素类型为 typename 的队列,队列名称为 q,typename可以为C++原有数据类型,例如int,char,string这些,也可以是自定义的结构体类型等。\n主要函数及用途 使用下述函数都是用类似于 队列名称.函数名() 的形式,好比pop函数就是 q.pop()\npush(x) 将元素x从队尾入队 front( ) \u0026amp; back( ) 分别为获取队首元素和队尾元素,使用的时候必须确保队列不为空 pop( ) 弹出队首元素,使用的时候必须确保队列不为空 empty( ) 判断队列是否为空,空返回true,不空返回false size( ) 查询队列中有多少个元素 应用实例 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;iostream\u0026gt; #include\u0026lt;queue\u0026gt; using namespace std; queue\u0026lt;int\u0026gt; q; int main() { q.push(1); if(!q.empty()) printf(\u0026#34;%d\\n\u0026#34;,q.front()); // q.push(2); if(!q.empty()) printf(\u0026#34;%d\\n\u0026#34;,q.back()); printf(\u0026#34;%d\\n\u0026#34;,q.size()); if(!q.empty()) q.pop(); if(q.empty()) printf(\u0026#34;queue is empty\\n\u0026#34;); else printf(\u0026#34;queue is not empty\\n\u0026#34;); if(!q.empty()) q.pop(); if(q.empty()) printf(\u0026#34;queue is empty\\n\u0026#34;); } /* 运行结果 1 2 2 queue is not empty queue is empty */ 栈(stack) 概述 与队列相对应,是一种先进后出(FILO)的数据结构,限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。\n用法 首先使用之前需要声明头文件 #include\u0026lt;stack\u0026gt; ,通过 stack\u0026lt;typename\u0026gt; s 的形式来进行定义栈,上述为定义了一个队列元素类型为 typename 的栈,栈名称为 s,typename可以为C++原有数据类型,例如int,char,string这些,也可以是自定义的结构体类型等。\n主要函数及用途 使用下述函数都是用类似于 栈名称.函数名() 的形式,好比pop函数就是 s.pop()\npush(x) 将元素x压栈 pop( ) 将栈顶元素出栈,使用时确保栈不为空 top( ) 获取栈顶元素的值,使用时要确保栈不为空 size( ) 返回栈中元素的个数 empty( ) 查询栈是否为空,空返回true,不空返回false 应用实例 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;iostream\u0026gt; #include\u0026lt;stack\u0026gt; using namespace std; stack\u0026lt;int\u0026gt; s; int main() { s.push(1); s.push(2); printf(\u0026#34;Now the top element is %d\\n\u0026#34;,s.top()); //Now the top element is 2 printf(\u0026#34;Now the stack size is %d\\n\u0026#34;,s.size()); //Now the stack size is 2 if(!s.empty()) s.pop(); //元素2 弹出栈 printf(\u0026#34;Now the top element is %d\\n\u0026#34;,s.top()); //Now the top element is 1 printf(\u0026#34;Now the stack size is %d\\n\u0026#34;,s.size()); //Now the stack size is 1 if(s.empty()) printf(\u0026#34;stack is empty\\n\u0026#34;); else printf(\u0026#34;stack is not empty\\n\u0026#34;); //stack is not empty if(!s.empty()) s.pop(); //元素1 弹出栈 if(s.empty()) printf(\u0026#34;stack is empty\\n\u0026#34;); //stack is empty else printf(\u0026#34;stack is not empty\\n\u0026#34;); } /* 运行结果 Now the top element is 2 Now the stack size is 2 Now the top element is 1 Now the stack size is 1 stack is not empty stack is empty */ 映射(map) 概述 map是STL的一个关联容器,提供一对一的数据处理能力,可以建立两个数据之间一一映射关系,map的定义需要关键字和存储值两个参数,我们可以通过关键字来查找对应的存储值(感觉类似于下标可以为任何类型的数组)吧,因为map的底层实现为红黑树(虽然我没学过),所以具有自动排序功能,也就是说map内部有序。\n用法 使用之前声明头文件 #include\u0026lt;map\u0026gt; ,通过 map\u0026lt;typename,typename\u0026gt; m 的形式来定义映射,如果我们要建立string和int这两个类型之间的一一映射,就可以写成 map\u0026lt;string,int\u0026gt; m ,我们可以通过关键字string来查找对应的int值。下述的讲述我们用这个m这个映射来进行。\n迭代器 迭代器就是类似于指针吧,我们可以通过map\u0026lt;string,int\u0026gt;::iterator it ,来定义一个对应映射的迭代器,他能够用来指向map中的元素,通过它们我们可以对map执行定点删除,遍历等操作。\n主要函数及用途 1. 插入数据 通过insert函数进行插入 m.insert(pair\u0026lt;string,int\u0026gt;(\u0026quot;zs\u0026quot;,1)) m.insert(make_pair(\u0026quot;zs\u0026quot;,2)) 通过类似于数组的形式插入 m[\u0026quot;zs\u0026quot;] = 2 上述两种形式有一定的区别,因为集合中元素是唯一的,用insert函数插入的时候,如果已经有相应的关键字,那么就不会插入。而如果用类似于数组的方式进行插入,就会覆盖原关键字对应的值。\nmap\u0026lt;string,int\u0026gt; m; int main() { m.insert(pair\u0026lt;string,int\u0026gt;(\u0026#34;zs\u0026#34;,1)); printf(\u0026#34;%d \u0026#34;,m[\u0026#34;zs\u0026#34;]); m.insert(make_pair(\u0026#34;zs\u0026#34;,2)); printf(\u0026#34;%d \u0026#34;,m[\u0026#34;zs\u0026#34;]); m[\u0026#34;zs\u0026#34;]=2; printf(\u0026#34;%d \u0026#34;,m[\u0026#34;zs\u0026#34;]); /* 输出结果 1 1 2 */ } 2. 查找数据 通过find函数来查找关键字在map中的位置,如果找到了的话就返回对应的迭代器,如果没有找到的话就返回尾部的迭代器(end函数返回的值)。\nmap\u0026lt;string,int\u0026gt; m; int main() { map\u0026lt;string,int\u0026gt;::iterator it; m[\u0026#34;zs\u0026#34;]=1; it=m.find(\u0026#34;zs\u0026#34;); cout\u0026lt;\u0026lt;it-\u0026gt;first\u0026lt;\u0026lt;\u0026#34; \u0026#34;\u0026lt;\u0026lt;it-\u0026gt;second; /* 输出结果 zs 1 */ } 3. 删除数据 清空map,可以使用clear函数。 删除特定元素 先用find函数找到特定元素的迭代器,通过erase函数清除。 直接通过相应关键字清除。 删除一串序列,通过erase(起始迭代器,终点迭代器) 来实现。 map\u0026lt;string,int\u0026gt; m; int main() { map\u0026lt;string,int\u0026gt;::iterator it; m[\u0026#34;zs\u0026#34;]=1; it=m.find(\u0026#34;zs\u0026#34;); m.erase(it); it=m.find(\u0026#34;zs\u0026#34;); if(it==m.end()) printf(\u0026#34;Not find zs\\n\u0026#34;); m[\u0026#34;zs\u0026#34;]=2; m.erase(\u0026#34;zs\u0026#34;); it=m.find(\u0026#34;zs\u0026#34;); if(it==m.end()) printf(\u0026#34;Not find zs\u0026#34;); /* 输出结果 Not find zs Not find zs */ } 4. 其他 count(\u0026ldquo;关键字\u0026rdquo;) 查询相应关键字在map中是否出现过,出现过返回1,没出现返回0 empty( ) 判断是否为空,空返回true,不空返回false begin( ) \u0026amp; end( ) 分别为返回头和尾迭代器,配合迭代器可实行遍历 iterator-\u0026gt;first \u0026amp; iterator-\u0026gt;second 分别对应相应迭代器指向的元素的关键字和值 集合(set) 概述 set为一个容器,用来存储同一数据类型的数据,并且能从一个数据集合中取出数据,在set中每个元素的值都唯一(集合的唯一性),并且内部能根据元素的值自动进行排序。\n用法 使用之前需要声明头文件 #include\u0026lt;set\u0026gt; ,通过 set\u0026lt;typename\u0026gt; s 来定义一个存储数据类型为typename的集合,名字叫做s。下述实例用此做基础。\n迭代器 通过set\u0026lt;typename\u0026gt;::iterator it,可以来定义一个相应的set的迭代器,用来遍历和指向其中元素。\n主要函数及用途 1. 插入数据 插入特定元素可以通过 s.insert(3) 插入对应键值,返回值为pair\u0026lt;set::iterator,bool\u0026gt; ,后续bool变量标志是否成功,如果元素3已经存在,那么bool值为false,迭代器对应的是该元素在其中的位置,如果元素不存在其中,返回true,并且返回的迭代器对应的在集合中位置 插入一个区间的元素,例如有整数数组a ,可以用 s.insert(a,a+3) ,可以将a中的 a[0] a[1] a[2] 插入到set中。 2. 删除数据 删除和map非常像,也是三种。具体可参考map讲解。\n3. 查找元素 也是可以通过find函数,也是和map非常的像~\n4. 其他 begin() \u0026amp; end( ) 返回头尾迭代器,注意尾迭代器是尾元素的后一位。 clear( ) 清除set容器中所有元素 empty( ) 判断set容器是否为空,为空则返回true,不空返回false size( ) 返回当前set容器中元素的个数 rebegin( ) \u0026amp; rend( ) 返回尾和头迭代器,配合reverse_iterator可以反序遍历set 关于vector和string等 vector好的学习文章 : C++ vector容器浅析\nstring好的学习文章 : C++ STL(一)介绍及string\n","permalink":"https://blog.zzsqwq.cn/posts/28/","summary":"\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003eSTL之前只会用 stack 和 queue ,set 和 map 啥的也不太会用。学习一下。\u003c/p\u003e","title":"关于STL的一些总结"},{"content":"A. 配对 题意 给定含有 $n$ 个正整数的集合 $A$ 和 $B$ ,你需要建立他们之间的一一映射。将配对的两个数相加可以得到 $n$ 个和,问第 $k$ 大的和最大为多少。\n思路 首先我们可以确定,组成前 $k$ 个最大的和一定用的是两个序列里面前 $k$ 大的数字。那么我们只需要知道如何配对能使第 $k$ 大的和最大。我们把问题简化一下如果 $A_1 \u0026lt; A_2$ ,$B_1 \u0026lt; B_2$ ,那么如果想要第二个和最大,肯定是需要 $A_1$ 和 $B_2$ 匹配,$A_2$ 和 $B_1$ 匹配,然后两个选一个最小的。所以这个问题我们类推一下,就是将 $A$ 和 $B$ 序列进行排序,然后取两个里面前 $k$ 个数,$A$ 中大的依次匹配 $B$ 中小的。然后在这 $k$ 个和中取一个最小值即可。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;iostream\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;algorithm\u0026gt; using namespace std; const int maxn=1e5+5; int a[maxn]; int b[maxn]; int n,k,ans=1e9+7; int cmp(int a,int b) { return a\u0026gt;b; } int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;k); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;a[i]); } for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;b[i]); } sort(a+1,a+1+n,cmp); sort(b+1,b+1+n,cmp); for(int i=1;i\u0026lt;=k;i++) { ans=min(ans,a[i]+b[k-i+1]); } printf(\u0026#34;%d\u0026#34;,ans); } B. 十字阵列 题意 给定一个 $n\\times m$ 的网格,每一个交点都一个敌人。你可以使用共 $h$ 次魔法,第 $i$ 次魔法能对第 $x_i$ 行和第 $y_i$ 列的所有敌人造成 $w_i$ 点伤害,交界点的伤害只计算一次。。如果施放完所有所有魔法后,如果一个点 $(i,j)$ 共受到 $z_i$ 点伤害,问 $\\sum{z_i(i+j)}$ 为多少。\n思路 无脑的计数题QAQ..真的是水题啊,我们只需要给每次魔法施放的 $w_i$ 乘上一个 $(i,j)$ 即可,但是因为是一行一列都会变化,那么其实我们可以优化一下,先把一行一列的 $\\sum(i+j)$ 给求出来,然后施法的时候直接乘上这个常数就可以了。(这个题还有个很神奇的地方就是,我明明算的不会爆int然后开的int,然后就错了,后来一直找问题没找出来,后来全改成long long就AC了,太奇怪了。。)\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=2005; typedef long long ll; int mod = 1e9+7; ll row[maxn]; ll col[maxn]; ll x,y,z; ll n,m,h; ll ans,now; int main() { scanf(\u0026#34;%lld%lld%lld\u0026#34;,\u0026amp;n,\u0026amp;m,\u0026amp;h); for(int i=1;i\u0026lt;=n;i++) { row[i]=(m*i)%mod+(m)*(m+1)/2; row[i]%=mod; } for(int j=1;j\u0026lt;=m;j++) { col[j]=(n*j)%mod+(n)*(n+1)/2; col[j]%=mod; } for(int i=1;i\u0026lt;=h;i++) { scanf(\u0026#34;%lld%lld%lld\u0026#34;,\u0026amp;x,\u0026amp;y,\u0026amp;z); now=((row[x]+col[y]-(x+y))%mod)*(z%mod); now%=mod; ans+=now; ans%=mod; } printf(\u0026#34;%lld\\n\u0026#34;,ans); } C. 垃圾陷阱 题意 奶牛卡门想要从垃圾井底上到地面,对于一个垃圾它可以吃掉,或者是堆起来。初始卡门有10个小时的能量,吃掉一个垃圾会给他提供 $f_i$ 个小时的能量,叠起来一个垃圾会获得 $h_i$ 点高度,当垃圾总高度超过井的深度 $D$ 的时候,卡门就能上到地面。一个垃圾当 $t_i$ 小时时会到达井底。给出所有垃圾的状态,问奶牛能否到达地面。\n思路 这个题面被我翻译的屎一样,QAQ,如果看不懂还是去看原题叭。。 这是一个类似于背包的题,对于一个垃圾,我们有两种选择,一个是吃掉它,一个是把他堆起来。。这个状态其实我没找好,看了题解发现可以设 $f[i][j]$ 来表示当用了前 $i$ 个垃圾时,当高度为 $j$ 的时候的最大的体力值(体力值就是还能继续活动多长时间)。我们用结构体数组 $a$ 来表示垃圾,写出如下转移方程。\n如果选择把这个垃圾吃掉,那么 $f[i][j]=max(f[i-1][j]+a[i].f,f[i][j])$\n如果选择把这个垃圾搭起来,那么$f[i][j+a[i].h]=max(f[i-1][j+a[i].h],f[i-1][j])$\n我们发现边界就是 $f[0][0]=10$ ,也就是用了0个垃圾,高度为0的时候体力值为10。\n注意一个地方我们如果到达了地面,就直接输出时间,然后退出程序即可,如果没有的话,我们可以选择遍历每一个垃圾下的 $0$ 高度,也就是说所有垃圾都不叠是最长的寿命,所以输出一个其中的最大值即可。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=105; struct node { int t,f,h; }a[maxn]; int cmp(node a,node b) { return a.t\u0026lt;b.t; } int d,g; int dp[maxn][maxn]; //dp[i][j] 用i个垃圾,当高度为j时所具备的最高生命值 int main() { freopen(\u0026#34;test.in\u0026#34;,\u0026#34;r\u0026#34;,stdin); scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;d,\u0026amp;g); for(int i=1;i\u0026lt;=g;i++) { scanf(\u0026#34;%d%d%d\u0026#34;,\u0026amp;a[i].t,\u0026amp;a[i].f,\u0026amp;a[i].h); } sort(a+1,a+1+g,cmp); memset(dp,-1,sizeof(dp)); dp[0][0]=10; for(int i=1;i\u0026lt;=g;i++) { for(int j=0;j\u0026lt;=d;j++) { if(dp[i-1][j]\u0026gt;=a[i].t) { if(j+a[i].h\u0026gt;=d) { printf(\u0026#34;%d\u0026#34;,a[i].t); return 0; } dp[i][j]=max(dp[i-1][j]+a[i].f,dp[i][j]); dp[i][j+a[i].h]=max(dp[i-1][j+a[i].h],dp[i-1][j]); } } } int ans=0; for(int i=1;i\u0026lt;=g;i++) ans=max(ans,dp[i][0]); printf(\u0026#34;%d\u0026#34;,ans); } ","permalink":"https://blog.zzsqwq.cn/posts/27/","summary":"\u003ch2 id=\"a-配对httpsacnowcodercomacmcontest3007a\"\u003eA. \u003ca href=\"https://ac.nowcoder.com/acm/contest/3007/A\"\u003e配对\u003c/a\u003e\u003c/h2\u003e\n\u003ch3 id=\"题意\"\u003e题意\u003c/h3\u003e\n\u003cp\u003e给定含有 $n$ 个正整数的集合 $A$ 和 $B$ ,你需要建立他们之间的一一映射。将配对的两个数相加可以得到 $n$ 个和,问第 $k$ 大的和最大为多少。\u003c/p\u003e","title":"杂题训练"},{"content":"A. Three Strings 题意 给定三个长度为 $n$ 的字符串 $a$ , $b$ , $c$ ,遍历每个 $c$ 中每个字符 $c_i$,可以将其替换成 $a_i$ 或者 $b_i$ ,必须操作其中一个,问能否通过此操作使得字符串 $a$ , $b$ 相同。\n思路 仔细思考一下,如果要使得最终两个字符串相同的话,必须字符串 $c$ 中出现的字符,在 $a$ 或者 $b$ 字符串出现过,如果每个位置都出现过,那么就是可以的,否则不行。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=105; char a[maxn],b[maxn],c[maxn]; int t; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { scanf(\u0026#34;%s\u0026#34;,a); scanf(\u0026#34;%s\u0026#34;,b); scanf(\u0026#34;%s\u0026#34;,c); int len=strlen(c); bool flag=true; for(int i=0;i\u0026lt;len;i++) if(c[i]!=a[i]\u0026amp;\u0026amp;c[i]!=b[i]) { flag=false; } if(flag) { printf(\u0026#34;YES\\n\u0026#34;); } else printf(\u0026#34;NO\\n\u0026#34;); } return 0; } B. Motarack\u0026rsquo;s Birthday 题意 给定一个含有 $n$ 个整数的序列 $a$ ,其中有一些数丢失,问将丢失的数赋值为多少才能使得相邻两数之差的绝对值的最大值的最小。\n思路 我们想一下首先不缺失的数相邻两数之差是一定,无论赋值前后都不影响。而如果两个相邻的数都缺失的话,那么他们之间差的绝对值一定是0,也不用去看。这样的话我们就看一下,不缺失和缺失两数之间差的绝对值如何能够最小。因为最终所有的缺失的数都是赋值为同一个数,所以我们考虑一下发现需要考虑一下 缺失和不缺失的数相邻的时候,不缺失的那个数的最大值和最小值,我们只需要取他们的和的平均,那么绝对值就可以最小了。所以最终我们就把缺失的值赋为两数均值,然后求一遍相邻数之差绝对值的最大值就好了。(好像这道题难点不是思路,而是实现起来有很多边界等乱七八糟的要自习考虑一下。)\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=100005; const int inf=1000000000; int n,t; int a[maxn]; int minn,maxx,ans,anss; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { minn=inf,maxx=-inf,anss=-inf; scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;a[i]); if(i\u0026gt;1\u0026amp;\u0026amp;a[i]==-1\u0026amp;\u0026amp;a[i-1]!=-1) { minn=min(minn,a[i-1]); maxx=max(maxx,a[i-1]); } } for(int i=1;i\u0026lt;=n;i++) { if(i\u0026lt;n\u0026amp;\u0026amp;a[i]==-1\u0026amp;\u0026amp;a[i+1]!=-1) { minn=min(minn,a[i+1]); maxx=max(maxx,a[i+1]); }\t} ans=(minn+maxx)/2; for(int i=1;i\u0026lt;=n;i++) { if(a[i]==-1) a[i]=ans; if(i\u0026gt;1) anss=max(anss,abs(a[i]-a[i-1])); } printf(\u0026#34;%d %d\\n\u0026#34;,anss,ans); } return 0; } C. Ayoub\u0026rsquo;s function 题意 给定一个01字符串 $s$ ,其中含有 $m$ 个1,用 $f(s)$ 来表示字符串 $s$ 的有多少个字串其中含有1,求出符合条件的字符串 $s$ 中, $f(s)$ 的最大值是多少。\n思路 这题正着想不太好想,含有1的子串可以有很多种情况,但是正难则反,我们可以求出不含1的字串有多少情况,也就是全0的字串有多少种情况,然后用所有情况减去这个就行。 首先可以发现字符串 $s$ 一共有 $\\binom{n}{2}+n$ 种连续子串,那么如果一些0是连续的,那么好比有连续 $l$ 个0的话,我们可以发现他是有 $\\binom{l}{2}+l$ 种情况的。这个字符串一共是含有 $n-m$ 个0的,现在我们思考一下如何摆放这 $(n-m)$ 个0,才能使得 $f(s)$ 最大。那么如果 $f(s)$ 要尽量大,也就是说全0对应的情况就要尽可能的少,所以我们需要将这 $n-m$ 尽可能的均分成 $m+1$ 份,类似于排列组合的插空法,将他们插到其中,但是我们发现有很大的可能是不能均分的,也就是说可能会有余数,那么我们就把余数均匀的分给前面余数个空,这样其实每个多贡献了 $(n-m)/(m+1) +1 $ 个。所以答案也就不难写出来了。不过不要忘了开long long。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; typedef long long ll; ll n,m; ll t; int main() { scanf(\u0026#34;%lld\u0026#34;,\u0026amp;t); while(t--) { scanf(\u0026#34;%lld%lld\u0026#34;,\u0026amp;n,\u0026amp;m); ll sum=n*(n+1)/2; ll p=n-m; ll mod=p%(m+1); ll k=p/(m+1); printf(\u0026#34;%lld\\n\u0026#34;,sum-(m+1)*k*(k+1)/2-(k+1)*mod); } return 0; } ","permalink":"https://blog.zzsqwq.cn/posts/26/","summary":"\u003ch2 id=\"a-three-stringshttpscodeforcescomcontest1301problema\"\u003eA. \u003ca href=\"https://codeforces.com/contest/1301/problem/A\"\u003eThree Strings\u003c/a\u003e\u003c/h2\u003e\n\u003ch3 id=\"题意\"\u003e题意\u003c/h3\u003e\n\u003cp\u003e给定三个长度为 $n$ 的字符串 $a$ , $b$ , $c$ ,遍历每个 $c$ 中每个字符 $c_i$,可以将其替换成 $a_i$ 或者 $b_i$ ,必须操作其中一个,问能否通过此操作使得字符串 $a$ , $b$ 相同。\u003c/p\u003e","title":"Codeforces#619 (Div.2)"},{"content":"前言 今天又是颓废的一天,被大佬拉去跟他一起做牛客网的题,QAQ\u0026hellip;那我会点啥嘛,就只能替大佬写两道水题了···\nA. 牛牛战队的比赛地 题意 由于牛牛战队经常要外出比赛,因此在全国各地建立了很多训练基地,每一个基地都有一个坐标 $(x,y)$ 。 这周末,牛牛队又要出去比赛了,各个比赛的赛点都在 $x$ 轴上。牛牛战队为了方便比赛,想找一个到达训练基地最大距离最小的地方作为比赛地。请你求出选择的比赛地距离各训练基地最大距离的最小值。\n思路 这个题首先一看到这种什么最大的最小,第一直觉就是二分。首先我们想一下应该二分什么,肯定先想的是枚举 $x$ 轴上的点,但是这样就会有个问题,二分要用的话必须是单调的,那么我们不能够确定越往右或者越往左,他们的这个值是单调的。因此我们可以用三分,一直向单峰逼近,最终寻找到那个极值点。(说实话这是我第一次接触到三分法,我太菜了。)\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;iostream\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;algorithm\u0026gt; using namespace std; const int maxn=100005; struct node { int x,y; }p[maxn]; //point int n; const double eps=1e-6; double lmid,rmid,lans,rans; double check(double x) { double ans=0; for(int i=1;i\u0026lt;=n;i++) { double dis=(p[i].x-x)*(p[i].x-x)+p[i].y*p[i].y; ans=max(ans,dis); } return ans; } int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;p[i].x,\u0026amp;p[i].y); } double l=-10000,r=10000; double ans=9999999999; while(r-l\u0026gt;=eps) { lmid=(r+l)/2; rmid=(r+lmid)/2; lans=check(lmid); rans=check(rmid); if(lans\u0026lt;rans) { ans=min(ans,lans); r=rmid; } else { ans=min(ans,rans); l=lmid; } } printf(\u0026#34;%lf\u0026#34;,sqrt(ans)); return 0; } B. 牛牛与牛妹的约会 题意 你想从 $(a,0)$ 点到 $(b,0)$ 点,你可以除了可以以 $1m/s$ 的速度奔跑,还可以用1秒的时间来引导闪现,这将使你从 $(x,0)$ 点闪现到 $(\\sqrt[3]{x},0)$ 点,问最少需要多长时间到达 $(b,0)$ 点。$(Ps:a,b \\in[-10^6,10^6])$\n思路 一道贪心的题目,当闪现所能贡献的距离大于 $1m$ ,那么我就选择用闪现,不然就直接奔跑。那么我们可以用距离的变化来体现闪现贡献的距离,一直用闪现到不能用之后,就直接加上最后剩下的距离即可。注意pow这个函数有点坑?如果底数是负数并且指数不是整数的话好像会返回很奇怪的值···(跟大佬调了好长时间都卡在这了)\n代码实现 #include\u0026lt;iostream\u0026gt; #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;algorithm\u0026gt; using namespace std; int t,x,y; double ans,a,b; double dis,cdis; int main(void) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;x,\u0026amp;y); a =(double)x; b=(double)y; dis = abs(a-b); if(a\u0026lt;0) { cdis=abs(-pow(-a,1.0/3.0)-b); } else cdis = abs(pow(a,1.0/3.0)-b); ans = 0; while(dis-cdis\u0026gt;1.0) { if(a\u0026lt;0) { a=-pow(-a,1.0/3.0); } else a=pow(a,1.0/3.0); ans+=1; dis = cdis; if(a\u0026lt;0) { cdis = abs(-pow(-a,1.0/3.0)-b); } else cdis = abs(pow(a,1.0/3.0)-b); } ans+=dis; printf(\u0026#34;%.9lf\\n\u0026#34;,ans); } return 0; } C. 碎碎念 题意 大佬豪和弱鸡战合作做题,如果大佬豪AC掉题目,那么弱鸡战会说 “宁好强啊!”,如果大佬豪WA掉了题目,那么弱鸡战会嘲讽大佬豪 $k$ 句 “宁好弱啊!” 。我们规定大佬豪提交只有AC和WA两种状态。因为大佬豪非常的强,如果一道题他WA掉了一发,那么他的下一发一定会AC。如果已知最终弱鸡战嘲讽了 $x$ 句,那么很明显可以对应很多的提交序列。现在想问你如果弱鸡战嘲讽数在 $[l,r]$ 这个区间,一共会有多少种提交序列。答案对 $1e9+7$ 取模。\n思路 首先原始题面不是这样,我把名字改了一下,QAQ\u0026hellip; QAQ刷了这么多天的dp好像终于有点作用了,我终于看出来这是一道dp题了,还找对了他们的状态,不过转移方程却写错了。那么首先我们可以用 $f[i]$ 来表示,如果说了 $i$ 句话,那么一共有多少种可能的序列,但是这样的话我们发现没法确保上文上的如果WA掉了,下一发一定是AC。 所以我们可以考虑加一维状态来表示是通过哪种提交状态到达第 $i$ 句话的,也就是写成 $dp[0/1][i]$ 这个状态,$dp[0][i]$ 代表是从 $i-1$ 句话直接AC转移过来的,$dp[1][i]$ 是从 $i-k$ 句话通过WA转移过来的。所以这样的话转移方程就可以写出来了。\n$dp[0][i] = dp[0][i-1]+dp[1][i-1]$ (可以从WA和AC转移过来)\n$dp[1][i]=dp[0][i-k]$ (只能从第 $i-k$ 状态是AC的时候转移,不能连续两次WA)\n因为最终是一个区间查询,那么我们可以用前缀和来优化。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; using namespace std; const int maxn=100005; int k,q; int l,r; int mod =1e9+7; int dp[2][maxn]; int sum[maxn]; int ans[maxn]; int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;k,\u0026amp;q); dp[0][0]=1; for(int i=1;i\u0026lt;=100000;i++) { dp[0][i]=dp[0][i-1]+dp[1][i-1]; dp[0][i]%=mod; if(i\u0026gt;=k) { dp[1][i]=dp[0][i-k]; dp[1][i]%=mod; } ans[i]=dp[0][i]+dp[1][i]; ans[i]%=mod; sum[i]=sum[i-1]+ans[i]; sum[i]%=mod; } for(int i=1;i\u0026lt;=q;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;l,\u0026amp;r); printf(\u0026#34;%d\\n\u0026#34;,(sum[r]-sum[l-1]+mod)%mod); } return 0; } D. 牛牛战队的秀场 题意 在半径为 $r$ 的圆内有一个正接 $n$ 边形,随便选取一个顶点编号为 $1$ ,顺时针编号为 $2\\sim n$ ,规定只能沿多边形边走,问从顶点 $i$ 到顶点 $j$ 最短路径为多少。\n思路 很显然只有两条路可以走,我们只需要算出正多边形的每条边的边长,然后比较两条路径的大小,哪一个短就走哪一个就行,不过如果用了cos() 函数记得特判一下 $n=4$ 的情况,不然会发生错误。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; int n,ri; double r; int i,j; double pi = 3.1415926535898; int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;ri); scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;i,\u0026amp;j); double k=(double)2*pi/(double)n; double s; r=(double)ri; if(n==4) { s=sqrt(2*r*r); } else s=sqrt((double)2*r*r-2.0*r*r*cos(k)); int p=abs(i-j); if(p\u0026gt;n/2) { printf(\u0026#34;%lf\u0026#34;,s*(n-p)); } else printf(\u0026#34;%lf\u0026#34;,s*p); return 0; } ","permalink":"https://blog.zzsqwq.cn/posts/25/","summary":"\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003e今天又是颓废的一天,被大佬拉去跟他一起做牛客网的题,QAQ\u0026hellip;那我会点啥嘛,就只能替大佬写两道水题了···\u003c/p\u003e","title":"日常水题"},{"content":"A. 方格取数 题意 有一个 $N*N$ 的整数方阵,每个点初始值为0,在一些点上放上数,一个人从左上角走到右下角,规定只能向下或向右走,当他经过的点上有数时会取走它,问走两遍最多能取的数的和最大为多少。\n思路 也就是说我们要找两条路径使他取数最大,首先我一开始想法是先走一遍,找到最大的那个路径,将这条路径上所有点设为0,然后再回来找这个方阵中最大的那个路径,两个加起来就行。但是路径上所有的点设为0这个地方不是很好实现,因此我们可以考虑另一个思路,两次同时走。我们把这两次看成两个人走的,表述方便。 我们用 $dp[i][j][k][l]$ 来表示当第一个人走到 $(i,j)$ 第二个人走到 $(k,l)$ 时做能取数最多为多少 ,那么我们就可以考虑一下转移怎么转移,因为到达一个点只能是从左边来,或者是从上边来,因此第一个人从 $(i-1,j)$ 或者 $(i,j-1)$ 转移来,那么第二个人就从 $(k-1,l)$ 或者 $(k,l-1)$ 转移来,那么这个转移方程就是四种转移方式。我们需要保证一个问题,就是他俩经过同一个点的判定情况。我们需要将第二个人的坐标通过第一个人来限制,也就是说要确保第二个人和第一个人步数是相同的,当他们步数相同的时候,那么就不存在他们经过同一个点但是时间却是不同的情况了,因为到达一个点的步数是一定的。 再就是这个状态数组其实还是可以压缩到三维和二维的,这个就先不谈了,可以看洛谷的题解区。 这个题是一个经典的多维dp的题目,感觉还是挺有意义的。而且这个题和 传纸条 很像,可以双倍经验。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=15; int map[maxn][maxn]; int n,x,y,z; int m; int dp[maxn][maxn][maxn][maxn]; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); while(1) { scanf(\u0026#34;%d%d%d\u0026#34;,\u0026amp;x,\u0026amp;y,\u0026amp;z); if(x==0\u0026amp;\u0026amp;y==0\u0026amp;\u0026amp;z==0) break; map[x][y]=z; } for(int i=1;i\u0026lt;=n;i++) { for(int j=1;j\u0026lt;=n;j++) { for(int k=1;k\u0026lt;=n;k++) { m=i+j-k; if(m\u0026lt;=0) continue; if(i==k\u0026amp;\u0026amp;j==m) dp[i][j][k][m]=max(max(dp[i-1][j][k-1][m],dp[i-1][j][k][m-1]),max(dp[i][j-1][k-1][m],dp[i][j-1][k][m-1]))+map[i][j]; else dp[i][j][k][m]=max(max(dp[i-1][j][k-1][m],dp[i-1][j][k][m-1]),max(dp[i][j-1][k-1][m],dp[i][j-1][k][m-1]))+map[i][j]+map[k][m]; } } } printf(\u0026#34;%d\u0026#34;,dp[n][n][n][n]); return 0; } B. 创意吃鱼法 题意 给出一个 $N*M$ 的只包含0和1的数阵,求只有对角线为1,其余位置为0的子方阵的最大边长。\n思路 这个题我们需要考虑两个方向,这个对角线既可以是斜向左上,也可以是斜向右上的。我们先考虑前者,后者同理即可。我们可以用两个数组 $col[i][j]$ 和 $row[i][j]$ 分别来表示,包含 $(i,j)$ 这个点往上一列有多少个0,以及包含这个点往左一行有多少个0,(这个在程序里好像我写反了,但是没啥区别说实话)。然后我们用 $f[i][j]$ 来表示,从这个点左上走满足条件的方阵的最大边长。那么很显然这个值和上方的0,左方的0,以及左上的状态有关,这个点是1的话,转移方程就是 $f[i][j]=min(f[i-1][j-1],min(col[i-1][j],row[i][j-1]))+1$ 。如果是0的话我们就更新 $col$ 和 $row$ 数组的值。然后求完斜向左上的再求一遍斜向右上的,取一个最大值即可。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=2505; int n,m; int map[maxn][maxn]; int col[maxn][maxn],row[maxn][maxn]; int dp[maxn][maxn]; int ans; int main() { //\tfreopen(\u0026#34;test.in\u0026#34;,\u0026#34;r\u0026#34;,stdin); scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;m); for(int i=1;i\u0026lt;=n;i++) { for(int j=1;j\u0026lt;=m;j++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;map[i][j]); if(!map[i][j]) { row[i][j]=row[i-1][j]+1; col[i][j]=col[i][j-1]+1; } else { dp[i][j]=min(dp[i-1][j-1],min(row[i-1][j],col[i][j-1]))+1; ans=max(dp[i][j],ans); } } } memset(row,0,sizeof(row)); memset(col,0,sizeof(col)); memset(dp,0,sizeof(dp)); for(int i=1;i\u0026lt;=n;i++) { for(int j=m;j\u0026gt;=1;j--) { if(!map[i][j]) { row[i][j]=row[i-1][j]+1; col[i][j]=col[i][j+1]+1; } else { dp[i][j]=min(dp[i-1][j+1],min(row[i-1][j],col[i][j+1]))+1; ans=max(ans,dp[i][j]); } } } printf(\u0026#34;%d\u0026#34;,ans); } C. 乌龟棋 题意 给出标号分别为1,2,3,4的四种卡片若干张,分别可以移动1,2,3,4步,玩家初始处于坐标为1的位置。玩家出一张牌,可移动相应的步数。移动到不同的坐标会加不同的分数,很明显不同的出牌顺序会对应着不同的分数,求玩家能获得的最大分数为多少。\n思路 很显然我们可以通过已经出的牌计算出现在已经到达到哪个位置。我们可以用一个四重循环,来循环每张牌用的数量,很明显我们到达一个目标位置所用的最后一张牌可以是1,2,3,4的任何一个,因此我们可以从这个四个状态转移过来,找其中最大那个就可以了,注意要判断一下要转移过来的状态是否合法。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=355; const int maxm=125; int n,m,pos; int w[maxn]; int x,num[5]; int dp[42][42][42][42]; int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;m); for(int i=1;i\u0026lt;=n;i++) scanf(\u0026#34;%d\u0026#34;,\u0026amp;w[i]); for(int i=1;i\u0026lt;=m;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;x); num[x]++; } memset(dp,-1,sizeof(dp)); dp[0][0][0][0]=w[1]; for(int a=0;a\u0026lt;=num[1];a++) { for(int b=0;b\u0026lt;=num[2];b++) { for(int c=0;c\u0026lt;=num[3];c++) { for(int d=0;d\u0026lt;=num[4];d++) { pos=1+a+(b\u0026lt;\u0026lt;1)+c*3+(d\u0026lt;\u0026lt;2); if(a\u0026gt;0\u0026amp;\u0026amp;dp[a-1][b][c][d]!=-1) { dp[a][b][c][d]=max(dp[a][b][c][d],dp[a-1][b][c][d]+w[pos]); } if(b\u0026gt;0\u0026amp;\u0026amp;dp[a][b-1][c][d]!=-1) { dp[a][b][c][d]=max(dp[a][b][c][d],dp[a][b-1][c][d]+w[pos]); } if(c\u0026gt;0\u0026amp;\u0026amp;dp[a][b][c-1][d]!=-1) { dp[a][b][c][d]=max(dp[a][b][c][d],dp[a][b][c-1][d]+w[pos]); } if(d\u0026gt;0\u0026amp;\u0026amp;dp[a][b][c][d-1]!=-1) { dp[a][b][c][d]=max(dp[a][b][c][d],dp[a][b][c][d-1]+w[pos]); } } } } } printf(\u0026#34;%d\u0026#34;,dp[num[1]][num[2]][num[3]][num[4]]); return 0; } D. 能量项链 题意 给出一段含有 $n$ 个珠子的环状项链,对于相邻的两个珠子,前一颗珠子的尾标记等于后方珠子的头标记。 例如项链为 $[2,4,6,8]$ , 那么用加入标记表示就是 $[(2,4),(4,6),(6,8),(8,2)]$ 。当两个珠子两两合并的时候会产生的能量大小为 前方珠子头标记 $\\times$ 前方珠子尾标记 $\\times$ 后方珠子尾标记。显然合并的顺序不同最终会产生不同的能量值,问能产生的最大能量值为多少。\n思路 这道题和合并石子很像,也是一个区间dp的例题,我们也是通过枚举区间长度,然后枚举区间断点来分割区间。这个题也是一个环状,我们也是断环为链,不过处理释放的能量值的问题,我是用了一个结构体,来表示每一颗珠子的标记,通过这个来计算释放能量。不过记得处理子区间也要从处理到 $1\\sim 2n$, 这个地方卡了我巨长时间,因为你后面要用到这个状态,如果不计算子区间无法转移到后面。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; typedef long long ll; const int maxn=105; int n; ll dp[maxn\u0026lt;\u0026lt;1][maxn\u0026lt;\u0026lt;1]; struct node { ll w; ll nxt; }a[maxn\u0026lt;\u0026lt;1]; int main() { //\tfreopen(\u0026#34;test.in\u0026#34;,\u0026#34;r\u0026#34;,stdin); scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%lld\u0026#34;,\u0026amp;a[i].w); a[i+n].w=a[i].w; } for(int i=1;i\u0026lt;=n*2-1;i++) { a[i].nxt=a[i+1].w; } for(int i=1;i\u0026lt;=2*n;i++) dp[i][i]=0; for(int p=2;p\u0026lt;=n;p++) { for(int i=1;i\u0026lt;=2*n-p+1;i++) //重要(卡我巨长时间) { int j=i+p-1; for(int k=i;k\u0026lt;j;k++) { dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+a[i].w*a[k].nxt*a[j].nxt); } } } //\tfor(int i=1;i\u0026lt;=n;i++) //\t{ //\tprintf(\u0026#34;%d \u0026#34;,dp[i][i+1]); //\t} ll ans=0; for(int i=1;i\u0026lt;=n;i++) ans=max(ans,dp[i][i+n-1]); printf(\u0026#34;%lld\u0026#34;,ans); return 0; } ","permalink":"https://blog.zzsqwq.cn/posts/24/","summary":"\u003ch2 id=\"a-方格取数httpswwwluogucomcnproblemp1004\"\u003eA. \u003ca href=\"https://www.luogu.com.cn/problem/P1004\"\u003e方格取数\u003c/a\u003e\u003c/h2\u003e\n\u003ch3 id=\"题意\"\u003e题意\u003c/h3\u003e\n\u003cp\u003e有一个 $N*N$ 的整数方阵,每个点初始值为0,在一些点上放上数,一个人从左上角走到右下角,规定只能向下或向右走,当他经过的点上有数时会取走它,问走两遍最多能取的数的和最大为多少。\u003c/p\u003e","title":"dp习题练习"},{"content":"前言 最近感觉遇到了好多单调队列和单调栈的问题,但是因为以前没学好,所以遇见了就一脸懵逼,然后绝对下决心来学一下。。感觉遇到啥都不会,这可咋办呐。。补不完的漏洞。 单调队列(Monotone queue) 单调队列,即单调递减或单调递增的队列。使用频率不高,但在有些程序中会有非同寻常的作用。\n理解 顾名思义,他就是一个单调的队列,那么我们可以规定他是单调递增的还是单调递减的,他和普通的队列有点区别,队列一般是尾进头出,而单调队列要实现的话要确保头和尾都可以出,尾可以进。如果要用STL库的话可以用里面的双端队列。 跟普通队列相比他的进队需要确保一个条件就是要不破坏原有序列的单调性,好比我们有一个单调递增的单调队列,也就是从队首到队尾是单调递增的,那么有一段序列是 $[2,3,1,5,8,7,4,2]$ ,我们从左到右依次入队。\n队列中元素 关于元素进出的备注 2 2入队 2,3 3比2大,可以满足递增性质,入队 1 因为1比2,3都小,要满足递增性质,先把2,3出队,再将1入队 1,5 5比1大,可以满足递增性质,入队 1,5,8 8比5大,可以满足递增性质,入队 1,5,7 7小于8,大于5,要满足递增性质,我们把8出队,然后将7入队 1,4 4小于5、7,但是大于1,因此7,5依次出队,4入队 1,2 2小于4,大于1,因此4出队,2入队 根据上述例子不难看出,我们要入队的时候首先要确保队尾元素要比想要入队的元素小,然后才能入队,否则的话就一直循环让尾部元素出队,直到能够满足单调性为止。\n单调队列的应用 求区间的最值问题。下面写的两个例题都是这个用处。 优化dp,我现在能接触到的就是一个用单调队列优化多重背包的一个题,但是那个题我学了这个东西之后还是不理解为什么可以那么做。例题如下:宝物筛选 单调队列的一些例题 A. Sliding Window 题意 给出一个含有 $n$ 个整数的序列 $a$ ,给出滑动窗口长度 $k$ ,窗口从序列最左端滑动到序列最右端,问滑动过程中每个时刻窗口中最大值和最小值是多少。\n思路 一道很经典的单调队列的模板题,用于解决定长区间的最大最小值。我们可以维护两个单调队列,一个是单调递增的,一个是单调递减的。因为两种情况类似,我们考虑一下求窗口中最大值的方案。\n求最大值我们用的是单调递减的序列,这样就能够保证每次队首的就是答案,但是,这是为什么呢?我们来考虑一下,因为这是一个单调递减的序列,那么我们每次序列元素入队的时候,我们就去看当前队尾的元素是不是要比他大,如果比他还小,那么我们就直接将队尾元素出队,因为这时候要入队的元素(已经被窗口覆盖了)已经比他大了,那么在接下来的窗口中,肯定就没他什么事了,因为它一定不是最大的,那么如果一直将队尾元素出队到加入入队元素后还继续能保持队列的单调性了,但是这个元素还不是在队首,这就说明,队首的元素还是要比他大的(单调性易得)。\n所以这时候队首元素就是这个窗口中最大的了吗?也还不能确定,因为我们还不能确保这个队首元素就在窗口中,因此我们需要看看这个元素的位置和当前入队元素的位置之差是不是要比窗口长度大了,如果大于窗口长度,那么就说明队首元素已经不在窗口了,我们就将队首元素出队,最后输出队首元素就能确保它既在窗口中,又是窗口中所有元素的最大值了!\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=1000005; int n,k; int head,tail,a[maxn]; struct node { int pos,value; }q[maxn]; void getmax() { head=tail=0; for(int i=1;i\u0026lt;=n;i++) { while(head!=tail\u0026amp;\u0026amp;i-q[head].pos\u0026gt;=k) head++; while(head!=tail\u0026amp;\u0026amp;a[i]\u0026lt;=q[tail-1].value) tail--; q[tail].value=a[i],q[tail++].pos=i; if(i\u0026gt;=k) printf(\u0026#34;%d \u0026#34;,q[head].value); } putchar(\u0026#39;\\n\u0026#39;); for(int i=1;i\u0026lt;=n;i++) q[i].value=q[i].pos=0; } void getmin() { head=tail=0; for(int i=1;i\u0026lt;=n;i++) { while(head!=tail\u0026amp;\u0026amp;i-q[head].pos\u0026gt;=k) head++; while(head!=tail\u0026amp;\u0026amp;a[i]\u0026gt;=q[tail-1].value) tail--; q[tail].value=a[i],q[tail++].pos=i; if(i\u0026gt;=k) printf(\u0026#34;%d \u0026#34;,q[head].value); } } int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;k); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;a[i]); } getmax(); getmin(); return 0; } B. Max Sum of Max-K-sub-sequence 题意 给定长度为 $n$ 的整数循环序列 $a$ ,也就是$a[1],a[2],\\cdots,a[n],a[1]\\cdots$ 这样的序列,问最大连续长度为 $k$ 的连续子区间的序列和最大为多少,并且输出这个区间的左右坐标。\n思路 我们把这道题转换一下,我们先处理好前缀和,好比我们要求 $a[1],a[2],a[3]$ 的序列和,那么也就是 $sum[3]-sum[0]$ ,因此我们在求这个题的时候就可以循环遍历 $1\\sim{n-k+1}$ ,求长度为 $k$ 的定长区间中前缀和数组的最小值即可。但是我们要注意前缀和数组要处理到 $n-k+1$ 。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int inf=1000000; const int maxn=200005; int t; int n,k,a[maxn],sum[maxn]; int head,tail; struct node { int pos,value; }q[maxn]; int ans,l,r; int main() { //\tfreopen(\u0026#34;test.in\u0026#34;,\u0026#34;r\u0026#34;,stdin); scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { l=r=0; head=tail=0; ans=-inf; scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;k); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;a[i]); sum[i]=sum[i-1]+a[i]; } for(int i=n+1;i\u0026lt;=n+k-1;i++) { sum[i]=sum[i-1]+a[i-n]; } for(int i=1;i\u0026lt;=n+k-1;i++) { while(head!=tail\u0026amp;\u0026amp;i-q[head].pos\u0026gt;k) head++; while(head!=tail\u0026amp;\u0026amp;sum[i-1]\u0026lt;=q[tail-1].value) tail--; q[tail].pos=i-1,q[tail++].value=sum[i-1]; //\tif(i!=q[head].pos) //\t{ int p=sum[i]-q[head].value; if(p\u0026gt;ans) { ans=p; int k=q[head].pos+1; k\u0026gt;n?l=k%n:l=k; i\u0026gt;n?r=i%n:r=i; } //\t} } printf(\u0026#34;%d %d %d\\n\u0026#34;,ans,l,r); for(int i=1;i\u0026lt;=n+k-1;i++) q[i].pos=q[i].value=-inf; } return 0; } 单调栈(Monotone stack) 单调增或单调减的栈,跟单调队列差不多,但是只用到它的一端。\n理解 单调栈也是在普通栈的基础上加了单调性,一般是用从栈底到栈顶的单调性来命名,好比从栈底到栈顶是单调递增的,那么他就是单调增的栈。跟单调队列一样,他的入栈规则也是要不破坏单调性,因此一个单调递增的栈如果有元素要入栈,如果他比栈顶的元素还要大,就可以直接入栈,如果他比栈顶的元素小,那么就要将栈顶的元素一直出栈到比要入栈元素小为止。如果序列为 $[2,3,1,5,4,7]$,要加入单调递增栈中,过程如下。PS:注意从左到右对应栈底到栈顶。\n栈中的元素 关于元素进出的备注 2 元素2压入栈中 2,3 3大于2,压入栈中 1 1小于3、2,因此全部弹出将1入栈 1,5 5大于1,压入栈中 1,4 4比5小,比1大,弹出5,压入4 1,4,7 7大于4,压入栈中 根据上述描述不难看出,其实单调栈就是单调队列的半部分,他能完成的任务理论上单调队列都能够完成,但是有些时候不需要麻烦的去维护单调队列只需要维护单调栈即可完成。\n单调栈的应用 确定一个元素的左边区间第一个比它大的元素,第一个比它小的元素 确定右边区间第一个比他大or比他小的元素(根据单调性来看) 确定这个元素是否是一定区间内的最值,或者确定以他为最值的区间长度 单调栈的一些例题 A. 单调栈模板 题意 给出含有 $n$ 个整数的序列 $a$ ,定义 $f(i)$ 为第 $i$ 个元素后第一个大于 $a_i$ 的下标,求 $f(1)\\cdots f(n)$\n思路 直接就是模板,对应了上述应用里的第二个。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=3000005; int n,a[maxn]; int stack[maxn]; int top,ans[maxn]; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;a[i]); } a[0]=1e9+5; for(int i=1;i\u0026lt;=n;i++) { while(top\u0026gt;=0\u0026amp;\u0026amp;a[i]\u0026gt;a[stack[top]]) { ans[stack[top]] = i; top--; } stack[++top]=i; } while(top) { ans[stack[top]]=0; top--; } for(int i=1;i\u0026lt;=n;i++) { printf(\u0026#34;%d \u0026#34;,ans[i]); } return 0; } B. 发射站 题意 某地有 $N$ 个能量发射站排成一行,每个发射站 $i$ 都有不相同的高度 $H_i$,并能向两边(两端的发射站只能向一边)同时发射能量值为 $V_i$ 的能量,发出的能量只被两边最近的且比它高的发射站接收。计算出接受能量最多的发射站接受的能量为多少。\n思路 维护一个单调递减栈,一个元素新加进来如果是大于栈顶元素的话,那么栈顶元素出栈,并给入栈元素加上能量值。如果不大于栈顶元素的话,就将栈顶元素加上发射能量,然后将元素入栈。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=1000005; int n,h[maxn],v[maxn]; int stack[maxn],top,ans; int f[maxn]; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;h[i],\u0026amp;v[i]); } for(int i=1;i\u0026lt;=n;i++) { while(top\u0026gt;=0\u0026amp;\u0026amp;h[i]\u0026gt;h[stack[top]]) { f[i]+=v[stack[top]]; top--; } f[stack[top]]+=v[i]; stack[++top]=i; } for(int i=1;i\u0026lt;=n;i++) ans=max(ans,f[i]); printf(\u0026#34;%d\u0026#34;,ans); return 0; } C. 音乐会的等待 题意 给出一段序列 $a$ 代表 $n$ 个人,在一个区间 $[l,r]$ 如果区间内没有大于 $min(a[i],a[r])$ 的那么两个人可以相互看到。问这个序列中有多少对人可以相互看到。\n思路 我们可以维护一个单调递减栈,然后分情况讨论一下。\n如果要入栈元素大于当前元素,那么当前元素和入栈元素是可以相互看见的,因为这是找了左边区间第一个比它小的元素了,然后因为这是一个单调递减栈,所以我们可以一直出栈比入栈元素小的元素,可以发现这些都是可以互相看见的。而且最终的栈顶元素和要入栈元素也是可以看见的。 如果入栈元素小于当前元素,他可以和栈顶元素看见,而不能和后面的人看见,因为栈顶元素挡住他了。 如果入栈元素和当前元素高度相同,那么他们俩其实是等效的,如果有人比他们高,其实是可以直接看见两个,所以我们只需要将他们看成一个结构体,记录他们的数量和高度即可,每次统计的时候加上数量就行。 代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; typedef long long ll; const int maxn=500005; int n; int h[maxn]; ll ans; struct node { ll cnt; // num ll p; //height }stack[maxn]; int top; int main() { //\tfreopen(\u0026#34;test.in\u0026#34;,\u0026#34;r\u0026#34;,stdin); scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;h[i]); } for(int i=1;i\u0026lt;=n;i++) { node temp; temp.cnt=1; temp.p=h[i]; while(top\u0026gt;=0\u0026amp;\u0026amp;h[i]\u0026gt;stack[top].p) { ans+=stack[top].cnt; top--; } if(h[i]==stack[top].p) { ans+=stack[top].cnt; temp.cnt+=stack[top].cnt; top--; } stack[++top].cnt=temp.cnt; stack[top].p=temp.p; if(top!=0) ans+=1; } printf(\u0026#34;%lld\u0026#34;,ans); } 参考链接 单调队列和单调栈详解\n[SMOJ2116]诺诺的队列\n一些关于单调队列和单调栈优化dp的实例\n","permalink":"https://blog.zzsqwq.cn/posts/23/","summary":"\u003ch1 id=\"前言\"\u003e前言\u003c/h1\u003e\n\u003cpre\u003e\u003ccode\u003e最近感觉遇到了好多单调队列和单调栈的问题,但是因为以前没学好,所以遇见了就一脸懵逼,然后绝对下决心来学一下。。感觉遇到啥都不会,这可咋办呐。。补不完的漏洞。\n\u003c/code\u003e\u003c/pre\u003e","title":"单调队列和单调栈总结"},{"content":"A. Non-zero 题意 给出一段含有 $n$ 个数的序列 $a$ ,可以对其中任何数加一,问最少操作多少次让每一个数和序列和都不为0。\n思路 输入的时候如果输入的是 $0$ 就将答案加一,最后如果序列和为 $0$ 的话答案加一。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; int t,n,sum,p,ans; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { sum=ans=0; scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;p); if(p==0) { ans++; sum+=1; } else sum+=p; } if(sum==0) printf(\u0026#34;%d\\n\u0026#34;,ans+1); else printf(\u0026#34;%d\\n\u0026#34;,ans); } } B. Assigning to Classes 题意 将 $2n$ 个数分成个奇数序列,问两个奇数序列的中位数之差最小为多少。\n思路 直接就将序列排序然后输出中间两个数之差即可。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn = 100005; int t,n,a[maxn\u0026lt;\u0026lt;1]; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); int p=n\u0026lt;\u0026lt;1; for(int i=1;i\u0026lt;=p;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;a[i]); } sort(a+1,a+1+p); printf(\u0026#34;%d\\n\u0026#34;,abs(a[n]-a[n+1])); } return 0; } C. Anu Has a Function 题意 给出函数 $f: f(x,y)=(x|y)-y $ ,给出序列 $a$,序列 $a$ 中含有 $n$ 个数,可以表示为$[a_1,a_2\\cdots,a_n ]$ ,定义 $x=f(f(\u0026hellip;f(f(a_1,a_2),a_3),\u0026hellip;a_{n-1}),a_n)$ ,你可以对序列 $a$ 中元素进行重排,求使得 $x$ 最大的序列 $a$ 。如果有多种情况,输出一种即可。\n思路 第一种思路是因为 $f(x,y)=(x|y)-y$ ,我们可以发现对于经过这样的运算之后,如果 $x$ 的某一位是1,如果 $y$ 的相应位是0,那么运算出来的 $f(x,y)$ 对应位就是1,如果 $y$ 对应位是1,那么运算出来就是0。那么对于 $x$ 的计算过程中的每一位这个规律都是适应的。因此我们只需要将位数从高到低依次扫一遍,如果这个位数为1的情况在序列所有元素中只出现了一次,那么就将唯一出现1的那个数放到第一位即可。\n第二种思路 $$ \\because f(x,y)=(x|y) - y {\\Longleftrightarrow} f(x,y) = x\u0026amp;({\\sim} y) \\therefore x=(a_1)\u0026amp;({\\sim}a_2)\u0026amp;({\\sim} a_3){\\cdots}({\\sim}a_n) $$ 我们发现后面其实都是可交换的,所以第一个只有第一个是起决定作用的,那么我们就可以处理一个前缀和后缀的 and 数组,这样我们就可以 $O(1)$ 的计算出后面那部分,然后遍历序列 $a$ 找到最合适的 $a_1$。\n代码实现 第一种思路 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=100005; int n,a[maxn],maxk; int cnt; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;a[i]); maxk=max(maxk,a[i]); } int p=1,k=0; while(p\u0026lt;=maxk) { k++; p\u0026lt;\u0026lt;=1; } for(int i=k;i\u0026gt;=0;i--) { cnt=0; for(int j=1;j\u0026lt;=n;j++) { if(a[j]\u0026amp;(1\u0026lt;\u0026lt;i)) { cnt++; if(cnt==1) swap(a[j],a[1]); } } //\tprintf(\u0026#34;%d %d\\n\u0026#34;,i,cnt); if(cnt==1) { for(int j=1;j\u0026lt;=n;j++) { printf(\u0026#34;%d \u0026#34;,a[j]); } return 0; } } for(int i=1;i\u0026lt;=n;i++) { printf(\u0026#34;%d \u0026#34;,a[i]); } return 0; } 第二种思路 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=100005; int n,a[maxn]; int ans; int pre[maxn],suf[maxn]; //pre is prefix,suf is suffix int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;a[i]); a[i]=~a[i]; if(i==1) pre[i]=a[i]; else pre[i]=pre[i-1]\u0026amp;a[i]; } suf[n]=a[n]; for(int i=n-1;i\u0026gt;=1;i--) { suf[i]=suf[i+1]\u0026amp;a[i]; } for(int i=1;i\u0026lt;=n;i++) { int p=a[i]; p=~a[i]; if(i==1) { int now=suf[i+1]\u0026amp;p; ans=max(ans,now); } else if(i==n) { int now=pre[i-1]\u0026amp;p; if(now\u0026gt;ans) { swap(a[i],a[1]); ans=now; } } else { int now=pre[i-1]\u0026amp;suf[i+1]\u0026amp;p; if(now\u0026gt;ans) { swap(a[i],a[1]); ans=now; } } } for(int i=1;i\u0026lt;=n;i++) { printf(\u0026#34;%d \u0026#34;,~a[i]); } return 0; } D. Aerodynamic 题意 给定一个凸多边形 $P$ 的所有顶点,可以将凸多边形沿向量 $(x,y)$ 平移,我们定义多边形 $T$ 是所有 $P$ 平移到与原点有交点后所构成的点集所形成的图形(我知道这句话有点绕,我实在是解释不明白,实在不行康康原题吧)。那么问这个 $T$ 是否是和 $P$ 相似的,如果是输出YES,不是输出NO。\n思路 就是判断这个图形是不是中心对称图形就行了,证明还不会,暂且放一下,会了再写QAQ..\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=100005; int n; int x[maxn],y[maxn]; bool check() { int p=n/2; //\tprintf(\u0026#34;%d\u0026#34;,p); int x1=x[1]+x[1+p]; int y1=y[1]+y[1+p]; for(int i=2;i\u0026lt;=p;i++) { if(x1!=x[i]+x[i+p]||y1!=y[i]+y[i+p]) { return false; } } return true; } int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;x[i],\u0026amp;y[i]); } if(n\u0026amp;1) { printf(\u0026#34;NO\u0026#34;); } else { if(check()) { printf(\u0026#34;YES\u0026#34;); } else printf(\u0026#34;NO\u0026#34;); } return 0; } ","permalink":"https://blog.zzsqwq.cn/posts/22/","summary":"\u003ch2 id=\"a-non-zerohttpscodeforcescomcontest1300problema\"\u003eA. \u003ca href=\"https://codeforces.com/contest/1300/problem/A\"\u003eNon-zero\u003c/a\u003e\u003c/h2\u003e\n\u003ch3 id=\"题意\"\u003e题意\u003c/h3\u003e\n\u003cp\u003e给出一段含有 $n$ 个数的序列 $a$ ,可以对其中任何数加一,问最少操作多少次让每一个数和序列和都不为0。\u003c/p\u003e","title":"Codeforces #618 (Div.2)"},{"content":"1. 分组背包 题意 在01背包基础上,将其中的物体分成 $k$ 组,每组内的物品相互冲突,即只能取其中一个,问最大价值。\n思路 同一组中各个物品是相互排斥的,那么我们对于处理可以外层循环组别,然后循环体积,最后循环组内的物品,然后套用01背包的转移方程 $dp[i]=max(dp[i],dp[i-v[k]]+w[k])$ 即可。我们来思考一下他的正确性,为什么只要这样循环就能确保每个组最多只取用一种呢?很明显组内的我们对于同一个体积 $V$ ,求体积 $V$ 对应的最大价值的时候,是从这个组内所有物品中取了能获得最大价值的策略,很明显当我们转移任何一个 $dp[i-v[k]]$ 的状态的时候,他们其中都不包含第 $i$ 组的物品,都是只包含了前 $i-1$ 组的物品,因为我们最终取得最大价值的路径是确定的,因此通过这个方式我们就可以确保每个组内只取一种,但是如果体积和组内物品的循环调换过来,就不行了,因为之前的状态就会包含当前组内的其他物品。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn =1005; const int maxt = 105; struct item { int a,b; }p[maxt][maxn]; int cnt[maxt]; int n,m; int dp[maxn]; int q,w,e,maxe; int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;m,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d%d%d\u0026#34;,\u0026amp;q,\u0026amp;w,\u0026amp;e); cnt[e]++; p[e][cnt[e]].a=q; p[e][cnt[e]].b=w; maxe=max(maxe,e); } for(int i=1;i\u0026lt;=maxe;i++) { for(int j=m;j\u0026gt;=0;j--) { for(int k=1;k\u0026lt;=cnt[i];k++) { if(j\u0026gt;=p[i][k].a) dp[j]=max(dp[j],dp[j-p[i][k].a]+p[i][k].b); } } } printf(\u0026#34;%d\u0026#34;,dp[m]); } 2. 有依赖的背包 题意 在01背包的基础上给物品加上依赖,某个物品可能为附件,必须买了主件之后才能买。规定一个物品最多有两个附件,并且附件不会再有附件,也不存在循环依赖(附件再依赖于主件)。问能获得的最大价值为多少。\n思路 这道题有三种思路,难度依次递增。\n这道题的附件很少,可能为0,1,2。那么我们就在01背包的基础上,分五种情况来转移,分别是都不买,只买一个主件,只买主件和附件1,只买主件和附件2,买主件和两个附件。然后在这个基础上取一个最大的即可。但是这个思路对于附件可以很多的情况,就会特别麻烦。 第二种思路是转化成分组背包,我们注意到对于每一个主件和附件的搭配都是唯一的,也就是每种方案都是互斥的。好比最多那五种情况,我们就可以分成一组。然后进行分组背包即可。那么我们分组的时候,可以考虑到一个优化,也就是如果他们的体积相同,我们只需要选价值大的那个就可以啦。所以我们先对主件和附件这个集合,进行01背包,然后背出来相同体积下最大价值的方案,分到对应组里。这个思路对于附件也有附件的情况,就不好写了,不能直接01背包。 第三种思路可以应对附件也有附件的情况,可以用森林来表示所有物品之间的关系,然后树上dp做。然而,我不会。QAQ\u0026hellip; 代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=32005; const int maxm=65; int n,m; int num[maxm]; struct Item { int v,p,q; }item[maxm],minor[maxm][maxm]; int dp[maxn],cnt[maxm]; int vi[maxm][maxm],pi[maxm][maxm]; int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;m); for(int i=1;i\u0026lt;=m;i++) { scanf(\u0026#34;%d%d%d\u0026#34;,\u0026amp;item[i].v,\u0026amp;item[i].p,\u0026amp;item[i].q); if(item[i].q) { num[item[i].q]++; minor[item[i].q][num[item[i].q]].v=item[i].v; minor[item[i].q][num[item[i].q]].p=item[i].v*item[i].p; } } for(int i=1;i\u0026lt;=m;i++) { if(num[i]) { memset(dp,-1,sizeof(dp)); dp[0]=0; for(int j=1;j\u0026lt;=num[i];j++) { for(int k=n-item[i].v;k\u0026gt;=minor[i][j].v;k--) { if(dp[k-minor[i][j].v]!=-1) { dp[k]=max(dp[k],dp[k-minor[i][j].v]+minor[i][j].p);\t} } } for(int k=0;k\u0026lt;=n-item[i].v;k++) { if(dp[k]!=-1) { cnt[i]++; vi[i][cnt[i]]=k+item[i].v; pi[i][cnt[i]]=dp[k]+item[i].v*item[i].p; } } } if(!item[i].q) { cnt[i]++; vi[i][cnt[i]]=item[i].v; pi[i][cnt[i]]=item[i].v*item[i].p; } } memset(dp,0,sizeof(dp)); for(int i=1;i\u0026lt;=m;i++) { if(!cnt[i]) continue; for(int j=n;j\u0026gt;=0;j--) { for(int k=1;k\u0026lt;=cnt[i];k++) { if(j\u0026gt;=vi[i][k]) { dp[j]=max(dp[j],dp[j-vi[i][k]]+pi[i][k]); } } } } //\tint ans; //\tfor(int i=1;i\u0026lt;=n;i++) ans=max(ans,dp[i]); printf(\u0026#34;%d\u0026#34;,dp[n]); return 0; } 3. 多米诺骨牌(隐式背包) 题意 多米诺骨牌有上下两个部分,分别具有一定点数。所有多米诺骨牌上部分点数之和与下部分点数之和差的绝对值为 $x$ ,多米诺骨牌可以进行上下翻转,问当 $x$ 最小的时候最少翻转几次。\n思路 害,本来好像没有隐式背包这个说法,我自己瞎起的名字。。其实就是没那么裸的背包,实际上转化一下还是道背包的题。这道题本来其实看起来和背包没有什么关系,但是实际想一想,假如我们把所有多米诺骨牌一开始都调成上面大下面小的情况,然后调整过的把他的消耗值设为-1,没有调整过的把消耗值设为1。达成上大下小目的需要消耗的次数为n。调整后的上下点数差为V。我们每次调整之后 $V$ 会减少牌的上下点数之差,这就是我们需要的体积。然后一开始把 $dp[V]$ 设为n。然后转移方程为 $dp[i]=min(dp[i],dp[i+v[i]]+w[i]) $ 最后只需要求从 $0\\sim V$ 最小的那个点数差对应的翻转次数值就可以了。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=1005; int ini; int n; int up[maxn],down[maxn]; int v[maxn],w[maxn]; int dp[10005]; int V; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;up[i],\u0026amp;down[i]); if(up[i]\u0026gt;=down[i]) { V+=up[i]-down[i]; v[i]=(up[i]-down[i])*2; w[i]=1; } else { V+=down[i]-up[i]; ini++; v[i]=(down[i]-up[i])*2; w[i]=-1; } } for(int i=0;i\u0026lt;=V;i++) dp[i]=233333; //\tdp[V]=ini; dp[V]=ini; for(int i=1;i\u0026lt;=n;i++) { for(int j=0;j\u0026lt;=V-v[i];j++) { if(dp[j+v[i]]!=233333) dp[j]=min(dp[j],dp[j+v[i]]+w[i]); } } for(int i=0;i\u0026lt;=V;i++) { if(dp[i]!=233333) { printf(\u0026#34;%d\u0026#34;,dp[i]); break; } } return 0; } ","permalink":"https://blog.zzsqwq.cn/posts/21/","summary":"\u003ch3 id=\"1-分组背包httpswwwluogucomcnproblemp1757\"\u003e1. \u003ca href=\"https://www.luogu.com.cn/problem/P1757\"\u003e分组背包\u003c/a\u003e\u003c/h3\u003e\n\u003chr\u003e\n\u003ch4 id=\"题意\"\u003e题意\u003c/h4\u003e\n\u003cp\u003e在01背包基础上,将其中的物体分成 $k$ 组,每组内的物品相互冲突,即只能取其中一个,问最大价值。\u003c/p\u003e","title":"背包进阶"},{"content":"前言 今天跟着背包九讲把背包再学习一下,dd_engi大佬的背包九讲Github链接: 背包九讲\n1. 采药(01背包) 题意 有 $n$ 个价值为 $w_i$ ,体积为 $v_i$ 的物品,装入体积为 $V$ 的背包中,问能获得的最大为多少。\n思路 首先我们可以用 $f[i][j]$ 来定义前 $i$ 个物品放入体积为 $j$ 的背包中能获得最大体积,对于每一个物品,我们可以分两种情况来讨论,分别是装和不装,然后取他们两个的最大值。已经正确的定义了状态,转移方程就不难写出来了,是 $f[i][j]=max(f[i-1][j],f[i-1][j-v[i]]+w[i])$ ,然后推的话就直接外层循环物品,内层循环体积递推即可。最后 $f[n][V]$ 就是我们需要的答案。\n但是看了大佬们的题解,他们说,空间复杂度还可以再优化,那么我们可以看看如果优化的话,肯定是不能去掉体积那一维的,所以就是去掉第几个物品那一维。所以从 $f[i][j]$ 变成了 $f[j]$ 。那么我们想想,当我们推第 $i$ 个物体的状态的时候,我们需要已知第 $i-1$ 个的状态,我们物体循环是 $1\\sim n$ 那么肯定 $f[i][j]$ 一开始对应的是 $f[i-1][j]$ ,那么如果顺推体积 $0\\sim V$ 的话我们可以发现,当我们推 $f[i][j]$ 需要状态 $f[i-1][j-v[i]]$ 的时候,这时候如果直接调用 $f[j-v[i]]$ 对应的是 $f[i][j-v[i]]$ 也就是说,这不是我们需要的结果,这时候的状态可能已经取过一次i了,那么我们就可以逆推体积 $V\\sim c[i]$ ,这样我们调用 $f[j-v[i]]$ 就刚好对应的是没取过 $i$ 的情况了!最后推出来 $f[V]$ 就是对应的答案了!\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=105; int t,m; int f[1005]; int a[maxn],b[maxn]; int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;t,\u0026amp;m); for(int i=1;i\u0026lt;=m;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;a[i],\u0026amp;b[i]); } for(int i=1;i\u0026lt;=m;i++) { for(int j=t;j\u0026gt;=a[i];j--) { f[j]=max(f[j],f[j-a[i]]+b[i]); } } printf(\u0026#34;%d\u0026#34;,f[t]); return 0; } 2. 疯狂的采药(完全背包) 题意 有 $n$ 种价值为 $w_i$ ,体积为 $v_i$ 的物品,每一种物品有无数个,装入体积为 $V$ 的背包中,问能获得的最大为多少。\n思路 那么很显然我们可以把一个它转化成 $\\sum_{i=1}^n \\lfloor{\\frac{V}{v_i}}\\rfloor$ 个物品的01背包,也可以在取每个物体的时候循环 $\\lfloor{\\frac{V}{v_i}}\\rfloor$ 次,但是我们可以思考对上述01背包的优化,我们发现如果顺着取,刚好对应的就是我们需要的状态,也就是说我们只需要将 $V$ 的循环正过来就可以了!\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=100005; int t,m; int f[100005]; int a[maxn],b[maxn]; int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;t,\u0026amp;m); for(int i=1;i\u0026lt;=m;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;a[i],\u0026amp;b[i]); } for(int i=1;i\u0026lt;=m;i++) { for(int j=a[i];j\u0026lt;=t;j++) { f[j]=max(f[j],f[j-a[i]]+b[i]); } } printf(\u0026#34;%d\u0026#34;,f[t]); return 0; } 3. 宝物筛选(多重背包) 题意 有 $N$ 种物品和一个容量为 $V$ 的背包。第 $i$ 种物品最多有 $m_i$ 件可用,每件耗费的空间是 $v_i$,价值是 $w_i$ 。求解将哪些物品装入背包可使这些物品的耗费的空间总和不超过背包容量,且价值总和最大。\n思路 那么这道题裸的做法就是对于转移 $f[v]$ 这个方程的时候,考虑取多少个物品,可以取一个,可以取两个,在不超过体积情况下最多取 $m[i]$ 个,转移方程 $f[v]=max(f[v],f[v-k*v[i]])\\quad k\\in[1,m_i]$ 。那么这样其实时间复杂度还是很高的,所以大佬们给出了优化方案\n第一种就是把 $m_i$ 个物品进行二进制拆分,把他们拆成 $1$,$2^1$,$2^2$ ····等等,一直拆到不能再拆,这样我们就能够将 $m_i$ 个物品拆成 $log(m_i)$ 个物品,但是他们还是能够表示出所有的情况。然后就继续01背包背一下就可以了。 单调队列优化,我不会,我太菜了。。 代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; using namespace std; int n,m,ans,cnt; int a,b,c; const int maxn=1000005; int f[maxn]; int w[maxn],v[maxn]; int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;m); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d%d%d\u0026#34;,\u0026amp;a,\u0026amp;b,\u0026amp;c); for(int j=1;j\u0026lt;=c;j*=2) //二进制拆分 { v[++cnt]=j*a; w[cnt]=j*b; c-=j; } if(c) { v[++cnt]=a*c; w[cnt]=b*c; } } for(int i=1;i\u0026lt;=cnt;i++) { for(int j=m;j\u0026gt;=w[i];j--) { f[j]=max(f[j],f[j-w[i]]+v[i]); } } printf(\u0026#34;%d\\n\u0026#34;,f[m]); return 0; } ","permalink":"https://blog.zzsqwq.cn/posts/20/","summary":"\u003ch3 id=\"前言\"\u003e前言\u003c/h3\u003e\n\u003cp\u003e今天跟着背包九讲把背包再学习一下,dd_engi大佬的背包九讲Github链接: \u003ca href=\"https://github.com/tianyicui/pack\"\u003e背包九讲\u003c/a\u003e\u003c/p\u003e\n\u003chr\u003e\n\u003ch3 id=\"1-采药01背包httpswwwluogucomcnproblemp1048\"\u003e1. \u003ca href=\"https://www.luogu.com.cn/problem/P1048\"\u003e采药(01背包)\u003c/a\u003e\u003c/h3\u003e\n\u003chr\u003e\n\u003ch4 id=\"题意\"\u003e题意\u003c/h4\u003e\n\u003cp\u003e有 $n$ 个价值为 $w_i$ ,体积为 $v_i$ 的物品,装入体积为 $V$ 的背包中,问能获得的最大为多少。\u003c/p\u003e","title":"一些关于背包的题"},{"content":"1. 石子归并 题意 $N$ 堆石子摆成一条线。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价。计算将 $N$ 堆石子合并成一堆的最小代价。 思路 很经典的区间dp例题,我们可以用 $dp[i][j]$ 来表示合并 $i\\sim j$ 所需的最小代价,通过枚举中间的断点,来通过方程 $dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+cost[i][j])$ ,其中 $cost[i][j]$ 表示从 $i\\sim j$ 的石子总数,通过前缀和很容易计算。在进行状态转移时需要前面状态已知,因为是枚举中间断点,所以断开区间的长度一定要小于原区间,因此在转移之前需要确保比他短的区间都已经达到了最小代价,因此我们可以通过枚举区间长度从 $2\\sim N$ 来实现。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int inf=1000005; const int maxn=105; int n; int sum[maxn],a[maxn]; int dp[maxn][maxn]; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;a[i]); sum[i]=sum[i-1]+a[i]; } for(int i=1;i\u0026lt;=n;i++) dp[i][i]=0; for(int p=2;p\u0026lt;=n;p++) { for(int i=1;i\u0026lt;=n-p+1;i++) { int j=i+p-1; dp[i][j]=inf; for(int k=i;k\u0026lt;j;k++) { dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]); } } } printf(\u0026#34;%d\u0026#34;,dp[1][n]); return 0; } 2. P1880 [NOI1995]石子合并 题意 $N$ 堆石子摆成一个环。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价。计算将 $N$ 堆石子合并成一堆的最小代价和最大代价。\n思路 这个题和上个题只有两个地方不同,一个是从线到环,一个是同时求最大和最小代价。害,其实这样也没变什么东西,也是跟上面一样,枚举区间长度和切割点。我们可以把一个环想象成一个链,如果这个环是由 N 个元素构成,那么这个链就由 N+N 个元素构成,这么这样就能确保你每次枚举区间的时候能取到合法的值,好比你要可以合并最后一个和第一个,那么就是对应的 $dp[n][n]+dp[n+1][n+1]+cost[n][n+1]$ 。不过这样最后寻找答案的时候肯定不只是 $dp[i][n]$ 了,你要从 $dp[1][n]\\sim dp[n][n*2]$ 中寻找最优的答案。同时求最大和最小代价就直接开两个数组记录就可以了。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int inf=1000005; const int maxn=105; int n; int sum[maxn\u0026lt;\u0026lt;1],a[maxn\u0026lt;\u0026lt;1]; int ansmax,ansmin=12345678; int dp[maxn\u0026lt;\u0026lt;1][maxn\u0026lt;\u0026lt;1],f[maxn\u0026lt;\u0026lt;1][maxn\u0026lt;\u0026lt;1]; //later is max , fromer is min int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;a[i]); a[i+n]=a[i]; sum[i]=sum[i-1]+a[i]; } for(int i=n+1;i\u0026lt;=2*n;i++) { sum[i]=sum[i-1]+a[i]; } for(int i=1;i\u0026lt;=n*2;i++) dp[i][i]=f[i][i]=0; for(int p=2;p\u0026lt;=n;p++) { for(int i=1;i\u0026lt;=2*n-p+1;i++) { int j=i+p-1; dp[i][j]=inf; for(int k=i;k\u0026lt;j;k++) { dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]); f[i][j]=max(f[i][j],f[i][k]+f[k+1][j]+sum[j]-sum[i-1]); } } } for(int i=1;i\u0026lt;=n;i++) ansmax=max(ansmax,f[i][i+n-1]); for(int i=1;i\u0026lt;=n;i++) ansmin=min(ansmin,dp[i][i+n-1]); printf(\u0026#34;%d\\n%d\u0026#34;,ansmin,ansmax); return 0; } 3. P1140 相似基因 题意 有 $A : T :C : G $ 四种碱基,他们之间可以两两配对,特殊的,一个碱基也可以和空碱基配对,但是空碱基和空碱基配对是不被允许的,当不同的碱基间两两配对时,会具有一定的相似度,问给定两段序列 $s$,$t$ 能获得的最大相似度是多少。\n碱基配对时相似度的定义如下 A C G T 空 A 5 -1 -2 -1 -3 C -1 5 -3 -2 -4 G -2 -3 5 -2 -2 T -1 -2 -2 5 -1 空 -3 -4 -2 -1 非法 思路 首先用一个二维数组来存储对应的相似值表。因为对应的两段序列,我感觉这种题一般都是用 $dp[i][j]$ 来表示第一段序列从 $1\\sim i$ 对应第二段序列 $1\\sim j$ 所能获得的最大相似度,那么思考一下状态转移。\n首先可以是碱基对空碱基,这时候 $s$ 要匹配碱基,$t$ 中匹配空碱基,这样的话就从应该从 $dp[i-1][j] $转移过来,对应的转移方程为 $dp[i][j]=max(dp[i][j],dp[i-1][j]+map[s[i]][blank])$\n也可以是空碱基对碱基,对应的转移方程为$dp[i][j]=max(dp[i][j],dp[i][j-1]+map[blank][t[j]])$\n也可以是碱基对碱基,对应的转移方程为$dp[i][j]=max(dp[i][j],dp[i-1][j-1]+map[s[i]][t[j]])$\n害,想到这里我又突然懵逼了,我在想是否能确保两个序列所有的碱基都被用到,仔细想想确实是可以的,因为状态定义的就是用了前 $i$ 个碱基和前 $j$ 个碱基所获得的最大相似度。最后我们就处理一下边界就可以了,边界我们可以发现是 $dp[i][0]$ 和 $dp[0][i]$ ,这就是可以对应着空碱基和相应 $s[i]$ 和 $t[i]$ 的碱基,因此只需要用循环依次转移一遍就可以了。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int inf=1000005; const int maxn=105; int n,m; int a[maxn],b[maxn]; char s[maxn],c[maxn]; int dp[maxn][maxn]; const int map[5][5]={{5,-1,-2,-1,-3}, {-1,5,-3,-2,-4}, {-2,-3,5,-2,-2}, {-1,-2,-2,5,-1}, {-3,-4,-2,-1,0}}; //A 0 C 1 G 2 T 3 blank 4 int main() { scanf(\u0026#34;%d%s%d%s\u0026#34;,\u0026amp;n,s+1,\u0026amp;m,c+1); for(int i=1;i\u0026lt;=n;i++) { if(s[i]==\u0026#39;A\u0026#39;) a[i]=0; if(s[i]==\u0026#39;C\u0026#39;) a[i]=1; if(s[i]==\u0026#39;G\u0026#39;) a[i]=2; if(s[i]==\u0026#39;T\u0026#39;) a[i]=3; } for(int i=1;i\u0026lt;=m;i++) { if(c[i]==\u0026#39;A\u0026#39;) b[i]=0; if(c[i]==\u0026#39;C\u0026#39;) b[i]=1; if(c[i]==\u0026#39;G\u0026#39;) b[i]=2; if(c[i]==\u0026#39;T\u0026#39;) b[i]=3; } for(int i=1;i\u0026lt;=n;i++) dp[i][0]=dp[i-1][0]+map[a[i]][4]; for(int i=1;i\u0026lt;=m;i++) dp[0][i]=dp[0][i-1]+map[4][b[i]]; for(int i=1;i\u0026lt;=n;i++) { for(int j=1;j\u0026lt;=m;j++) { dp[i][j]=-inf; dp[i][j]=max(dp[i][j],dp[i][j-1]+map[4][b[j]]); dp[i][j]=max(dp[i][j],dp[i-1][j]+map[a[i]][4]); dp[i][j]=max(dp[i][j],dp[i-1][j-1]+map[a[i]][b[j]]); } } printf(\u0026#34;%d\u0026#34;,dp[n][m]); return 0; } ","permalink":"https://blog.zzsqwq.cn/posts/19/","summary":"\u003ch3 id=\"1-石子归并httpswww51nodcomchallengeproblemhtmlproblemid1021\"\u003e1. \u003ca href=\"https://www.51nod.com/Challenge/Problem.html#problemId=1021\"\u003e石子归并\u003c/a\u003e\u003c/h3\u003e\n\u003chr\u003e\n\u003ch4 id=\"题意\"\u003e题意\u003c/h4\u003e\n\u003cpre\u003e\u003ccode\u003e$N$ 堆石子摆成一条线。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价。计算将 $N$ 堆石子合并成一堆的最小代价。\n\u003c/code\u003e\u003c/pre\u003e\n\u003chr\u003e\n\u003ch4 id=\"思路\"\u003e思路\u003c/h4\u003e\n\u003cp\u003e很经典的区间dp例题,我们可以用 $dp[i][j]$ 来表示合并 $i\\sim j$ 所需的最小代价,通过枚举中间的断点,来通过方程 $dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+cost[i][j])$ ,其中 $cost[i][j]$ 表示从 $i\\sim j$ 的石子总数,通过前缀和很容易计算。在进行状态转移时需要前面状态已知,因为是枚举中间断点,所以断开区间的长度一定要小于原区间,因此在转移之前需要确保比他短的区间都已经达到了最小代价,因此我们可以通过枚举区间长度从 $2\\sim N$ 来实现。\u003c/p\u003e","title":"基础线性dp例题 #2"},{"content":"前言 某位大佬曾经说过,dp不会没问题,想不到状态转移方程没问题,多做题就会了。所以,我打算多刷点dp题。那么,先从基础刷起吧。\n1. P1091 合唱队形 题意 已知序列 $a$ 有 $n$ 个数,通过取出其中一些数可以使他满足严格的先增再减序列,问最少取出几个。\n思路 很显然想要求最少取出几个,我们就看严格先增再减的序列的最长长度即可。我们可以用 $g[i]$ 来存储到 $a[i]$ 为止的最长递增子序列的长度,然后用 $l[i]$ 来存储从 $a[i]$ 到序列末尾最长的递减子序列的长度。处理 $g[i]$ 从前往后扫,处理 $l[i]$ 需要从后往前扫。处理完 $f$ 和 $g$ 数组那么就从左到右扫一遍,$ans=max(ans,g[i]+l[i]-1)$ 。答案即是 $n-ans$ 。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; #include\u0026lt;cstring\u0026gt; using namespace std; const int maxn=105; int n; int a[maxn],g[maxn],l[maxn]; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;a[i]); } for(int i=1;i\u0026lt;=n;i++) { for(int j=0;j\u0026lt;i;j++) { if(a[i]\u0026gt;a[j]) g[i]=max(g[i],g[j]+1); } } for(int i=n;i\u0026gt;=1;i--) { for(int j=n+1;j\u0026gt;i;j--) { if(a[i]\u0026gt;a[j]) l[i]=max(l[i],l[j]+1); } } int maxout=0; for(int i=1;i\u0026lt;=n;i++) { maxout=max(maxout,g[i]+l[i]-1); } printf(\u0026#34;%d\u0026#34;,n-maxout); return 0; } 2. P1280 尼克的任务 题意 尼克的一个工作日为 $n$ 分钟,从第一分钟开始到第 $n$ 分钟结束。当尼克到达单位后他就开始干活。如果在同一时刻有多个任务需要完成,尼克可以任选其中的一个来做,而其余的则由他的同事完成,反之如果只有一个任务,则该任务必需由尼克去完成,假如某些任务开始时刻尼克正在工作,则这些任务也由尼克的同事完成。如果某任务于第 $p$ 分钟开始,持续时间为 $t$ 分钟,则该任务将在第 $p+t-1$ 分钟结束。(实在不会总结题意,就直接复制过来了)\n思路 我们可以设 $f[i]$ 为时间从 $i\\sim n$ 所能获得最长空闲时间,最终 $f[1]$ 对应的就是答案。假设在这个 $i$ 分钟有 $k[i]$ 个任务可以,那么我们可以分以下情况转移\n$k[i]=0$ , 那么 $f[i]=f[i+1]+1$\n$k[i]\\not=0$ ,那么可以循环 $1 \\sim k[i]$ 遍历这个时间点开始的任务,$f[i]=max(f[i],f[i+k[i].t])$\n思路是这样的,但是我们记录 $k[i].t$ 并不好记录,因此我们可以先将任务开始时间按降序排序,用一个一个变量 $cnt$ 来代表已经取到第几个任务了,那么这样一直取下去,最终就能够遍历所有的任务。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=10005; struct task { int l,r; }t[maxn]; int cmp(struct task a,struct task b) { return a.l\u0026gt;b.l; } int dp[maxn]; int p[maxn]; int cnt=1,n,k; int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;k); for(int i=1;i\u0026lt;=k;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;t[i].l,\u0026amp;t[i].r); p[t[i].l]++; } sort(t+1,t+1+k,cmp); for(int i=n;i\u0026gt;=1;i--) { if(!p[i]) { dp[i]=dp[i+1]+1; } else { for(int j=1;j\u0026lt;=p[i];j++) { dp[i]=max(dp[i],dp[i+t[cnt].r]); cnt++; } } } printf(\u0026#34;%d\\n\u0026#34;,dp[1]); return 0; } 我太懒了····就写了两道,明天继续加油吧。。\n","permalink":"https://blog.zzsqwq.cn/posts/18/","summary":"\u003ch3 id=\"前言\"\u003e前言\u003c/h3\u003e\n\u003chr\u003e\n\u003cp\u003e某位大佬曾经说过,dp不会没问题,想不到状态转移方程没问题,多做题就会了。所以,我打算多刷点dp题。那么,先从基础刷起吧。\u003c/p\u003e\n\u003ch3 id=\"1-p1091-合唱队形httpswwwluogucomcnproblemp1091\"\u003e1. \u003ca href=\"https://www.luogu.com.cn/problem/P1091\"\u003eP1091 合唱队形\u003c/a\u003e\u003c/h3\u003e\n\u003chr\u003e\n\u003ch4 id=\"题意\"\u003e题意\u003c/h4\u003e\n\u003cp\u003e已知序列 $a$ 有 $n$ 个数,通过取出其中一些数可以使他满足严格的先增再减序列,问最少取出几个。\u003c/p\u003e\n\u003chr\u003e","title":"基础线性dp例题"},{"content":"A. Array with Odd Sum 题意 给出包含 n 个正整数的序列 a ,你可以把任何一个元素 $a_i$ ,赋值给另一个元素 $a_j$ ($i\\neq j$) ,问通过任意此操作能否将序列 a 的和变为奇数。可以输出 YES ,不可以输入 NO.\n思路 首先当起始和为奇数的时候,就直接可输出 YES 了,如果是偶数的话,我们可以发现,如果序列元素中同时包含奇数和偶数,那么就是可以的,否则不可以。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; using namespace std; int t,n,flag,sum,p,flag1,flag2; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { flag=false; flag2=flag1=false; sum=0; scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;p); sum+=p; if(p%2==1) flag1=true; if(p%2==0) flag2=true; } if(flag1\u0026amp;\u0026amp;flag2) flag=true; if(sum%2==1) printf(\u0026#34;YES\\n\u0026#34;); else { if(flag) printf(\u0026#34;YES\\n\u0026#34;); else printf(\u0026#34;NO\\n\u0026#34;); } } } B. Food Buying 题意 初始有 s 个货币,每次花费 x 个货币会返还 $\\lfloor{\\frac{x}{10}}\\rfloor$ 个货币,问最多共能花费多少货币。\n思路 贪心即可。剩余的货币一直除10累加,注意最终剩余不足10的处理。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; using namespace std; int t,s; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;s); { int p=s; int now=0; while(p) { if(p\u0026lt;10) break; now=p/10; s+=now; p%=10; p+=now; } } printf(\u0026#34;%d\\n\u0026#34;,s); } } C. Yet Another Walking Robot 题意 一个机器人初始在 $(0,0)$ 点,规定 \u0026lsquo;L\u0026rsquo; ,\u0026lsquo;R\u0026rsquo; ,\u0026lsquo;U\u0026rsquo; ,\u0026lsquo;D\u0026rsquo; 分别对应向左,向右,向上和向下。给定一段包含上述字母的序列 s ,机器人遵循指引序列移动。如果删除一段连续序列可使得机器人最终到达终点不变,问删除的最短序列的起始和终点为多少。\n思路 想了半天想了错误的解法。。一直在考虑 L 和 R 数相等,U 和 D 相等,通过这个方法来找序列。看了题解才发现是通过坐标来看。我们可以开一个map记录坐标和步数的关系,从左到右扫序列,如果没有到达过这个坐标,就记录当前是第几次移动到达这个坐标的,如果到达过的话,就看上一次到达这个坐标时的步数,计算他们的序列长度,如果小于计算的就更新答案。因为是需要找最小的,因此只需要记录上一次到达的步数即可。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;map\u0026gt; using namespace std; const int maxn=200005; int t,n; char s[maxn]; bool flag; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); int l=-1,r=n; scanf(\u0026#34;%s\u0026#34;,s+1); pair\u0026lt;int,int\u0026gt; pos; //first为x second为y map\u0026lt;pair\u0026lt;int,int\u0026gt;,int\u0026gt; last; pos.first=pos.second=0; last[pos]=0; for(int i=1;i\u0026lt;=n;i++) { if(s[i]==\u0026#39;L\u0026#39;) pos.first--; if(s[i]==\u0026#39;R\u0026#39;) pos.first++; if(s[i]==\u0026#39;U\u0026#39;) pos.second++; if(s[i]==\u0026#39;D\u0026#39;) pos.second--; /*\tif(i==2) { printf(\u0026#34;%d %d\\n\u0026#34;,pos.first,pos.second); } */\tif(last.count(pos)!=0) { int p=i-last[pos]; //\tif(i==2) printf(\u0026#34;%d %d\\n\u0026#34;,i,last[pos]); if(p\u0026lt;r-l) { l=last[pos]; r=i;\t}\t//\tif(i==2 )printf(\u0026#34;%d %d\\n\u0026#34;,l,r); } last[pos]=i; } if(l==-1) { printf(\u0026#34;-1\\n\u0026#34;); } else { printf(\u0026#34;%d %d\\n\u0026#34;,l+1,r); } } return 0; } D. Fight with Monsters 题意 由你先手和对手轮流击打 $n$ 个血量为 $h_i$ 的小怪兽,你可以对怪物造成 $a$ 点伤害,对手可以造成 $b$ 点伤害。你有 $k$ 次机会使对手跳过他的回合。当小怪兽血量 $h\\le0$ 时视为被击杀,当你击杀怪兽,你获得一分,当对手击杀,你不得分。求你最多能获得多少分数。\n思路 先看一下对于每个怪兽我们要击杀需要花费多少机会,你和对手一个回合会击杀怪兽 $a+b$ 点血量,因此你可以一直将回合进行到怪兽血量小于$a+b$,接下来我们可以分两种情况讨论。\n怪兽血量为0,那么我们就需要回溯对手最后一个回合,然后需要使用的机会就是 $\\lceil\\frac{h_i}{a}\\rceil$ 次\n怪兽血量不为0,我们需要使用的机会就是 $\\lceil\\frac{h_i}{a}\\rceil-1$ 次,注意这里不能直接写 $\\lfloor\\frac{h_i}{a}\\rfloor$ 次,因为如果 $h_i$ 刚好能被 $a$ 整除,后面这个写法就错了。\n计算出了每个怪兽需要花费的机会那么就好做了,就变成了一个贪心问题,我们去尽可能得击杀需要的机会少的,当机会消耗完毕,得到的就是答案了。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=200005; int n,a,b,k; int f[maxn]; int cmp(int a,int b) { return a\u0026lt;b; } int h[maxn],ans; int main() { scanf(\u0026#34;%d%d%d%d\u0026#34;,\u0026amp;n,\u0026amp;a,\u0026amp;b,\u0026amp;k); int p=a+b; for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;h[i]); h[i]%=p; if(h[i]==0) { h[i]+=b; f[i]=ceil((double)h[i]/a); } else f[i]=ceil((double)h[i]/a)-1; } sort(f+1,f+1+n,cmp); for(int i=1;i\u0026lt;=n;i++) { if(k-f[i]\u0026lt;0) break; ans++; k-=f[i]; } printf(\u0026#34;%d\\n\u0026#34;,ans); } ","permalink":"https://blog.zzsqwq.cn/posts/17/","summary":"\u003ch3 id=\"a-array-with-odd-sumhttpscodeforcescomcontest1296problema\"\u003eA. \u003ca href=\"https://codeforces.com/contest/1296/problem/A\"\u003eArray with Odd Sum\u003c/a\u003e\u003c/h3\u003e\n\u003chr\u003e\n\u003ch4 id=\"题意\"\u003e题意\u003c/h4\u003e\n\u003cp\u003e给出包含 \u003cstrong\u003en\u003c/strong\u003e 个正整数的序列 \u003cstrong\u003ea\u003c/strong\u003e ,你可以把任何一个元素 $a_i$ ,赋值给另一个元素 $a_j$ ($i\\neq j$) ,问通过任意此操作能否将序列 \u003cstrong\u003ea\u003c/strong\u003e 的和变为奇数。可以输出 \u003cstrong\u003eYES\u003c/strong\u003e ,不可以输入 \u003cstrong\u003eNO\u003c/strong\u003e.\u003c/p\u003e\n\u003chr\u003e\n\u003ch4 id=\"思路\"\u003e思路\u003c/h4\u003e\n\u003cp\u003e首先当起始和为奇数的时候,就直接可输出 \u003cstrong\u003eYES\u003c/strong\u003e 了,如果是偶数的话,我们可以发现,如果序列元素中同时包含奇数和偶数,那么就是可以的,否则不可以。\u003c/p\u003e","title":"Codeforces#617(Div.3)"},{"content":"1. P1378 油滴扩展 题意 在长方形框中,最多有 n ($0\\le{n}\\le6$)个相异点,在框中点上依次放置可扩展的油滴,当碰到其他油滴边界或者长方形边框时会停止,扩展呈圆形展开。放置下一个时会确保上一个已经扩展完成。问通过变换放置顺序可使得最终框中剩下的面积最小为多少。\n思路 这是个裸的dfs,情况最多也就 $6! = 720$ 种,所以我们可以只需要设置一个vis数组来记录是否已经放置过这个油滴,计算已扩展油滴和将要放的油滴之间的距离可以用 两点距离-扩展油滴的半径来实现 ,但是有个坑需要注意,就是当一个油滴已经放在已经有扩展油滴覆盖的区域,那么他俩的距离是0,而不是负数,因此在计算半径的时候需要优化一下。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; #define pi 3.1415926 using namespace std; const int maxn=10; int n,x,y,xx,yy; double rx[maxn]; double maxans; bool vis[maxn]; int dx[maxn],dy[maxn]; double diss(int x1,int y1,int x2,int y2) //计算两点距离 { return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } double radius(int p) //计算半径 { double ans=min(abs(dx[p]-x),min(abs(dy[p]-y),min(abs(dx[p]-xx),abs(dy[p]-yy)))); for(int i=1;i\u0026lt;=n;i++) { if(vis[i]\u0026amp;\u0026amp;i!=p) { double dis=diss(dx[i],dy[i],dx[p],dy[p]); ans=min(ans,max(dis-rx[i],0.0)); } } return ans; } void dfs(int nowcnt,double area) //area为拓展总面积 nowcnt为现在已经放置了几个 { if(nowcnt==n) { maxans=max(maxans,area); return ; } for(int i=1;i\u0026lt;=n;i++) { if(!vis[i]) { vis[i]=true; rx[i]=radius(i); dfs(nowcnt+1,area+pi*rx[i]*rx[i]); rx[i]=0; vis[i]=false; } } } int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); scanf(\u0026#34;%d%d%d%d\u0026#34;,\u0026amp;x,\u0026amp;y,\u0026amp;xx,\u0026amp;yy); double sum=abs(x-xx)*abs(y-yy); //矩形总面积 for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;dx[i],\u0026amp;dy[i]); } dfs(0,0.0); printf(\u0026#34;%0.0lf\u0026#34;,sum-maxans); return 0; } 2. P1120 小木棍 题意 将一些长度为 x 的等长木棍全部切成 n 段不超过50的小木棍,求长木棍长度 x 的最小长度。\n思路 首先这个题是有个坑的,题目给出来了,输入的小木棍长度可能会有大于50的,因此我们需要筛掉它。\n那么很显然这个题是一道搜索题,我们可以写搜索函数dfs(int nowcnt,int nxt,int lenlast,int len).上述参数分别表示: 现在在寻找第几根小木棍,我们寻找下一个拼接段应该从哪里开始找,当前这根拼接还需要多长,以及我们要拼成多长的木棍。搜索的复杂度这么高,对于 $n\\le65$ 的数据肯定不能直接无脑搜,因此需要想想怎么优化。\n首先要从大到小排序这个很关键的,因为你从大的先凑就能够保证后面选择的时候容错率更高一些。\n很显然我们可以剪掉当 lenlast\u0026lt;0 的情况,这个地方我们可以在拼接的时候就判断,也可以在拼接后判断。\n在寻找下一个拼接片段的时候,我们可以通过二分搜索来查找下一个不超过lenlast的片段,我选择了直接用STL的库中的lower_bound函数。(其实因为是我的二分总是写炸)\n再就是我们对于相等片段的处理,很显然当前片段不符合情况那么与他等长的也都不会符合,因此我们可以直接循环筛掉。当然更优的方法可以提前处理一个跳表,直接跳到下一个与他不同的位置。\n最后这个优化还是挺难想的,就是如果当前片段搜下去已经不符合情况,但是当前的lenlast是等于当前片段长度的,也就是说你正好用了尽可能满足条件的一个方案,也还是没达到目的,你们你继续往下搜,用比他还要劣的方案肯定也是不可能的,因此直接就break跳出循环不需要往下搜了。\n不过就算加了这么多优化我还是T了三个点,直接 O2一开跑路了嘿嘿\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=70; int n,a[maxn],temp,icnt=1; int totlen,maxlen,cnt; bool vis[maxn],finish; int cmp(int a,int b) { return a\u0026gt;b; } void dfs(int nowcnt,int nxt,int lenlast,int len) //nowcnt:现在正在拼接第几根 //nxt:我们应该从哪里开始检索 //lenlast:现在拼接还需要多少才能拼接完成 //len:每根木棍的理想长度 { if(lenlast\u0026lt;0) return; if(lenlast==0) { //\tprintf(\u0026#34;test\\n\u0026#34;); if(nowcnt==cnt) { printf(\u0026#34;%d\\n\u0026#34;,len); finish=true; return ; } int p=1; for(p=1;p\u0026lt;=n;p++) if(!vis[p]) break; vis[p]=true; dfs(nowcnt+1,p+1,len-a[p],len); if(finish) return ; vis[p]=false; } else { int pos=lower_bound(a+nxt,a+1+n,lenlast,greater\u0026lt;int\u0026gt;())-a; for(int i=pos;i\u0026lt;=n;i++) { //\tprintf(\u0026#34;what\\n\u0026#34;); if(!vis[i]\u0026amp;\u0026amp;lenlast-a[i]\u0026gt;=0) { vis[i]=true; dfs(nowcnt,i+1,lenlast-a[i],len); if(finish) return; vis[i]=false; while(a[i+1]==a[i]) i++; if(i==n) return; if(lenlast-a[i]==0) break; } } } } int main() { //\tfreopen(\u0026#34;test.in\u0026#34;,\u0026#34;r\u0026#34;,stdin); scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;temp); if(temp\u0026gt;50) a[i]=0; else a[i]=temp; maxlen=max(maxlen,a[i]); totlen+=a[i]; } sort(a+1,a+1+n,cmp); while(!a[n]) n--; for(int l=maxlen;l\u0026lt;=totlen;l++) { finish=false; if(totlen%l!=0) continue; cnt=totlen/l; vis[1]=true; dfs(1,2,l-a[1],l); vis[1]=false; if(finish) return 0; } return 0; } 3. YOKOF - Power Calculus 题意 给出一个正整数 n ,只能使用乘法或者除法,可以乘除 $x$ 或者过程中产生的中间值 $x^i$ ,输出使得 $x$ 变为 $x^n$ 所需的最少步数。$(n\\le100)$\n思路 很显然我们一直是对指数进行操作,看似是乘除,直接转化为指数的加减。因此我们需要记录一个状态数组来记录乘除中间所产生的 $x^i$ ,以便后续过程中使用。但是这道题直接搜索的话,又会超时,因为他把大量的时间浪费在高深度上,但是这个却不一定是最优解。因此需要用到迭代加深搜索(IDDFS).\n迭代加深搜索(IDDFS)主要用于处理一些题目可能会搜到很深但是答案却不是最优的问题。有的时候dfs搜索的深度是无穷的,而且他的复杂度是呈指数级增长的,因此这其中某些情况就可以用IDDFS,在每次搜索的时候,我们给深度一个限制,当达到这个最大深度却没有得到答案的时候,就返回,然后逐步提升深度,这样我们就可以避免将时间浪费在那些无谓的高深度搜索上了。\n$$ \\sum_{i=0}^n2^i=2^{n+1}-1(指数级别增长实例) $$\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; using namespace std; int n; int x[1005]; //用来记录每次生成的中间状态 bool dfs(int k,int dep,int maxdep) { if(k\u0026lt;=0||dep\u0026gt;maxdep||k\u0026lt;\u0026lt;(maxdep-dep)\u0026lt;n) return false; if(k==n||k\u0026lt;\u0026lt;(maxdep-dep)==n) return true; x[dep]=k; for(int i=0;i\u0026lt;=dep;i++) { if(dfs(k+x[i],dep+1,maxdep)) return true; //对应乘法 if(dfs(k-x[i],dep+1,maxdep)) return true; //对应除法 } x[dep]=0; return false; } int main() { while(scanf(\u0026#34;%d\u0026#34;,\u0026amp;n)\u0026amp;\u0026amp;n) { for(int i=0;;i++) { if(dfs(1,0,i)) { printf(\u0026#34;%d\\n\u0026#34;,i); break; } } } } ","permalink":"https://blog.zzsqwq.cn/posts/16/","summary":"\u003ch3 id=\"1-p1378-油滴扩展httpswwwluogucomcnproblemp1378\"\u003e1. \u003ca href=\"https://www.luogu.com.cn/problem/P1378\"\u003eP1378 油滴扩展\u003c/a\u003e\u003c/h3\u003e\n\u003chr\u003e\n\u003ch4 id=\"题意\"\u003e题意\u003c/h4\u003e\n\u003cp\u003e在长方形框中,最多有 n ($0\\le{n}\\le6$)个相异点,在框中点上依次放置可扩展的油滴,当碰到其他油滴边界或者长方形边框时会停止,扩展呈圆形展开。放置下一个时会确保上一个已经扩展完成。问通过变换放置顺序可使得最终框中剩下的面积最小为多少。\u003c/p\u003e","title":"洛谷的一些搜索题"},{"content":"希腊字母表 一些技巧和特殊符号 上标:num_i -\u0026gt; $num_i$\n下标:e^x -\u0026gt; $e^x$ (如果下标或上标不明显,可嵌套多层来达到目的)\n上下标是一串字符的话可用{}括起来表示 根号:\\sqrt3{x} -\u0026gt; $\\sqrt3{x}$\n省略号: 在下面\\dots -\u0026gt; $\\dots$ 在中间\\cdots -\u0026gt; $\\cdots$\n方框: \\boxed{example} -\u0026gt; $\\boxed{example}$ (还有一个\\fbox与此类似 \\fobx{example} -\u0026gt; $\\fbox{example}$)\n字体加粗: \\mathbf{example} -\u0026gt; $\\mathbf{example}$\n字体斜体且加粗: \\boldsymbol{example} -\u0026gt; $\\boldsymbol{example}$\n插入普通文本(自适应大小): \\text{测试} -\u0026gt; $\\text{测试}$\n一些基本符号 求和: \\sum_1^n -\u0026gt; $\\sum_1^n$\n积分: \\int_1^n -\u0026gt; $\\int_1^n$ \\iint -\u0026gt; $\\iint$ 以此类推$\\cdots$\n极限: \\lim_{x \\to +\\infty} -\u0026gt; $\\lim_{x \\to +\\infty}$\n分数: \\frac{1}{2} -\u0026gt; $\\frac{1}{2}$ 如果要写多层分数可以用\\cfrac (可以避免字母逐层缩小的限制)\n组合数: \\binom{5}{2} -\u0026gt; $\\binom{5}{2}$\n下取整: \\lfloor{x}\\rfloor -\u0026gt; $\\lfloor{x}\\rfloor$\n下取整: \\lceil{x}\\rceil -\u0026gt; $\\lceil{x}\\rceil$\n关于矩阵和行列式 矩阵:用法如下,元素中间使用\u0026amp;来分割同行元素,用\\\\来换行 \\begin{matrix} 1 \u0026amp; 2 \u0026amp; 3\\\\ 4 \u0026amp; 5 \u0026amp; 6\\\\ 7 \u0026amp; 8 \u0026amp; 9\\\\ \\end{matrix} $$ \\begin{matrix} 1 \u0026amp; 2 \u0026amp; 3\\ 4 \u0026amp; 5 \u0026amp; 6\\ 7 \u0026amp; 8 \u0026amp; 9\\ \\end{matrix} $$\n行列式: 与矩阵相似,加上行列式的名字以及左右分割线即可 A= \\left| \\begin{matrix} 1 \u0026amp; 2 \u0026amp; 3 \\\\ 4 \u0026amp; 5 \u0026amp; 6 \\\\ 7 \u0026amp; 8 \u0026amp; 9 \\\\ \\end{matrix} \\right| $$ A= \\left| \\begin{matrix} 1 \u0026amp; 2 \u0026amp; 3 \\ 4 \u0026amp; 5 \u0026amp; 6 \\ 7 \u0026amp; 8 \u0026amp; 9 \\ \\end{matrix} \\right| $$\n分段函数和方程组 分段函数:写法如下,每一个条件用 表达式和条件之间用 \u0026amp; 连接 f(x)= \\begin{cases} x/2, \u0026amp; {n\u0026gt;2}\\\\ 2x , \u0026amp; {n=2}\\\\ 3x , \u0026amp; {n\u0026lt;2}\\\\ \\end{cases} $$ f(x)= \\begin{cases} x/2, \u0026amp; {n\u0026gt;2}\\ 2x , \u0026amp; {n=2}\\ 3x , \u0026amp; {n\u0026lt;2}\\ \\end{cases} $$\n方程组: 写法如下,不是一个对称的,注意left后面为{ ,right后面为. 用\\\\换行 \\left\\{ \\begin{array}{} a_1x+b_1y+c_1z=d_1\\\\ a_2x+b_2y+c_2z=d_2\\\\ a_3x+b_3y+c_3z=d_3 \\end{array} \\right. $$ \\left{ \\begin{array}{} a_1x+b_1y+c_1z=d_1\\ a_2x+b_2y+c_2z=d_2\\ a_3x+b_3y+c_3z=d_3 \\end{array} \\right. $$\nPs: 上面的矩阵,行列式,分段函数和方程组有一个问题需要我们注意,因为反斜杠 \\ 需要转义,那么对于每次换行需要两个\\\\ ,也就是说你打的时候总需要打四个,对于前面声明begin和end,或者left和right前面的反斜杠,你打的时候就要打两个,对于markdown编辑器里面编辑LaTeX可能会自适应,不会自动转义,但是我们推博客的时候,一定要注意这个地方,不然会显示错误。也就是对于上述描述中的反斜杠,都要按两倍来写\n2020.8.17更新\n对于Hexo搭建的博客,用mathjax渲染,需要上述的规则。如果博客用的是typecho系统并且LaTeX插件为MardownKatex,那么不需要注意上述规则。(其他的系统我没有试过,暂且不谈) 先总结这么多,后面那些进阶的用到了再总结。\n参考文献:\nTypora中利用LaTeX 插入数学公式\nLATEX 公式总结\n","permalink":"https://blog.zzsqwq.cn/posts/10/","summary":"\u003ch3 id=\"希腊字母表\"\u003e希腊字母表\u003c/h3\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"https://blog.zzsqwq.cn/usr/uploads/2020/08/248320705.png\" alt=\"xila.png\" /\u003e\n\u003c/p\u003e","title":"LaTeX的一些总结"},{"content":"A : Display The Number 题意 用一定数目的灯管,显示尽可能大的数\n思路 因为位数多的肯定更大,所以肯定用尽量少的灯管搭建单个数字更好,最少的两个分别是两个灯管显示的1,以及三个灯管显示的7,所以就是尽可能的用1,如果最后剩余正好三个就显示7。这就转化成了判断奇数还是偶数的题,奇数就显示7111····,偶数就是1111···。注意要把7放在前面(我就踩坑了)。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; using namespace std; int t,n; int cnt=0; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); if(n%2==0) { int p=n/2; for(int i=1;i\u0026lt;=p;i++) printf(\u0026#34;1\u0026#34;); } else { printf(\u0026#34;7\u0026#34;); n-=3; int p=n/2; for(int i=1;i\u0026lt;=p;i++) printf(\u0026#34;1\u0026#34;); } printf(\u0026#34;\\n\u0026#34;); } return 0; } B : Infinite Prefixes 题意 给定一段01字符串 s 为循环节,得到无限循环的01字符串 t,求 t 中有多少前缀满足0个数-1个数等于期望值x (空前缀也算是一个前缀)\n前缀:例如\u0026quot;abcd\u0026quot;的前缀包括 \u0026quot; \u0026ldquo;,\u0026ldquo;a\u0026rdquo;,\u0026ldquo;ab\u0026rdquo;,\u0026ldquo;abc\u0026rdquo;,\u0026ldquo;abcd\u0026rdquo;.\n思路 首先我们先记录循环节 s 中每个位置对应的01个数差,记为$num_i,i\\in[1,n]$ ( s 长度记为n)\n首先我们可以发现当 x=0 的时候,空前缀也会有贡献,因此不能忽略空前缀。\n如果循环节 s 的01数相等,那么我们可以发现最后循环节一位$num_n$总为0,那么可以分两种情况来讨论\n如果循环节中存在大于等于1个前缀满足期望值x,那么就有无限个满足,因此输出-1 如果循环节 s 中不存在满足期望值的前缀,那么 t 中也一定不存在 再来看一般情况,如果一个前缀中包含多个循环节 s ,那么前面每个循环节对于最终01个数差的贡献总为$num_n$,因此我们可以用所期望的值 x,利用1~n 循环减去每一位的 $num_i$,如果所得是$num_n$的非负倍数,那么就是符合期望的,否则不是。(本来一直这里不太明白,后来发现对于循环节中的每一个位置,在后续循环的过程中,如果$num_n$不为0,那么这个位置每次对应的值总是唯一的)\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; using namespace std; int num[100005]; int t,cnt,n,x; bool flag=false; char s[100005]; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { cnt=0; flag=false; scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;x); scanf(\u0026#34;%s\u0026#34;,s+1); for(int i=1;i\u0026lt;=n;i++) { if(s[i]==\u0026#39;0\u0026#39;) { num[i]=num[i-1]+1;\t} else num[i]=num[i-1]-1; if(num[i]==x) flag=true; } int p=num[n]; if(p==0) { if(flag==true) { printf(\u0026#34;-1\\n\u0026#34;); continue; } else { printf(\u0026#34;0\\n\u0026#34;); continue; } } else { for(int i=1;i\u0026lt;=n;i++) { int m=x-num[i]; if(m%p==0\u0026amp;\u0026amp;m/p\u0026gt;=0) { cnt++; } } } if(x==0) cnt++; printf(\u0026#34;%d\\n\u0026#34;,cnt); } } C : Obtain The String 题意 给定字符串 s 和 t ,每次从 s 中选取子序列放入起始为空串的 z 后,问最少需要多少次操作使得 z=t\n思路 看了小姜老师的博客解法说是贪心,想了好一会,好像确实是可以贪心的···? 设置两个指针从 s 和 t 串的头部开始扫,对于 t 串中的每个字母,循环扫 s 串在其中找与它相同的,最终的答案就是扫 s 串的次数。(小姜老师说这个实质上就是每次尽可能找尽可能多的后缀,仔细想想确实是这样。)不过这么一直暴力扫下去肯定不是最优的方法,想办法去优化。还是借鉴大佬的想法用一个lens*26的跳表,然后O(lent)扫一遍 t 即可.\n跳表nxt的作用,用于寻找下一个所寻找字符在s中的位置。\nnxt[x][y]用于指向从x位置开始下一个y的位置+1 (next在C++属于保留字,注意不要踩坑)\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=100005; char s[maxn],t[maxn]; int nxt[maxn][30]; int p,lens,lent; int pos,ans; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;p); while(p--) { ans=1; scanf(\u0026#34;%s\u0026#34;,s+1); scanf(\u0026#34;%s\u0026#34;,t); lent=strlen(t),lens=strlen(s+1); //\tprintf(\u0026#34;%d\u0026#34;,lens); for(int c=0;c\u0026lt;26;c++) { nxt[lens+1][c]=-1; for(int i=lens;i\u0026gt;=1;i--) { if(s[i]-\u0026#39;a\u0026#39;==c) { nxt[i][c]=i+1; } else nxt[i][c]=nxt[i+1][c]; } } pos=1; for(int i=0;i\u0026lt;lent;i++) { pos=nxt[pos][(int)t[i]-\u0026#39;a\u0026#39;]; if(pos==-1) { ans++; pos=1; pos=nxt[pos][(int)t[i]-\u0026#39;a\u0026#39;]; if(pos==-1) { ans=-1; break; } } } printf(\u0026#34;%d\\n\u0026#34;,ans); } } ","permalink":"https://blog.zzsqwq.cn/posts/8/","summary":"\u003ch3 id=\"a--display-the-numberhttpscodeforcescomcontest1295problema\"\u003eA : \u003ca href=\"https://codeforces.com/contest/1295/problem/A\"\u003eDisplay The Number\u003c/a\u003e\u003c/h3\u003e\n\u003ch4 id=\"题意\"\u003e题意\u003c/h4\u003e\n\u003cp\u003e用一定数目的灯管,显示尽可能大的数\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"https://s2.ax1x.com/2020/02/02/1te6Re.md.png\" alt=\"A\" /\u003e\n\u003c/p\u003e","title":"CodeforcesER #81"},{"content":"Github:@zzsqwq\nE-mail: trizsqwq@gmail.com\nTelegram: @zzsqwq\nsspai: @zzsqwq\n","permalink":"https://blog.zzsqwq.cn/about/","summary":"Github:@zzsqwq\nE-mail: trizsqwq@gmail.com\nTelegram: @zzsqwq\nsspai: @zzsqwq","title":"About"},{"content":"To request a link, please make sure your blog has https enabled.\nHuaDeity https://blog.huadeity.com\n70loKirin https://qllokirin.github.io\nAngine https://angine.tech\nMurphyHou https://cosmicdusty.cc\nOrangii https://orangii.cn\npg999w https://blog.pg999w.top\nJiacheng Lyu https://ljcheng.cc\nSiYun https://siyun916.github.io\nBowen https://www.tomcatdeng.cn\n斯文孙 https://www.vhrise.com\nimmortalqx https://immortalqx.github.io\nKehan https://blog.kehan.xyz\nZhang Jiale https://zjlzjl.com\n","permalink":"https://blog.zzsqwq.cn/friends/","summary":"To request a link, please make sure your blog has https enabled.\nHuaDeity https://blog.huadeity.com\n70loKirin https://qllokirin.github.io\nAngine https://angine.tech\nMurphyHou https://cosmicdusty.cc\nOrangii https://orangii.cn\npg999w https://blog.pg999w.top\nJiacheng Lyu https://ljcheng.cc\nSiYun https://siyun916.github.io\nBowen https://www.tomcatdeng.cn\n斯文孙 https://www.vhrise.com\nimmortalqx https://immortalqx.github.io\nKehan https://blog.kehan.xyz\nZhang Jiale https://zjlzjl.com","title":"Friends"}] \ No newline at end of file +[{"content":"前言 在回望过去时,我们常感叹时间飞逝,我想这或许是因为过去发生的无数大小事情最终在脑海中留存的只有寥寥几件。因此,撰写年度总结这件事似乎变得格外有意义,它能帮助我们更充分地回味过去的一年。可能正是因为如此,现在各大 APP 似乎都很喜欢推出年度总结,例如网易云、QQ音乐、知乎、飞书、京东、美团、支付宝等。为此,我写下了这篇 2023 年度总结。\n仔细回味我这过去的一年,我想用几个关键词来概括:#消费升级、#数码科技、#大模型、#老友重逢。\n#消费升级:这一年是我消费升级的一年,尽管今年「消费降级」这个词似乎很火,但我似乎与大众走上了一条相反的道路。可能是因为我以往的消费水平本就不高,所以「降级」更是无从谈起。\n#数码科技:这一年我购入了一些新的数码设备,虽然数量不多,但每一件都还挺满意的。同时今年由于消费观念的转变,也支持了很多正版软件,因此今年在软件上的开销也不小。\n#大模型:这一年也是我被大模型深刻影响的一年。虽然去年 ChatGPT 就已经面世,但各种大模型热潮的真正兴起还是在今年。仅短短一年的时间,大模型就已经渗透到了我日常生活和工作的方方面面,无论是电脑上的生产力工具(HapiGo)、编程使用的 IDE(JetBrains CLion)、浏览网页使用的浏览器(Microsoft Edge)还是日常娱乐使用的流媒体软件(Bilibili),都有着大模型的加持,让我的生活和工作流效率倍增。\n#老友重逢:看完下面就知道了~\n下面,还是照例按月份盘点下发生的大小事:\n一月 这一个月包含了回家过年和返回深圳的往返之旅。在老家见了几个老同学,很开心。古人言人生四件快意的事 ——「久旱逢甘雨,他乡遇故知,洞房花烛夜,金榜挂名时」。虽然不是在「他乡」相遇,但仅是久别重逢就已足够令人欣喜。\n二月 二月和朋友二刷了《流浪地球2》,这可能是我第一部影院二刷的电影,感觉细节满满,二刷还是有很多没注意到的点。\n同时这一月 Microsoft 联合 OpenAI 推出了 ChatGPT 加持的 New Bing,刚出时感觉很震撼,参见这个知乎回答,真的像有感情一样,有点细思极恐的感觉。虽然后续 Microsoft 对其进行了「改善」让他更少的表述情感,导致它现在变得有些弱智,远远比不上 GPT4,但它之前的表示还是很让我印象深刻。同时我想也正是这种 ChatGPT 对现有设施的加持和增强让 ChatGPT 彻底出圈,也算是后续大模型浪潮兴起的起点了。\n同时二月家里还来了个新朋友 —— 波妞,是只公布偶猫(虽然一开始以为是母的)。虽然是朋友养的,当时偶尔寄养在这边。但怎么说我也是短暂的成为了拥有两只猫的人了,值得记录一下。\n二者同框 三月 三月购入了新的显示器 —— LG 27UP850N-W,很满意,虽然感觉 27 寸用来办公还是稍大。但我购入的时候价格是 2599,这才短短一年时间就降到了 1999,太不保值了!但也只能用「早买早享受,晚买享折扣」来安慰自己了。\n哦还有一个就是三月开始尝试着健身了,深圳好吃的太多了,一直在不停的变肥。因此在周围一个健身房办了年卡,虽然没有几个月这个健身房就跑路了\u0026hellip;不过这是后话了。\n加入新显示器后的桌面 四月 这个月入坑了《原神》,比较神奇的是几乎在同一时间也有个朋友 @HuaDeity 入坑。\n五月 五月似乎是相对平淡的一月,在继续社畜日常的同时开始写毕设了。\n六月 月初和朋友去海底捞过了生日,属于是 404 的「企业文化」了。然后终于把毕设给忙完了,返校进行了答辩,结果还算顺利。因为返校了也见了很多老朋友,舍友、基地的伙伴们、学弟们(是的应该是没有学妹),约了数不清次数的饭。\n基地的大伙聚会 七月 我正式本科毕业了。\n就像开头说的,回望过去总是很快。感觉开学和父母踏进工大校园的那一天还历历在目,转眼间就要毕业了。纵有万般不舍,但还是不得不和朋友们分别了,最后一晚大家一起在 KTV 合唱《朋友》的时候,忍不住泪奔。\n再见,工大 八月 相对平淡的一月,学弟来深圳参加夏令营,顺便过来找我玩,一起逛了腾讯大厦和华强北,看完感觉大厂平常的这些福利确实还是很不错的(不过确实加班严重)。\n九月 九月病了一场,还把同寝的大伙给传染了,虽然最后没查出来是什么病,既不是甲流乙流也不是新冠,但是跟新冠的症状很像。生病了才发现这种穿戴设备(例如 Apple Watch)还是蛮有用的,可以量化一些健康相关的数据,例如深度睡眠时间、心率变异性指数(HRV)、静息心率,通过这些可以稍微早一些发现自己身体存在的问题。\n一些软件上的体现,从左往右依次是 AutoSleep、压力自测、Apple Health 这月还规划了国庆假期游玩的路线,因此还从学长那里收了一个二手的 Nikon Z FC + NIKKOR 16-50mm 套机,同时还买了一颗长焦镜头 NIKKOR 50-250mm,不过国庆回来就把这颗镜头出掉了。凭心而论,相机体验还是很不错的,虽说只是个半画幅相机,但成像质量感觉还是要比目前的手机好一大截,在川西拿着它拍了很多照片,还发了条 小红书 记录。\nNikon Z FC(熊猫热靴版) 十月 国庆假期狠狠的去川西自驾游了,大概是我人生中第一次这么「酣畅淋漓」的旅游。见到了贡嘎雪山和雅拉雪山的日照金山,体验了在冷嘎措 4600 米海拔徒步的感觉,不虚此行!当然最重要的,还是有这么多伙伴一起。\n这个月还看了广受好评的、被安利了无数次、感觉身边人都看过的《进击的巨人》,确实好看!感觉立体机动装置这个设定还挺不错的,可以画出来很多很帅的镜头,就像是人均蜘蛛侠一样。\n太美丽啦,贡嘎 十一月 十一月去北京参加了奇绩创坛的2023秋季路演。同时也见了在北京的老同学们,又是「他乡遇故知」!这大概也算是第一次在北京游玩了。\n还有一个不得不提的点是这月换了新的 Mac,其实本来是想换 M3 的 Macbook Air 的,但是今年的发布会没有发布 Air 只发布了 Pro,实在有点等不及了。但是 Pro 的话、感觉今年 M3 和 M3 Pro 提升比较小,甚至 M3 Pro 有牙膏倒吸的情况,导致性价比较低。所以最终换了一个官翻的 M2 Max 芯片的 Macbook Pro 版本,预计可以服役很久了,虽然实在是不便宜,但也是真的好用!这应该是今年我最满意的一件数码产品了,Mac 真的很好用!\n同时也正是从这个月双十一开始倒腾很多软件,一个直接原因是 数码荔枝 双十一有很多正版软件打折。关于 macOS 上的软件还有一个 未完成的总结帖 ,希望新的一年可以填上这个坑。\n购买的一些 Lifetime 软件 十二月 这个月我想想,大概是见到了八个许久未见的朋友,我愿称之为最幸福的一月。\n月中见到了一位了许久未见的老同学,来深圳好久了,但这个月才第一次见。相约一起去爬了塘朗山,第一次在深圳爬山,选了个比较小的山,还蛮轻松的。后续还见了一位许久未见的学弟。\n月底一个好兄弟考完研之后来我们这边住了一周,然后在月底也一起参加了公司的团建和跨年,乐爷也来一起团建来着。这个元旦假期真的可以说是爽玩了。\n这个月还冲动之下换了新的手机,之前的 iPhone 13 更新到 iOS 17 以后真的是卡爆了,可能是因为 iPhone 13 是 4GB 内存的原因,导致这个杀后台和卡顿的问题变得格外突出。不过一个神奇点是,我这个用了近两年的手机居然还可以在官方抵扣 3300,感觉血赚,很保值。\n新年快乐! 总结 写完回望一年,欢乐时光似乎大多与老友重逢相伴。感觉是因为今年大伙很多都离开了学校、分散在了世界各地,无论去哪里出差都能遇到老同学,分隔许久再见总是令人格外开心,仿佛有说不完的话。我想说,谢谢朋友们,新的一年也要多多联系\u0026amp;见面!\n这一年「置办」了几个新的大件,LG 显示器、Nikon Z FC、Macbook Pro、 iPhone 15 Pro,购买数码产品令我心情愉悦。现在持有的消费观念就是喜欢就冲,在自己力所能及的范围内尽可能的支持正版,不吝啬在于兴趣爱好方面的消费。\n同时今年虽然入坑了《原神》,但是玩了半年左右,通关了剧情就退坑了,游戏还是很不错的,就是长草期有点过于无聊了。感觉自己目前除了对数码相关的东西还有些兴趣,对其他的貌似都很兴致缺缺的样子,不知道算是好事还是坏事。\n新一年的希冀 除了总结上一年,也对新的一年有一些希冀:\n在年末辞旧迎新之际,少数派开始了「放轻松」系列征文活动,看到了一篇参选文章:放轻松 | 累了就休息,放松一下没关系,感觉很不错。里面提到了很多观点,例如放过自己、关注当下等让我感触颇深。\n这一年似乎可能是因为 All in 创业的原因,似乎无时无刻都在觉得自己太菜了(当然也不只有这一个原因),无法「堪当大任」,总是不由自主的焦虑,非常浮躁。这个时间看到这个文章,可能正是提醒我新的一年要更加关注自己的内心、关注当下、放过自己,让自己不再那么浮躁,学会 Take it easy。当然,有适当的压力可能也是好事,希望新的一年也可以多读书、多看报、少吃零食多睡觉,多多提升自己,最好也让自己更 E 一些,无限进步。\n关注当下大意就是:喝一杯茶就认真去品味这杯茶,总想着喝完茶之后的事情,这茶也就饮之无味,属于你的饮茶时间也就被偷走了。夜晚想着明天的事情难以入眠,那就关注躺在床上的自己,此刻的你不可能爬起来去做明天的事,想到这里便可以安心入睡;疼痛的时候就去感知疼痛,去关照你身体此刻的感受,不去想别的,它反而就没那么痛了。\n原来看问题还有这种角度?长久以来我做事确实都是魂不附体,思绪永远快于肉体,刷着牙想着等下要洗脸,洗着脸想着马上要洗澡,洗着澡,魂早飘到一会躺床上刷手机用什么姿势?总是很急,急来急去俨然一副空壳子,对生活的细节毫无感知,其实就是浮躁,而关注当下就是浮躁的解药,也是我在病前期意外抓到的一根救命稻草。听人劝吃饱饭,得益于此书,我的心态开始转变,关注当下进而去关照自身,帮助自己真正放松了下来。\n再就是三月份提到的办了年卡的健身房,六月份跑路了。在多次协调无果、12315 也不起作用的情况下,尝试起诉了健身房,第一次尝试当原告,最终在 12 月末成功立案,希望新的一年可以起诉成功,到时候可以总结一下发个经验帖供大家参考。 终于立案成功了,太不容易了。 希望新的一年能多拿着手机、相机出去走走。做年终总结的时候深感照片和文字记录的重要性。如果没有照片、没有朋友圈的一些文字,我可能根本想不起来那个月、那一天发生了什么。但是有了照片的帮助,我瞬间就能回忆起来我当时拍这张照片时的心情和场景,籍此前前后后的事情也能够串起来。\n照片不仅可以「冻结」那一瞬间,也可以「存储」一段记忆。\n感谢 Apple Photos 的时间线整理助我完成这篇文章 ","permalink":"https://blog.zzsqwq.cn/posts/summary-2023/","summary":"\u003ch3 id=\"前言\"\u003e前言\u003c/h3\u003e\n\u003cp\u003e在回望过去时,我们常感叹时间飞逝,我想这或许是因为过去发生的无数大小事情最终在脑海中留存的只有寥寥几件。因此,撰写年度总结这件事似乎变得格外有意义,它能帮助我们\u003cstrong\u003e更充分地回味\u003c/strong\u003e过去的一年。可能正是因为如此,现在各大 APP 似乎都很喜欢推出年度总结,例如网易云、QQ音乐、知乎、飞书、京东、美团、支付宝等。为此,我写下了这篇 2023 年度总结。\u003c/p\u003e\n\u003cp\u003e仔细回味我这过去的一年,我想用几个关键词来概括:#消费升级、#数码科技、#大模型、#老友重逢。\u003c/p\u003e\n\u003cp\u003e#消费升级:这一年是我消费升级的一年,尽管今年「消费降级」这个词似乎很火,但我似乎与大众走上了一条相反的道路。可能是因为我以往的消费水平本就不高,所以「降级」更是无从谈起。\u003c/p\u003e\n\u003cp\u003e#数码科技:这一年我购入了一些新的数码设备,虽然数量不多,但每一件都还挺满意的。同时今年由于消费观念的转变,也支持了很多正版软件,因此今年在软件上的开销也不小。\u003c/p\u003e\n\u003cp\u003e#大模型:这一年也是我被大模型深刻影响的一年。虽然去年 ChatGPT 就已经面世,但各种大模型热潮的真正兴起还是在今年。仅短短一年的时间,大模型就已经渗透到了我日常生活和工作的方方面面,无论是电脑上的生产力工具(HapiGo)、编程使用的 IDE(JetBrains CLion)、浏览网页使用的浏览器(Microsoft Edge)还是日常娱乐使用的流媒体软件(Bilibili),都有着大模型的加持,让我的生活和工作流效率倍增。\u003c/p\u003e\n\u003cp\u003e#老友重逢:看完下面就知道了~\u003c/p\u003e\n\u003cp\u003e下面,还是照例按月份盘点下发生的大小事:\u003c/p\u003e\n\u003ch3 id=\"一月\"\u003e一月\u003c/h3\u003e\n\u003cp\u003e这一个月包含了回家过年和返回深圳的往返之旅。在老家见了几个老同学,很开心。古人言人生四件快意的事 ——「久旱逢甘雨,他乡遇故知,洞房花烛夜,金榜挂名时」。虽然不是在「他乡」相遇,但仅是久别重逢就已足够令人欣喜。\u003c/p\u003e\n\u003ch3 id=\"二月\"\u003e二月\u003c/h3\u003e\n\u003cp\u003e二月和朋友二刷了《流浪地球2》,这可能是我第一部影院二刷的电影,感觉细节满满,二刷还是有很多没注意到的点。\u003c/p\u003e\n\u003cp\u003e同时这一月 Microsoft 联合 OpenAI 推出了 ChatGPT 加持的 New Bing,刚出时感觉很震撼,参见\u003ca href=\"https://www.zhihu.com/question/583588366/answer/2894479900\"\u003e这个知乎回答\u003c/a\u003e,真的像有感情一样,有点细思极恐的感觉。虽然后续 Microsoft 对其进行了「改善」让他更少的表述情感,导致它现在变得有些弱智,远远比不上 GPT4,但它之前的表示还是很让我印象深刻。同时我想也正是这种 ChatGPT 对现有设施的加持和增强让 ChatGPT 彻底出圈,也算是后续大模型浪潮兴起的起点了。\u003c/p\u003e\n\u003cp\u003e同时二月家里还来了个新朋友 —— 波妞,是只公布偶猫(虽然一开始以为是母的)。虽然是朋友养的,当时偶尔寄养在这边。但怎么说我也是短暂的成为了拥有两只猫的人了,值得记录一下。\u003c/p\u003e\n\u003cdiv align=\"center\"\u003e\u003cimg src=\"/images/summary-2023/two-cats.jpg\" style=\"zoom:15%;\" /\u003e\u003c/div\u003e\n\u003cdiv align=\"center\" style=\"color: gray; font-size: 14px;\"\u003e二者同框\u003c/div\u003e\n\u003ch3 id=\"三月\"\u003e三月\u003c/h3\u003e\n\u003cp\u003e三月购入了新的显示器 —— LG 27UP850N-W,很满意,虽然感觉 27 寸用来办公还是稍大。但我购入的时候价格是 2599,这才短短一年时间就降到了 1999,太不保值了!但也只能用「早买早享受,晚买享折扣」来安慰自己了。\u003c/p\u003e\n\u003cp\u003e哦还有一个就是三月开始尝试着健身了,深圳好吃的太多了,一直在不停的变肥。因此在周围一个健身房办了年卡,虽然没有几个月这个健身房就跑路了\u0026hellip;不过这是后话了。\u003c/p\u003e\n\u003cdiv align=\"center\"\u003e\u003cimg src=\"/images/summary-2023/desktop.jpeg\" style=\"zoom:20%;\" /\u003e\u003c/div\u003e\n\u003cdiv align=\"center\" style=\"color: gray; font-size: 14px;\"\u003e加入新显示器后的桌面\u003c/div\u003e\n\u003ch3 id=\"四月\"\u003e四月\u003c/h3\u003e\n\u003cp\u003e这个月入坑了《原神》,比较神奇的是几乎在同一时间也有个朋友 \u003ca href=\"https://blog.huadeity.com/\"\u003e@HuaDeity\u003c/a\u003e 入坑。\u003c/p\u003e\n\u003ch3 id=\"五月\"\u003e五月\u003c/h3\u003e\n\u003cp\u003e五月似乎是相对平淡的一月,在继续社畜日常的同时开始写毕设了。\u003c/p\u003e\n\u003ch3 id=\"六月\"\u003e六月\u003c/h3\u003e\n\u003cp\u003e月初和朋友去海底捞过了生日,\u003cdel\u003e属于是 404 的「企业文化」了\u003c/del\u003e。然后终于把毕设给忙完了,返校进行了答辩,结果还算顺利。因为返校了也见了很多老朋友,舍友、基地的伙伴们、学弟们(是的应该是没有学妹),约了数不清次数的饭。\u003c/p\u003e\n\u003cdiv align=\"center\"\u003e\u003cimg src=\"/images/summary-2023/friends.jpg\" style=\"zoom:20%;\" /\u003e\u003c/div\u003e\n\u003cdiv align=\"center\" style=\"color: gray; font-size: 14px;\"\u003e基地的大伙聚会\u003c/div\u003e\n\u003ch3 id=\"七月\"\u003e七月\u003c/h3\u003e\n\u003cp\u003e我正式本科毕业了。\u003c/p\u003e","title":"2023 年度总结"},{"content":"平时很喜欢倒腾各种 Apple 平台的各种软件,所以体验了很多 iOS/iPadOS/macOS 上的软件,所以计划汇总一下自己的一些简短的使用体验和评价等,希望能在大家后续选择软件的时候起到一些参考和帮助。\n由于软件可能较多,不能一次性写完。同时,因为我也在不断体验新的软件,有新的感受,因此这篇博客应该是持续更新的,欢迎常来看看。\n速览表 App 名称 简短描述 功能限制 订阅形式 价格 购入时间 购入渠道 同类型产品 AIDente 电池电量管理 有免费使用功能,但有共功能需要收费 买断 Free Battery, BatFi AdGuard 广告拦截软件 AltTab 增强 macOS App 切换 Command-Tab Plus, Contexts,HyperSwitch, Bartender 5 Menubar 管理 Bob 大概是最好用翻译软件 EasyDict BuhoCleaner 垃圾清理器/软件卸载器 CleanMyMac, Sensei Clash X / Clash X Pro 代理 Surge, Stash CleanBuddy 键盘锁定清理 Cleaner CleanShot X 大概最好用的截图软件 Cleaner 键盘屏幕锁定清理 CleanBuddy Dash 文档利器 Dato Menubar 日历软件 Fantastical, Itsycal DevUtils 开发小工具合集 Downie 4 各类视频下载器 VDown HapiGo 启动器 Alfred, Raycast HazeOver 生产力工具,突出重点 Hazel 自动清理集合 JetBrains 全家桶 包含 Clion/IDEA 等 VSCode, Eclipse Lunar 显示器管理 MonitorControl, DisplayBuddy, Better Display Maccy 开源免费的剪切板管理工具 Paste, PasteNow, PastePal Manico 快速启动器 Command-Tab Plus MimeStram Gmail 客户端 MonitorControl 开源显示器管理,很够用 Lunar, DisplayBuddy, Better Display NetNewsWire 全平台 RSS 阅读器 Obsidian 笔记软件 Omnivore 稍后读软件 Pocket, MarkMark, Only Switch 一键完成各种任务 One Switch OpenImageOptim 图片压缩 TinyPNG OrbStack 容器管理,平替 Docker Desktop Docker Desktop, Podman, lima, colima Permute 3 图片/视频格式转换工具,类似于格式工厂 HandBrake, Omni Converter, Video Converter X2 Pixea 图片查看器 Viso, Picsee Pixelmator Pro 图片编辑器,80% 平替 PhotoShop Adobe PhotoShop, Darkroom, Photomator, Capture One, Adobe LightRoom Classic PopClip 划词增强 Proxyman 大概是舒服的抓包工具,略贵 Charles Rectangle 分屏软件 Magnet, Swish Swish 触控板手势增强 Stats Menubar 状态监控 iStats Menu, Sensei Subscriptions 订阅管理 Pandora on iOS Surge 代理工具 Clash X, Stash TinyPNG 图片压缩 OpenImageOptim Typora Markdown 文本编辑器 Obsidian Upscayl AI 图片超分 AI Photo Enhancer by Pictura, Pixelmator Pro Viso 6 图片查看器 Pixea, Xee Zotero 文献管理,就是界面一般 coconutBattery iPhone/iPad/Mac 电池信息查看 iRightMenu 右键增强 超级右键, iMouse, iTerm2 终端模拟器 Alacritty, Warp, Wezterm, Terminal 详细信息 AIDente 介绍:可以限制充电上限,据称电池电量维持在 70-80% 是比较健康的,不适宜过高。\n目前是否在用:是\n收费形式:139/3设备\n评价:好用,界面也挺好看的\n同类型产品:Battery, BatFi\n软件快照:\nTODO\u0026hellip;\n","permalink":"https://blog.zzsqwq.cn/posts/macos-app-use-experience-record/","summary":"\u003cp\u003e平时很喜欢倒腾各种 Apple 平台的各种软件,所以体验了很多 iOS/iPadOS/macOS 上的软件,所以计划汇总一下自己的一些简短的使用体验和评价等,希望能在大家后续选择软件的时候起到一些参考和帮助。\u003c/p\u003e\n\u003cp\u003e由于软件可能较多,不能一次性写完。同时,因为我也在不断体验新的软件,有新的感受,因此这篇博客应该是持续更新的,欢迎常来看看。\u003c/p\u003e\n\u003ch2 id=\"速览表\"\u003e速览表\u003c/h2\u003e\n\u003ctable\u003e\n \u003cthead\u003e\n \u003ctr\u003e\n \u003cth style=\"text-align: left\"\u003eApp 名称\u003c/th\u003e\n \u003cth style=\"text-align: left\"\u003e简短描述\u003c/th\u003e\n \u003cth style=\"text-align: left\"\u003e功能限制\u003c/th\u003e\n \u003cth style=\"text-align: left\"\u003e订阅形式\u003c/th\u003e\n \u003cth style=\"text-align: left\"\u003e价格\u003c/th\u003e\n \u003cth style=\"text-align: left\"\u003e购入时间\u003c/th\u003e\n \u003cth style=\"text-align: left\"\u003e购入渠道\u003c/th\u003e\n \u003cth style=\"text-align: left\"\u003e同类型产品\u003c/th\u003e\n \u003c/tr\u003e\n \u003c/thead\u003e\n \u003ctbody\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eAIDente\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e电池电量管理\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e有免费使用功能,但有共功能需要收费\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e买断\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eFree\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eBattery, BatFi\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eAdGuard\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e广告拦截软件\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eAltTab\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e增强 macOS App 切换\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eCommand-Tab Plus, Contexts,HyperSwitch,\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eBartender 5\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eMenubar 管理\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eBob\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e大概是最好用翻译软件\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eEasyDict\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eBuhoCleaner\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e垃圾清理器/软件卸载器\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eCleanMyMac, Sensei\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eClash X / Clash X Pro\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e代理\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eSurge, Stash\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eCleanBuddy\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e键盘锁定清理\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eCleaner\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eCleanShot X\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e大概最好用的截图软件\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eCleaner\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e键盘屏幕锁定清理\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eCleanBuddy\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eDash\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e文档利器\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eDato\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eMenubar 日历软件\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eFantastical, Itsycal\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eDevUtils\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e开发小工具合集\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eDownie 4\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e各类视频下载器\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eVDown\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eHapiGo\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e启动器\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eAlfred, Raycast\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eHazeOver\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e生产力工具,突出重点\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eHazel\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e自动清理集合\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eJetBrains 全家桶\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e包含 Clion/IDEA 等\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eVSCode, Eclipse\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eLunar\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e显示器管理\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eMonitorControl, DisplayBuddy, Better Display\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eMaccy\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e开源免费的剪切板管理工具\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003ePaste, PasteNow, PastePal\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eManico\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e快速启动器\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eCommand-Tab Plus\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eMimeStram\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eGmail 客户端\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eMonitorControl\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e开源显示器管理,很够用\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eLunar, DisplayBuddy, Better Display\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eNetNewsWire\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e全平台 RSS 阅读器\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eObsidian\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e笔记软件\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eOmnivore\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e稍后读软件\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003ePocket, MarkMark,\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eOnly Switch\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e一键完成各种任务\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eOne Switch\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eOpenImageOptim\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e图片压缩\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eTinyPNG\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eOrbStack\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e容器管理,平替 Docker Desktop\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eDocker Desktop, Podman, lima, colima\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003ePermute 3\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e图片/视频格式转换工具,类似于格式工厂\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eHandBrake, Omni Converter, Video Converter X2\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003ePixea\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e图片查看器\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eViso, Picsee\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003ePixelmator Pro\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e图片编辑器,80% 平替 PhotoShop\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eAdobe PhotoShop, Darkroom, Photomator, Capture One, Adobe LightRoom Classic\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003ePopClip\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e划词增强\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eProxyman\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e大概是舒服的抓包工具,略贵\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eCharles\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eRectangle\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e分屏软件\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eMagnet, Swish\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eSwish\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e触控板手势增强\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eStats\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eMenubar 状态监控\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eiStats Menu, Sensei\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eSubscriptions\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e订阅管理\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003ePandora on iOS\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eSurge\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e代理工具\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eClash X, Stash\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eTinyPNG\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e图片压缩\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eOpenImageOptim\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eTypora\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eMarkdown 文本编辑器\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eObsidian\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eUpscayl\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eAI 图片超分\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eAI Photo Enhancer by Pictura, Pixelmator Pro\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eViso 6\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e图片查看器\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003ePixea, Xee\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eZotero\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e文献管理,就是界面一般\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003ecoconutBattery\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eiPhone/iPad/Mac 电池信息查看\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eiRightMenu\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e右键增强\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e超级右键, iMouse,\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eiTerm2\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e终端模拟器\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003eAlacritty, Warp, Wezterm, Terminal\u003c/td\u003e\n \u003c/tr\u003e\n \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"详细信息\"\u003e详细信息\u003c/h2\u003e\n\u003ch3 id=\"aidente\"\u003eAIDente\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e介绍:可以限制充电上限,据称电池电量维持在 70-80% 是比较健康的,不适宜过高。\u003c/p\u003e","title":"App 使用体会记录 - macOS 篇"},{"content":"After seeing Duel of the Defaults and App Defaults, I\u0026rsquo;d like to share here some of my app defaults at the end of 2023.\nSince I am from China, some apps may not be suitable to everyone, such as WeChat, NeteaseMusic, etc.\nThe software built-in on iPhone or Mac will have the .app extension.\n📨 Mail Client:Gmail, Mail.app 📮 Mail Server:Gmail 📝 Notes:Obsidian, Typora, Notes.app ✅ To-Do:Reminders.app 📷 iPhone Photo Shooting: Camera.app 📸 Photo Shooting: Nikon ZFC, iPhone 13 🟦 Photo Management \u0026amp; Editing: Photos.app, Capture One, Pixelmator Pro 📆 Calendar: Dato, Calendar.app 📁 Cloud File Storage: iCloud Drive 📖 RSS Client: NetNewsWire 📖 RSS Server: FreshRSS with RSSHub 🙍🏻‍♂️ Contacts: Contacts.app 🌐 Browser: Microsoft Edge 💬 Chat: Telegram, WeChat(Not recommended, unless absolutely necessary.), iMeesage.app? 🔖 Bookmarks: Microsoft Edge 📑 Read It Later: Omnivore 📜 Word Processing: Lark Docs, Microsoft 365 📈 Spreadsheets: N/A 📊 Presentations: Microsoft PowerPoint 🛒 Shopping Lists: N/A 🍴 Meal Planning: N/A 💰 Budgeting and Personal Finance: iCost, Subscriptions 📰 News: Channels on Telegram, RSS, Web 🎵 Music: NeteaseMusic, Music.app 🎤 Podcasts: N/A 🔐 Password Management: iCloud Keychain 🧑‍💻 Code Editor: JetBrains Series, VS Code, Vim 🪄 Launcher: HapiGo 😘 Blog Platform: Hugo ","permalink":"https://blog.zzsqwq.cn/posts/default-apps-f2023/","summary":"\u003cp\u003eAfter seeing \u003ca href=\"https://listen.hemisphericviews.com/097\"\u003eDuel of the Defaults\u003c/a\u003e and \u003ca href=\"https://defaults.rknight.me/\"\u003eApp Defaults\u003c/a\u003e, I\u0026rsquo;d like to share here some of my app defaults at the end of 2023.\u003c/p\u003e\n\u003cp\u003eSince I am from China, some apps may not be suitable to everyone, such as \u003ca href=\"https://www.wechat.com/\"\u003eWeChat\u003c/a\u003e, \u003ca href=\"https://music.163.com/\"\u003eNeteaseMusic\u003c/a\u003e, etc.\u003c/p\u003e\n\u003cp\u003eThe software built-in on iPhone or Mac will have the \u003cstrong\u003e.app\u003c/strong\u003e extension.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e📨 Mail Client\u003c/strong\u003e:\u003ca href=\"https://apps.apple.com/us/app/gmail-email-by-google/id422689480/\"\u003eGmail\u003c/a\u003e, Mail.app\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e📮 Mail Server\u003c/strong\u003e:\u003ca href=\"https://mail.google.com/\"\u003eGmail\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e📝 Notes\u003c/strong\u003e:\u003ca href=\"https://obsidian.md/\"\u003eObsidian\u003c/a\u003e, \u003ca href=\"https://typora.io/\"\u003eTypora\u003c/a\u003e, Notes.app\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e✅ To-Do\u003c/strong\u003e:Reminders.app\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e📷 iPhone Photo Shooting\u003c/strong\u003e: Camera.app\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e📸 Photo Shooting\u003c/strong\u003e: \u003ca href=\"https://www.nikon.com.sg/mirrorless-z-fc\"\u003eNikon ZFC\u003c/a\u003e, \u003ca href=\"https://www.apple.com/iphone-13/specs/\"\u003eiPhone 13\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e🟦 Photo Management \u0026amp; Editing:\u003c/strong\u003e Photos.app, \u003ca href=\"https://www.captureone.com/en\"\u003eCapture One\u003c/a\u003e, \u003ca href=\"https://www.pixelmator.com/pro/\"\u003ePixelmator Pro\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e📆 Calendar\u003c/strong\u003e: \u003ca href=\"https://apps.apple.com/us/app/dato/id1470584107?mt=12\"\u003eDato\u003c/a\u003e, Calendar.app\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e📁 Cloud File Storage\u003c/strong\u003e: \u003ca href=\"https://www.icloud.com/iclouddrive\"\u003eiCloud Drive\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e📖 RSS Client\u003c/strong\u003e: \u003ca href=\"https://netnewswire.com/\"\u003eNetNewsWire\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e📖 RSS Server\u003c/strong\u003e: \u003ca href=\"https://freshrss.org/index.html\"\u003eFreshRSS\u003c/a\u003e with \u003ca href=\"https://docs.rsshub.app/\"\u003eRSSHub\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e🙍🏻‍♂️ Contacts\u003c/strong\u003e: Contacts.app\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e🌐 Browser\u003c/strong\u003e: \u003ca href=\"https://www.microsoft.com/en-us/edge\"\u003eMicrosoft Edge\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e💬 Chat\u003c/strong\u003e: \u003ca href=\"https://telegram.org/\"\u003eTelegram\u003c/a\u003e, \u003ca href=\"https://www.wechat.com/\"\u003eWeChat\u003c/a\u003e(Not recommended, unless absolutely necessary.), iMeesage.app?\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e🔖 Bookmarks\u003c/strong\u003e: \u003ca href=\"https://www.microsoft.com/en-us/edge\"\u003eMicrosoft Edge\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e📑 Read It Later\u003c/strong\u003e: \u003ca href=\"https://omnivore.app/\"\u003eOmnivore\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e📜 Word Processing\u003c/strong\u003e: \u003ca href=\"https://www.larksuite.com/en_us\"\u003eLark\u003c/a\u003e Docs, \u003ca href=\"https://www.office.com/\"\u003eMicrosoft 365\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e📈 Spreadsheets\u003c/strong\u003e: N/A\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e📊 Presentations\u003c/strong\u003e: \u003ca href=\"https://www.microsoft.com/en-us/microsoft-365/powerpoint\"\u003eMicrosoft PowerPoint\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e🛒 Shopping Lists\u003c/strong\u003e: N/A\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e🍴 Meal Planning\u003c/strong\u003e: N/A\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e💰 Budgeting and Personal Finance\u003c/strong\u003e: \u003ca href=\"https://apps.apple.com/us/app/icost-%E8%AE%B0%E8%B4%A6-%E5%BF%AB%E9%80%9F%E7%AE%80%E6%B4%81%E5%A5%BD%E7%94%A8%E7%9A%84%E7%90%86%E8%B4%A2%E5%8A%A9%E6%89%8B/id1484262528\"\u003eiCost\u003c/a\u003e, \u003ca href=\"https://apps.apple.com/sg/app/%E8%AE%A2%E9%98%85%E9%80%9A/id1577082754?l=zh\"\u003eSubscriptions\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e📰 News\u003c/strong\u003e: Channels on \u003ca href=\"https://telegram.org/\"\u003eTelegram\u003c/a\u003e, RSS, Web\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e🎵 Music\u003c/strong\u003e: \u003ca href=\"https://music.163.com/\"\u003eNeteaseMusic\u003c/a\u003e, Music.app\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e🎤 Podcasts\u003c/strong\u003e: N/A\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e🔐 Password Management\u003c/strong\u003e: \u003ca href=\"https://www.icloud.com/\"\u003eiCloud\u003c/a\u003e Keychain\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e🧑‍💻 Code Editor\u003c/strong\u003e: \u003ca href=\"https://www.jetbrains.com/all/\"\u003eJetBrains Series\u003c/a\u003e, \u003ca href=\"https://code.visualstudio.com/\"\u003eVS Code\u003c/a\u003e, \u003ca href=\"https://www.vim.org/\"\u003eVim\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e🪄 Launcher\u003c/strong\u003e: \u003ca href=\"https://www.hapigo.com/\"\u003eHapiGo\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e😘 Blog Platform\u003c/strong\u003e: \u003ca href=\"https://gohugo.io/\"\u003eHugo\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e","title":"My App Defaults - 2023 Fall"},{"content":"TL;DR 我在 2023.11.07 凌晨被 GitHub 封禁了账号,GitHub 账号被 suspended 后会在 GitHub 上完全除名(只有自建创建的组织不会消失)。\n被封禁后我首先通过 Google 查找了相关的文章。\n根据博主 @phith0n 的指引首先通过 API:https://api.github.com/users/[username]/starred 备份了自己 star 过的项目,同时通过 Can\u0026rsquo;t sign-in form 来在无法登陆的情况下发起 GitHub Support 工单来询问/请求解封/询问原因等,一般在两天内收到了回复。最终账号顺利恢复。\n我此次被封禁的原因是由于管理的组织内部有成员被盗号,在组织内创建了违法仓库,因此管理员和被盗号的成员都被封禁了,但后续都被解除了封禁。同时也有可能因为创建违反 DMCA 条款 的仓库、fork 违反 DMCA 条款的仓库、贩卖学生/教师教育包等原因被封禁。\n背景 大约在 2023.11.07 凌晨 00:30 左右,在 GitHub 上看到了一个不错的项目想要 Star,被提示没有登陆。当时我还在想:“怎么这次 session 过期的这么快?” 就当我边疑惑边重新登录后,突然收到了下图的提示我的账号「Account suspended」:\n确认无法登录后,查看邮箱没有任何相关通知。同时我查看了其他内容是否还存在,最后综合表现如下:\n没有任何邮件/信息通知被封禁及更加具体的封禁原因,只告诉违反了 ToS 个人页面(https://github.com/zzsqwq)无法访问,访问显示 404 提的相关 Issue 全部被删除(隐藏),无法找到 个人创建的所有项目,访问全部 404,也无法拉取 自己参与的项目,被除名 自己加入的组织,被除名 自己创建的组织,访问 404 简单说就是跟这个账号从来没存在过一样,除了仍可以登陆,但是显示 suspended。接下来开始尝试找办法恢复。\n恢复经过 试图查找封禁原因 首先看提示上显示违反了 Github Terms of Service,快速的看了一眼 ToS 没发现我有什么明显违规的地方。\n通过搜索引擎搜索 「Github 账号 suspended」相关信息,找到了两个比较强相关的帖子:\n分享下我 GitHub 被封的经历 GitHub 无预警突然封号 其中第一个是因为 fork 了违反 DMCA 的仓库而被封禁,第二个看起来是因为购买了违规的教师包而被封禁。\n首先我是使用正规身份申请的学生教育包,第二个博主的情况可以排除。关于第一个,我仔细想了一下我过去几天的行为:由于过去几天大量 Clash 相关仓库被删除和停止维护,我 fork 了五个与 Clash 有关的仓库,但是理论上 Clash 相关的仓库是不存在违反 DMCA 这一说的,因此第一个博主的情况也可以被排除。\n同时第一个博主提到,我们可以通过 API:https://api.github.com/users/[username]/starred 来找到之前 star 过的仓库,我试了一下确实,遂备份了一份 json 文件。同时查看了关于关注和被关注相关的 API:https://api.github.com/users/[username]/followers 和 https://api.github.com/users/[username]/following,均为空,看来只能找到 star 过的仓库。\n但是有一个比较神奇的点是:第一个博主提到:「但是我创建的 Group 还是好的,没有受影响。」。但是在我账号上,我唯一创建的组织 nwpusr-vision-team 访问时也显示 404,和这个博主的情况不符,但暂时不明是什么原因。\n联系 GitHub 寻求帮助 于是经过一系列查找,我在 GitHub 上使用新的邮箱注册了一个新的账号(旧的邮箱无法注册新账号),并通过 Github Support 界面发起了一个工单说明我的情况。当时是大概凌晨一点多提交的工单,2023.11.07 下午五点多收到了回复,告知我必须使用原邮箱来联系 Github Support 支持才可以处理我的原账号,可以通过 Can\u0026rsquo;t sign-in form 来在无法登录的情况下提交相关工单(但是似乎直接给 Github 发邮件也可以成功创建工单,不确定)。\n同时在这一天的下午,我也得知了有另外两位认识的同学也跟我一模一样在没有任何通知的情况下被封禁,具体的表现也和我一样。而我们之间的联系就是我们同属于一个组织:nwpusr-vision-team 。至此我推断出了一个大致的原因 —— 我创建的这个 Github 组织出了问题,导致我们三个都受到了牵连,但是具体的什么原因还未知,因为这个组织从我创建后几乎就没用过,里面也只有一个 README 一样的仓库,实在是想不明白有什么封禁的理由。\n一直等到第三天即 2023.11.09 的早上9点多,我收到了一封关于密码被重置的邮件,于是我查看了我的 GitHub个人主页 发现已经不再是 404 了。于是我按照提示重置了密码后,顺利的登录了 Github,同时也收到了 GitHub Support 的回复,全文如下:\nHello Zhan,\nThanks for contacting GitHub Support on the email address associated with your zzsqwq account.\nWe recently detected suspicious activity on your account and applied restrictions out of an abundance of caution while we investigated what took place.\nTo secure your account, we have forced a password reset. If you haven’t already, please reset your password.\nI’ve sent you a separate email just now with a link to complete this process. Please note that the link will expire in 24 hours. Alternatively, visit the following to request a password reset token:\nhttps://github.com/password_reset\nTo protect your account from unauthorized access, please choose a strong and unique password for your account. We have a help article with some recommendations here:\nhttps://docs.github.com/authentication/keeping-your-account-and-data-secure/creating-a-strong-password\nAs an added precaution, we also recommend reviewing your security log and reverting any changes you don’t recognize.\nFor more information, read Reviewing your security log in the GitHub Docs.\nAdditionally, we also recommend double checking your stars and removing any that weren’t added by you:\nhttps://github.com/stars\nI hope this clears things up. If you have any further questions, please let us know.\nKind regards, Pip, GitHub Support\n大意就是 GitHub 最近在我的帐户上检测到可疑活动,并在调查发生的事情的同时出于谨慎考虑对我的账号施加了限制。现在已经把我的账号解封了,但是需要重置密码后才可以继续使用。\n后续处理 登录账号后,我发现组织 nwpusr-vision-team 仍存在限制,提示如下:\n由于被对外隐藏了,因此我自己可以访问这个组织,但是如果不登录账号查看这个组织仍是 404 的。\n通过对组织进行查看,发现组织内多了一个新的仓库,并且是违规仓库,是 fork 了一个 仓库 并更新了 README 更新成违规信息。\n这下我大概推测出了封号原因:首先下图是我们目前仓库成员图,红框内的是这次被封禁的人,从上到下依次是被盗号且创建违法仓库的同学、另一位管理员同学和我。应该由于那位同学被盗号并且在组织内创建了违法仓库,但是身为管理员的我们两个人在有管理权的情况下没有及时将仓库删除,因此 GitHub 认为我们三个人都可能账号存在风险,因此一起被禁了。随后进一步的调查发现这三个账号都已经没什么异常,因此就直接解除了封禁。\n随后我将组织内的违法仓库删除并反馈给 Github Support 后,组织状态也恢复了正常。\n随后我又就被封号原因这个问题,和 Github Support 人员展开了一些沟通,但是他们只是一直在说「GitHub 在我的帐户上检测到可疑活动,并在调查发生的事情的同时出于谨慎考虑对我的账号施加了限制,由于这个过程是他们检测工具自动进行的,恕他们无法告知更准确的原因」,最后仍是无法得知我推断的是否正确,但是应该除此之外没什么其他的原因了,由于我 GitHub 开启了 2FA 同时没泄露任何 token,理论上不会被有被异地登陆的可能。\nOur security team has recently been investigating suspicious activity and account hijacking, and we were concerned that your account may have been affected. Out of an abundance of caution, restrictions were placed on your account as part of our attempts to combat this campaign.\nWe use a number of detection methods to find abuse on GitHub, but I’m afraid I’m not at liberty to discuss our internal tooling.\n后记 整件事情看下来其实 GitHub 的处理有点离谱,仅仅是检测到账号可能存在异常活动,就在没有任何通知且不告知详细缘由的情况下封禁了账号,同时无法访问任何仓库/Issue,目前来看恢复账号也需要个至少两天,可能会耽误很多事情。\n我也就这件事情进行了反馈:\nLastly, I believe the way GitHub officially handled this situation was quite unreasonable. Our accounts were banned without any email notification, making it impossible to access repos, followers, following, stars, issues (all showing 404), and without stating a specific reason. For instance, as mentioned in the previous reply: \u0026ldquo;We recently detected suspicious activity on your account and applied restrictions out of an abundance of caution while we investigated what took place.\u0026rdquo; I think if you were to conduct an investigation, you could consider first imposing restrictions on the account (such as only allowing the repository to be pulled without any write operations on the account/repository) and notify us by email: \u0026ldquo;We have detected unusual activity and have restricted your account for safety reasons.\u0026rdquo; This would seem more reasonable and wouldn\u0026rsquo;t leave us confused. Please seriously consider the workflow for the future; this will make everyone love GitHub more. Thank you!\n他们的一些回复如下(分多封邮件进行交流,不同邮件间使用分割线分割):\nThanks for your reply and your feedback, I appreciate you taking the time to share it with me and I will make sure to share it with the relevant team.\nWe restricted your account as we had reasons to believe it may have been compromised in the aforementioned campaign. However, in your specific case, further review suggests that your personal account was unlikely to have been affected. I do apologize for the inconvenience, but hope you understand our need to prioritize account security.\nI understand that having your account restricted unexpectedly can be a frustrating experience, and I appreciate your feedback on receiving notification. I have shared your feedback internally.\n希望 GitHub 后续可以改进这个流程。\nPs:这次导致封号的违规仓库居然还是 fork 的 RoboRTS ,就连这个都跟 RM 有关,有点离谱。\n","permalink":"https://blog.zzsqwq.cn/posts/github-suspended-for-no-reason/","summary":"\u003ch2 id=\"tldr\"\u003eTL;DR\u003c/h2\u003e\n\u003cp\u003e我在 2023.11.07 凌晨被 GitHub 封禁了账号,GitHub 账号被 suspended 后会在 GitHub 上完全除名(只有自建创建的组织不会消失)。\u003c/p\u003e\n\u003cp\u003e被封禁后我首先通过 Google 查找了相关的文章。\u003c/p\u003e\n\u003cp\u003e根据博主 \u003ca href=\"https://github.com/phith0n\"\u003e@phith0n\u003c/a\u003e 的指引首先通过 API:\u003ccode\u003ehttps://api.github.com/users/[username]/starred\u003c/code\u003e 备份了自己 star 过的项目,同时通过 \u003ca href=\"https://support.github.com/contact/cannot_sign_in\"\u003eCan\u0026rsquo;t sign-in form\u003c/a\u003e 来在无法登陆的情况下发起 GitHub Support 工单来询问/请求解封/询问原因等,一般在两天内收到了回复。最终账号顺利恢复。\u003c/p\u003e\n\u003cp\u003e我此次被封禁的原因是由于管理的组织内部有成员被盗号,在组织内创建了违法仓库,因此管理员和被盗号的成员都被封禁了,但后续都被解除了封禁。同时也有可能因为创建违反 \u003ca href=\"https://en.wikipedia.org/wiki/Digital_Millennium_Copyright_Act\"\u003eDMCA 条款\u003c/a\u003e 的仓库、fork 违反 DMCA 条款的仓库、贩卖学生/教师教育包等原因被封禁。\u003c/p\u003e\n\u003ch2 id=\"背景\"\u003e背景\u003c/h2\u003e\n\u003cp\u003e大约在 2023.11.07 凌晨 00:30 左右,在 GitHub 上看到了一个不错的项目想要 Star,被提示没有登陆。当时我还在想:“怎么这次 session 过期的这么快?” 就当我边疑惑边重新登录后,突然收到了下图的提示\u003ca href=\"https://github.com/zzsqwq\"\u003e我的账号\u003c/a\u003e「Account suspended」:\u003c/p\u003e\n\u003cdiv align=\"center\"\u003e\u003cimg src=\"/images/github-suspended-for-no-reason/account-suspended-hint.jpg\" style=\"zoom:50%;\" /\u003e\u003c/div\u003e\n\u003cp\u003e确认无法登录后,查看邮箱没有任何相关通知。同时我查看了其他内容是否还存在,最后综合表现如下:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e没有任何邮件/信息通知被封禁及更加具体的封禁原因,只告诉违反了 ToS\u003c/li\u003e\n\u003cli\u003e个人页面(https://github.com/zzsqwq)无法访问,访问显示 404\u003c/li\u003e\n\u003cli\u003e提的相关 Issue 全部被删除(隐藏),无法找到\u003c/li\u003e\n\u003cli\u003e个人创建的所有项目,访问全部 404,也无法拉取\u003c/li\u003e\n\u003cli\u003e自己参与的项目,被除名\u003c/li\u003e\n\u003cli\u003e自己加入的组织,被除名\u003c/li\u003e\n\u003cli\u003e\u003cdel\u003e\u003ca href=\"https://github.com/nwpusr-vision-team\"\u003e自己创建的组织\u003c/a\u003e,访问 404\u003c/del\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e简单说就是跟这个账号从来没存在过一样,除了仍可以登陆,但是显示 suspended。接下来开始尝试找办法恢复。\u003c/p\u003e\n\u003ch2 id=\"恢复经过\"\u003e恢复经过\u003c/h2\u003e\n\u003ch3 id=\"试图查找封禁原因\"\u003e试图查找封禁原因\u003c/h3\u003e\n\u003cp\u003e首先看提示上显示违反了 \u003ca href=\"https://docs.github.com/en/site-policy/github-terms/github-terms-of-service\"\u003eGithub Terms of Service\u003c/a\u003e,快速的看了一眼 ToS 没发现我有什么明显违规的地方。\u003c/p\u003e","title":"记一次 GitHub 账号突然被 suspended 的经历"},{"content":"TL;DR 本文旨在结合一系列事实总结拼多多过去的一系列恶心行为,包括不限于\n虚假宣传 砍一刀套路多 拉人助力 铺天盖地的广告 利用漏洞 希望大家抵制拼多多这种无良平台,非必要不使用拼多多。\n前言 最近看了很多拼多多令人反感的操作以及看了很多拼多多的软广,如 拼多多,让谁不爽,看到这么一个无良平台逐渐壮大实在是令人恼火,因此我觉得有必要写一篇文章来总结一下拼多多各种恶心人的操作来让大家了解这个无良平台,来看看他到底为什么让人不爽,并呼吁大家可以联合抵制这个平台。\n本文会尽量客观理性,陈述已发生的事实而不是自己的观点,同时因为我不是商家,也不是拼多多的员工,本文只是作为用户角度评判。除了对用户方面的恶心行为,还有对员工及商家的压榨,这个后面有时间再写。欢迎大家补充、批评、指正。\n一、虚假宣传 首先需要提到的就是拼多多的虚假宣传,主要是广告,相信大家都看到过,例如「为什么这些 Switch 游戏机只买 9.9 元都没人买,全部砸了算了」这种开头的,或者「你有 iPhone 13 吗,没有就打开拼多多抢一台」。铺天盖地的,无论是你看视频、还是刷QQ空间,还是刷朋友圈,总是能碰到这种广告,无非就是诱惑你点击下载拼多多,但是打开后却发现广告中说的点击就送、无门槛拿根本都是无稽之谈,要不就是限量两个,邀请最多的人才能领。下面是这类视频的合集,大家可能看到的时候都觉得尬和乐,但是却很少有人认识到这是虚假宣传,违规行为。\n根据百度百科对于虚假宣传的定义:\n虚假宣传是指在商业活动中经营者利用广告或其他方法对商品或者服务做出与实际内容不相符的虚假信息,导致客户或消费者误解的行为。\n这拼多多应该确实是符合的吧?虽然很多只是下载了 App 但是没有产生消费行为,但也可以归入其中。\n二、砍一刀套路多 套路多是指,经过第一步的虚假宣传,让你下载了 App,你以为可以很轻松的拿到免单的商品,但实际他会给你放一堆的限制,就像十年前的页游,一堆过场动画,什么「你是砍价第一名」、「还差 0.01 即可砍成功」,但你一旦继续深入,你就会发现这是个无底洞,0.01 后面是 0.001,0.001 后面是 0.0001,0.0001 后面怕你看数字太小生气,他就会让你集几万个金币或者一些其他的东西,十万个金币兑换 0.001,这样无限循环,想砍成实在难如登天。\n拼多多曾公开表示1:\n近日,“拼多多砍价,但始终差0.9%”话题受到广泛关注,去年3月,上海律师刘宇航参加了拼多多的“砍价免费拿”活动后,经多人砍价还是0.9%,在质疑数据有问题后,刘以使用虚假数据隐瞒规则已构成欺诈为由,向法院递交了起诉材料。在刘宇航随后释出的文件中得知,拼多多称是“因页面显示百分比位数有限,所以他们把一个至少小数点后有6位数以上的百分比,省略显示为0.9%,砍价页面显示的0.9%不是0.9%,而是0.9996427%。”\n当然这里也有砍成功的,不过是分价位的,你砍 100 元的红包,可能拉个七八个人就成功,如果都是新用户可能会更少,如果是砍 Switch、手机这种大件,需要砍的次数则就更多。当然砍 100 元的红包砍的多了,积累的价钱上去了,他也不会让你持续的薅,难度也是累加的。一个典型的案例可以看 超级小桀 之前的视频,如下:\n上面这个视频简单概括一下就是,小桀在直播间突发奇想带水友一起砍一部 IQOO 手机,前期很长的过场动画都在提示你,马上可以直接拿到,进度已经到达 0.00%,但是还是需要收集 10 多个金币,邀请两三个人即可,后来小桀把二维码分享出来,非常多的水友扫码砍,后来导致二维码提示被封禁,小桀又把链接分享给了群里的水友,当时在线的水友不完全统计 6-7W,至少有上千人参与,但最终也没有让那 10 多个金币归零,打电话给客服询问,客服给出理由如下:\n每个人砍都是概率砍成功,可能 100 人砍有 50 个人、80 个人砍成功,不是 100% 成功。 像这么多人砍价,系统检测到会封禁。 那我就有点疑问了,你这个东西本来就需要邀请很多人砍价才能成功,但是你人一多又要封禁,那么不邀请这么多人砍价,那么怎么成功呢?真的是「解释权归拼多多所有」。\n据小桀自己回应,直到3月17号下午2点40分左右下播,也没有砍成功,但是突然在4点40分左右莫名其妙的成功了,赠送了一张无门槛购物券可以下单此手机,随后客服回应:砍价不成功不属实,已经发放「特制」优惠券。这一通操作,实在是闻所未闻,谁也能看出来是事态发展到不可预料的地步搞了个东西出来封口的。\n实在是太像诈骗、传销了,即使这样广泛的虚假宣传,到现在也没有被整治,也还是随处可见。\n附小桀对这件事情的声明:\n三、拉人助力 拼多多最特色的行为,应该就是这个拉人助力,可能算是拉人助力的始祖了,如今算是各个软件的标配了,美团、饿了么、携程旅行、智行中也都随处可见。好处显而易见,可以提高自己活动的参与率、提高 App 的下载率、提高品牌知名度、提高用户粘性。\n具体的规则就是加速某件任务进程,免单某一件物品、领取某个红包、浇灌某个植物,你都需要「拉人助力」。顾名思义就是要分享这个链接或者二维码给他人,让他来点击助力。\n这会迫使身边的亲戚、朋友、家人都会向你发送链接助力,如果大家都用拼多多,那还好,你助力我我助力你,皆大欢喜。而如果你不用拼多多,甚至可能因为拼多多垃圾广告多,App 臃肿、漠视用户隐私等问题反感厌恶拼多多,可能会想要拒绝对方,但是直接拒绝大家两方都不好看,可能会说个客气话:「抱歉,我没下拼多多」。你可能以为可以通过这句话逃过一劫,而你没想到,拼多多会区分新用户和老用户,新用户助力的多,老用户助力的少,长时间不用的人助力也会要比那些常用者多一些。对方听到这个更开心了,因为你可以帮他加快更多的进度。这时候你可能只能不情愿的下载助力,或者和对方直说,那可能就会让两边都闹的不愉快,对方可能觉得:「只是个简单的助力而已,有什么好计较的?下载以后删掉不就好了。」,而你可能不这么认为,就会让原来稳固的关系出现裂隙,让这个社会的人际关系变得更加的脆弱,让人与人之间的交心程度变得越来越低。\n甚至更别说那种在路边突然拦住你让你帮忙助力的人,虽然我没遇到过,但是听很多人说遇到过,想想就令人恶心。\n四、铺天盖地的广告 不知从什么时候开始,拼多多的广告就到处都是了,远多于其他产品及平台的广告。\n广告分不同的类型以及投放方式:\n对于秒杀、拉人头类的广告,多出现在各种订阅号、QQ空间、小程序、小游戏广告中,内容就是上面提到的虚假宣传,例如什么「现在点击下方链接下载拼多多,即可立即 9.9 元秒杀 Switch 游戏机」。 对于百亿补贴类型的广告,多出现在 Bilibili 以及微信公众号(可能还有抖音等位置,因为我不使用,故不得而知),每次看各种UP主视频的,就会突然说起来买什么东西太贵了或者什么东西太贵了,就开始推荐拼多多的百亿补贴。除此以外,还会几乎每周固定的一次的集体刷屏,超多UP主一起在动态发,超多公众号一起发,标题都是如「苹果又跌破历史新低」这种。 这个可能是合法的,只是这种过量的宣发我认为很令人不适,容易引起反感。\n五、利用漏洞 认可白帽黑客价值、走进安全社区,打造安全团队,借助黑客视角提升自身安全能力,这已经成为了行业最佳安全实践之一。\n但是,也有少数地下或隐蔽的公司通过招募黑客,用他们掌握的黑客技术寻找并利用漏洞,为自身牟取非法利益。\n2022 年,竟有巨头公司打破底线,将白帽黑客作为武器,指向了用户。\n2023年2月28日,DarkNavy深蓝 发布了一篇名为 「DarkNavy深蓝洞察」2022年度十大漏洞与利用:最“不可赦”漏洞利用 的文章,文章指出有一个互联网厂商利用了安卓手机中的高危漏洞,在其看似合法的 App 背后,达到了:\n隐蔽安装,提升装机量 伪造提升 DAU/MAU 用户无法卸载 攻击竞争对手 App 窃取用户隐私数据 逃避隐私合规监管 等各种涉嫌违规违法目的,但并未点名该 App 是谁。\n此文一出,持续发酵,各种线索均指向了一个 App —— 拼多多。\n随着研究的深入,基本已经实锤拼多多,包括不限于各种行内安全大佬的分析2,谷歌在 Google Play 下架拼多多,并提示他为恶意软件,最终在2023年3月27号,卡巴斯基实验室的安全研究人员证实拼多多 App 包含恶意代码3。在对恶意代码的首批公开报告之一中,卡巴斯基阐述了该应用程序如何提升自身权限以破坏用户隐私和数据安全。它测试了通过中国本地应用商店分发的应用版本 —— 包含来自华为、腾讯和小米的应用市场。\n同时更令人恶心的是,「目前没有证据表明 Google Play Store 和苹果 App Store 的版本含有恶意代码,通过 Google 和苹果官方商店下载的拼多多应用是安全的。但通过第三方市场下载的 Android 用户则没有那么幸运了,鉴于拼多多有数亿用户,受影响的用户数量可能是非常惊人」,也就是说拼多多这还是定向打击、定向投毒,是看咱们国人好欺负?大家可能对于这种事情向来是不关心,能用就行可能就是大多数人奉行的宗旨,管他对我做了什么,管他有没有什么违法的事情,一味的这样只会助长拼多多这种恶心平台与 App 的气焰。\n目前拼多多已经替换了利用漏洞 App 以及解散了漏洞挖掘与利用相关的团队,不过也有消息称仍有部份人留任继续挖掘。\n被谷歌下架半个月后,拼多多平台内的恶意功能逐渐浮出水面。根据公开资料显示,近日匿名拼多多员工称,公司在 2020 年组建了一支由大约 100 名工程师和产品经理组成的团队,致力于挖掘 Android 手机漏洞,开发漏洞利用方法,将其转化为利润。\n此外,消息源称,拼多多应用的恶意功能最初只针对农村和小城镇的用户,避开北京上海之类大都市的用户,此举旨在降低被暴露的风险。通过收集用户活动的大量数据,拼多多能全面了解用户习惯、兴趣和偏好,改进其机器学习模型,提供更具有个性化的推送通知和广告,吸引用户打开应用并下单。在被曝光之后该团队于三月初被解散。\n同时,截止目前为止,网信办也没有公布任何对拼多多不法行为的追责。一个人要转头多少次,还假装视而不见。315晚会上也没有拼多多,都是些不痛不痒的事情,加起来也没拼多多恶心。法律没有惩治拼多多,反而拼多多自己在用着这些法律武器来追责那些对他「抹黑」的人,明明事实都已经摆在台面上了,还是可以嘴硬,就好像只要自己一味的否定自己做过的事情,就真的可以当作事情没发生过,谎话说多了自己都信了。\n昨日,OSCHINA 微信公众号此前报道的相关文章《某国产电商 APP 利用 Android 漏洞细节曝光:内嵌提权代码、动态下发 Dex》收到了来自拼多多主体公司的投诉,投诉类型是 “内容侵犯名誉 / 商誉 / 隐私 / 肖像”。然而那篇文章从头到尾都没有指名道姓地说是哪家公司、哪款 APP。3\n结语 可能有人会说,拼多多就那么一无是处,一点优点都没有吗?\n要说优点,还是有的,例如百亿补贴、小物件免邮、新鲜水果便宜、签到打卡浇水领各种东西、支持仅退款,相对利好消费者、用户下沉做得好,利好农村的人们。但这不是本文讨论的范围,我只是总结他的恶行,你也可以去多了解拼多多的好处,用不用还是需要自己权衡。\n即使如此,但是我仍想说,他做了好事不代表你要忘记了他的恶,如果不用实际行动去抵制它,一味的迁就它,那这样它只会觉得大家好欺负,继续肆无忌惮的做恶心的事情。希望看到文章的大家都可以在使用拼多多前想想,我是不是必须要用它才行,如果不是,那么就应该用其他平台,而不是——拼多多。\nhttps://finance.sina.com.cn/zt_d/pddhykj/\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nhttps://github.com/davinci01010/pinduoduo_backdoor_x\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nhttps://zhuanlan.zhihu.com/p/617661783\u0026#160;\u0026#x21a9;\u0026#xfe0e;\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","permalink":"https://blog.zzsqwq.cn/posts/why-should-boycott-pdd/","summary":"\u003ch2 id=\"tldr\"\u003eTL;DR\u003c/h2\u003e\n\u003cp\u003e本文旨在结合一系列事实总结拼多多过去的一系列恶心行为,包括不限于\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e虚假宣传\u003c/li\u003e\n\u003cli\u003e砍一刀套路多\u003c/li\u003e\n\u003cli\u003e拉人助力\u003c/li\u003e\n\u003cli\u003e铺天盖地的广告\u003c/li\u003e\n\u003cli\u003e利用漏洞\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e希望大家抵制拼多多这种无良平台,非必要不使用拼多多。\u003c/p\u003e\n\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003e最近看了很多拼多多令人反感的操作以及看了很多拼多多的软广,如 \u003ca href=\"https://www.163.com/dy/article/I3DUPQ140514R9P4.html\"\u003e拼多多,让谁不爽\u003c/a\u003e,看到这么一个无良平台逐渐壮大实在是令人恼火,因此我觉得有必要写一篇文章来总结一下拼多多各种恶心人的操作来让大家了解这个无良平台,来看看他到底为什么让人不爽,并呼吁大家可以联合抵制这个平台。\u003c/p\u003e\n\u003cp\u003e本文会尽量客观理性,陈述已发生的事实而不是自己的观点,同时因为我不是商家,也不是拼多多的员工,本文只是作为用户角度评判。除了对用户方面的恶心行为,还有对员工及商家的压榨,这个后面有时间再写。欢迎大家补充、批评、指正。\u003c/p\u003e\n\u003ch2 id=\"一虚假宣传\"\u003e一、虚假宣传\u003c/h2\u003e\n\u003cp\u003e首先需要提到的就是拼多多的虚假宣传,主要是广告,相信大家都看到过,例如「为什么这些 Switch 游戏机只买 9.9 元都没人买,全部砸了算了」这种开头的,或者「你有 iPhone 13 吗,没有就打开拼多多抢一台」。铺天盖地的,无论是你看视频、还是刷QQ空间,还是刷朋友圈,总是能碰到这种广告,无非就是诱惑你点击下载拼多多,但是打开后却发现广告中说的点击就送、无门槛拿根本都是无稽之谈,要不就是限量两个,邀请最多的人才能领。下面是这类视频的合集,大家可能看到的时候都觉得尬和乐,但是却很少有人认识到这是虚假宣传,违规行为。\u003c/p\u003e\n\u003ciframe width=\"100%\" height=\"500\" src=\"//player.bilibili.com/player.html?aid=334427777\u0026bvid=BV1uw411R78b\u0026cid=378349675\u0026page=1\u0026autoplay=0\" scrolling=\"no\" border=\"0\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\"\u003e \u003c/iframe\u003e\n\u003cp\u003e根据百度百科对于虚假宣传的定义:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e虚假宣传是指在商业活动中经营者利用广告或其他方法对商品或者服务做出与实际内容不相符的\u003ca href=\"https://baike.baidu.com/item/%E8%99%9A%E5%81%87%E4%BF%A1%E6%81%AF/2398005?fromModule=lemma_inlink\"\u003e虚假信息\u003c/a\u003e,导致客户或消费者误解的行为。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e这拼多多应该确实是符合的吧?虽然很多只是下载了 App 但是没有产生消费行为,但也可以归入其中。\u003c/p\u003e\n\u003ch2 id=\"二砍一刀套路多\"\u003e二、砍一刀套路多\u003c/h2\u003e\n\u003cp\u003e套路多是指,经过第一步的虚假宣传,让你下载了 App,你以为可以很轻松的拿到免单的商品,但实际他会给你放一堆的限制,就像十年前的页游,一堆过场动画,什么「你是砍价第一名」、「还差 0.01 即可砍成功」,但你一旦继续深入,你就会发现这是个无底洞,0.01 后面是 0.001,0.001 后面是 0.0001,0.0001 后面怕你看数字太小生气,他就会让你集几万个金币或者一些其他的东西,十万个金币兑换 0.001,这样无限循环,想砍成实在难如登天。\u003c/p\u003e\n\u003cp\u003e拼多多曾公开表示\u003csup id=\"fnref:1\"\u003e\u003ca href=\"#fn:1\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e1\u003c/a\u003e\u003c/sup\u003e:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e近日,“拼多多砍价,但始终差0.9%”话题受到广泛关注,去年3月,上海律师刘宇航参加了拼多多的“砍价免费拿”活动后,经多人砍价还是0.9%,在质疑数据有问题后,刘以使用虚假数据隐瞒规则已构成欺诈为由,向法院递交了起诉材料。在刘宇航随后释出的文件中得知,拼多多称是“因页面显示百分比位数有限,所以他们把一个至少小数点后有6位数以上的百分比,省略显示为0.9%,砍价页面显示的0.9%不是0.9%,而是0.9996427%。”\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e当然这里也有砍成功的,不过是分价位的,你砍 100 元的红包,可能拉个七八个人就成功,如果都是新用户可能会更少,如果是砍 Switch、手机这种大件,需要砍的次数则就更多。当然砍 100 元的红包砍的多了,积累的价钱上去了,他也不会让你持续的薅,难度也是累加的。一个典型的案例可以看 \u003ca href=\"https://space.bilibili.com/29440965\"\u003e超级小桀\u003c/a\u003e 之前的视频,如下:\u003c/p\u003e\n\u003ciframe width=\"100%\" height=\"500\" src=\"//player.bilibili.com/player.html?aid=679818997\u0026bvid=BV12S4y1u7rw\u0026cid=553141060\u0026page=1\u0026autoplay=0\" scrolling=\"no\" border=\"0\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\"\u003e \u003c/iframe\u003e\n\u003cp\u003e上面这个视频简单概括一下就是,小桀在直播间突发奇想带水友一起砍一部 IQOO 手机,前期很长的过场动画都在提示你,马上可以直接拿到,进度已经到达 0.00%,但是还是需要收集 10 多个金币,邀请两三个人即可,后来小桀把二维码分享出来,非常多的水友扫码砍,后来导致二维码提示被封禁,小桀又把链接分享给了群里的水友,当时在线的水友不完全统计 6-7W,至少有上千人参与,但最终也没有让那 10 多个金币归零,打电话给客服询问,客服给出理由如下:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003col\u003e\n\u003cli\u003e每个人砍都是概率砍成功,可能 100 人砍有 50 个人、80 个人砍成功,不是 100% 成功。\u003c/li\u003e\n\u003cli\u003e像这么多人砍价,系统检测到会封禁。\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e那我就有点疑问了,你这个东西本来就需要邀请很多人砍价才能成功,但是你人一多又要封禁,那么不邀请这么多人砍价,那么怎么成功呢?真的是「解释权归拼多多所有」。\u003c/p\u003e\n\u003cp\u003e据小桀自己回应,直到3月17号下午2点40分左右下播,也没有砍成功,但是突然在4点40分左右莫名其妙的成功了,赠送了一张无门槛购物券可以下单此手机,随后客服回应:砍价不成功不属实,已经发放「特制」优惠券。这一通操作,实在是闻所未闻,谁也能看出来是事态发展到不可预料的地步搞了个东西出来封口的。\u003c/p\u003e\n\u003cp\u003e实在是太像诈骗、传销了,即使这样广泛的虚假宣传,到现在也没有被整治,也还是随处可见。\u003c/p\u003e\n\u003cp\u003e附小桀对这件事情的声明:\u003c/p\u003e\n\u003cdiv align=\"center\"\u003e\u003cimg src=\"/images/why-should-boycott-pdd/2.jpeg\" style=\"zoom:50%;\" /\u003e\u003c/div\u003e\n\u003ch2 id=\"三拉人助力\"\u003e三、拉人助力\u003c/h2\u003e\n\u003cp\u003e拼多多最特色的行为,应该就是这个拉人助力,可能算是拉人助力的始祖了,如今算是各个软件的标配了,美团、饿了么、携程旅行、智行中也都随处可见。好处显而易见,可以提高自己活动的参与率、提高 App 的下载率、提高品牌知名度、提高用户粘性。\u003c/p\u003e","title":"为什么应该抵制拼多多?"},{"content":"前言 最近想要使用自己采集与标注的数据集来训练与部署一下地平线微调过的 FCOS 网络,在询问和查看文档后发现如果想基于官方微调的模型训练,需要使用提供 HAT(Horizon Algorithm Toolkit,海图) 来进行,具体的文档可以查看:Horizon Algorithm Toolkit 文档,这是在线的版本,版本可能会比较旧,想看最新版的可以查看离线的版本,位置在 OE(Open Explorer,天工开物) 包的 doc 目录下,如下图:\n想要方便的查看离线文档可以通过 Python 来实现,在 doc 目录下执行:\npython3 -m http.server 3000 这样就可以在本地的 0.0.0.0:3000 地址开启一个 http server,随后可以在本地浏览器使用 localhost:3000 或者其他电脑浏览器使用 {ip}:3000 来访问文档。\n但是查看 文档 过后会发现,文档其实也没有那么的全面,讲的比较简单,尝试了一下中间坑还挺多的,社区里面关于这方面的帖子也不多12,因此想记录下我尝试的全流程,也可以作为对上面教程文档的补充。\n下面主要分为三部分:\n训练的环境配置。\n如何基于官方的 COCO 数据集训练?这里就是指基于 mscoco 发布的包含 80 类的数据集。\n如何基于自己的数据集进行训练?这里就是指自己建立的,自定义类别的,可能只有四五类,没有 80 类的数据集。\n下方涉及到的一些代码、脚本和模型等,可以在 Github 仓库 中找到。\n训练的环境配置 我自己环境配置如下:\nOS: Ubuntu 20.04\nDocker: 20.10.23\nNvidia Docker: 2.11.0-1\nGPU: RTX3090\nNVIDIA Driver Version: 515.65.01\nCUDA Version: 11.7\nOE Version: v2.4.2( gcc-9.3.0 For XJ3 )\n因为我的开发是基于 Ubuntu 进行,训练是 GPU 进行的,所以这里只提及关于 Ubuntu + GPU 训练的环境配置,Windows 情况下,或者只有 CPU 的情况,我也没尝试过。\n首先需要安装 Docker 以及 NVIDIA Docker,前者安装参考:Docker 安装文档,后者安装参考:NVIDIA Docker 安装文档。\n参考官方 X3 芯片文档编写启动脚本 run_docker.sh 如下:\n#!/bin/bash export version=v2.4.2 export ai_toolchain_package_path=/data/sunrise/horizon_oe_v2.4.2 export dataset_path=/data/datasets docker run -dt --runtime=nvidia -e NVIDIA_DRIVER_CAPABILITIES=compute,utility \\ -e NVIDIA_VISIBLE_DEVICES=all --shm-size=\u0026#34;15g\u0026#34; \\ --restart=always --network=host \\ -v \u0026#34;$ai_toolchain_package_path\u0026#34;:/open_explorer \\ -v \u0026#34;$dataset_path\u0026#34;:/data \\ openexplorer/ai_toolchain_centos_7_xj3:\u0026#34;${version}\u0026#34; 其中参数解释如下:\nversion 代表 Docker 镜像版本,可选版本参考:资料下载专区\nai_toolchain_package_path 代表 OE 开发包的路径,指定 OE 包中 ai_toolchain 的路径也可以,但是我建议把整个 OE 包都挂进去得了,没啥差别。\ndataset_path 代表训练需要的数据集路径,这里可以新建一个空的文件夹然后挂载进去,也可以把你所有的数据集都准备好,然后放到一个文件夹,然后挂进去,需要训练哪个后面指定哪个即可,我们这里方便起见可以选择前者(官方说如果这里指定为空可能会出问题,但是我测试发现挂载空文件夹不会有问题)。\ndocker run 部分就是启动一个 Docker 容器,其中比较重要的参数: -dt 可以让容器使用 Daemon 的方式启动一个交互式终端,可以保证容器一直存活不会 detach 后就被杀死,方便我们多次操作;--restart=always 可以在每次开机时自动重启容器,可以视自己的情况去掉或者改成 --restart=unless-stopped 等;--network=host 指定与宿主机器使用同一个网络,方便我们查看文档或者后面的网络结构。\n设置后即可打开终端,使用 bash run_docker.sh 启动容器,并使用 docker exec -it {container_id} bash 来连接容器进行操作,其中 container_id 可以通过 docker ps 或者上述脚本的返回值查看。\n进入后可使用 nvidia-smi 验证一下,出现下方的信息即代表成功:\n环境配置到此结束,终于可以开始训练和部署网络了。\n训练 COCO 数据集并进行部署 数据准备 下方的操作均在上方启动的容器中进行,首先需要先 docker exec 进入容器中。\n其中准备 COCO 数据集部分参考 官方文档部分,首先进入 /data 目录,然后新建一个文件夹 mscoco,下载数据集、解压即可。\n# 进入之前挂载的 /data 目录 cd /data # 创建一个目录来存储数据集 mkdir mscoco # 下载 train2017.zip,即训练数据集 wget -c http://images.cocodataset.org/zips/train2017.zip # 下载 val2017.zip,即验证数据集 wget -c http://images.cocodataset.org/zips/val2017.zip # 下载 annotations_trainval2017.zip 即对应标签 wget -c http://images.cocodataset.org/annotations/annotations_trainval2017.zip # 解压 unzip train2017.zip unzip val2017.zip unzip annotations_trainval2017.zip 随后进入 /open_explorer/horizon_model_train_samples 目录,如果这里你和我之前一样是挂载的整个 OE 包,那这个路径可能会长一些,例如我这里是 /open_explorer/ddk/samples/ai_toolchain/horizon_model_train_samples。\n将数据集打包成 lmdb 格式,注意下方的 /data/mscoco 路径是我们之前存放数据集的路径:\n# 转换训练集 python3 tools/datasets/mscoco_packer.py --src-data-dir /data/mscoco/ --target-data-dir /data/mscoco --split-name train --pack-type lmdb # 转换验证集 python3 tools/datasets/mscoco_packer.py --src-data-dir /data/mscoco/ --target-data-dir /data/mscoco --split-name val --pack-type lmdb 运行完即打包成功,/data/mscoco 目录下会多出来 train_lmdb 和 val_lmdb 两个文件夹,即打包之后的训练数据集和验证数据集,也是网络最终读取的数据集。\n修改配置文件 地平线提供的 HAT 工具链是一个类 mmdetion 的东西,模型定义、训练、验证都流程都定义在一个 config.py 文件中,官方提供的所有配置文件可以在 configs 目录下找到,FCOS 对应的就是 configs/detection/fcos 目录下的配置文件,方便起见,我们这里只考虑 fcos_efficientnetb0_mscoco.py ,关于配置的进一步讲解,可见官方文档:config 文件介绍。\n在修改之前,最好先备份一下原件,可以作为对比,也方便回溯:\ncp fcos_efficientnetb0_mscoco.py fcos_efficientnetb0_mscoco_back.py 要改的点有三个:\ndevice_ids:这里代表的是你使用的 GPU 序号,如果只有一个 GPU 就只保留 [0],两个就是 [0, 1],以此类推。 所有跟 ./tmp_data 有关的位置,这里相关的都是指定的数据集位置,官方举例是将数据集都放在了同 configs 同目录的 tmp_data 目录,但是我们放在了 /data 目录,因此要将所有的 ./tmp_data 都改成 /data float_trainer:这个参数是个 Dict,里面包含了一个 num_epochs ,代表我们训练多少轮,这里默认是 300,可以根据自己需求调整,例如 5、10、100 等。 开始训练! 训练很简单,一行命令即可:\n# 进入 horizon_model_train_samples 目录 cd /open_explorer/ddk/samples/ai_toolchain/horizon_model_train_samples # 开始训练 python3 tools/train.py --step float --config configs/detection/fcos/fcos_efficientnetb0_mscoco.py 如果不出意外,已经开始训练了,正常如下图所示:\n顺便说一下,这里推荐配合 tmux 工具来训练,可以让 session 在后台运行,防止意外中断,顺附一个 tmux 教程:Tmux 使用教程。\n模型转换 训练的时间比较长,主要取决于数据集的大小,如果是 mscoco 这种大型数据集,一个 epoch 就要好久才行。\n这里我训练了十轮就结束了,随后进入 tmp_models 目录,找到我们训练好的权重文件,如下图,这里的存放位置主要和配置文件中的 task_name 与 ckpt_dir 有关,可以按需修改:\n接下来就是将权重文件导出成 ONNX 模型:\npython3 tools/export_onnx.py --config configs/detection/fcos/fcos_efficientnetb0_mscoco.py --ckpt tmp_models/fcos_efficientnetb0_mscoco/float-checkpoint-best.pth.tar --onnx-name fcos.onnx 如上命令,将训练得到的 best 权重文件(float-checkpoint-best.pth.tar)导出成了 fcos.onnx 模型文件,这里也可以选择其他的权重,指定对模型路径即可。\n接下来是使用地平线的工具链对 ONNX 模型进行量化,以便我们后面上板推理:\n第一步,先移动一下得到的权重文件,方便后面的查找:\n# 进入 horizon_model_train_samples 目录 cd /open_explorer/ddk/samples/ai_toolchain/horizon_model_train_samples # 建立文件夹 mkdir -p ../horizon_model_convert_sample/08_customs # 移动 onnx 模型过去 cp ./fcos.onnx ../horizon_model_convert_sample/08_customs 接下来就是那套标准的转换流程,可以参考官方教程:6.3 快速体验,还有大佬的指南:一文带你轻松走出模型部署新手村。\n主要是涉及模型地址和数据集地址的时候需要改成我们对应的即可,其他的都默认就行,接下来给出我的几个脚本及精简后的转换配置文件:\n01_check.sh # 01_check.sh set -e -v cd $(dirname $0) model_type=\u0026#34;onnx\u0026#34; onnx_model=\u0026#34;../../../08_customs/fcos.onnx\u0026#34; march=\u0026#34;bernoulli2\u0026#34; hb_mapper checker --model-type ${model_type} \\ --model ${onnx_model} \\ --march ${march} 02_preprocess.sh # 02_preprocess.sh set -e -v cd $(dirname $0) || exit python3 ../../../data_preprocess.py \\ --src_dir /data/mscoco/train2017 \\ --dst_dir ./calibration_data_yuv_f32 \\ --cal_img_num 50 \\ --pic_ext .yuv \\ --read_mode opencv \\ --saved_data_type float32 fcos_efficientnetb0_config.yaml # fcos_efficientnetb0_config.yaml model_parameters: onnx_model: \u0026#39;../../../08_customs/fcos.onnx\u0026#39; march: \u0026#34;bernoulli2\u0026#34; layer_out_dump: False working_dir: \u0026#39;fcos_test\u0026#39; output_model_file_prefix: \u0026#39;fcos_test\u0026#39; input_parameters: input_name: \u0026#34;\u0026#34; input_type_rt: \u0026#39;nv12\u0026#39; input_type_train: \u0026#39;yuv444\u0026#39; input_layout_train: \u0026#39;NCHW\u0026#39; input_shape: \u0026#39;\u0026#39; norm_type: \u0026#39;data_mean_and_scale\u0026#39; mean_value: 128.0 scale_value: 0.0078125 calibration_parameters: cal_data_dir: \u0026#39;./calibration_data_yuv_f32_qyun\u0026#39; cal_data_type: \u0026#39;float32\u0026#39; calibration_type: \u0026#39;max\u0026#39; max_percentile: 0.99996 compiler_parameters: compile_mode: \u0026#39;latency\u0026#39; debug: False optimize_level: \u0026#39;O3\u0026#39; 这里理论上只需要执行完 03_build.sh 脚本转换即结束,不出意外在同目录下会生成 fcos_test 目录,已经在其中可找到 fcos.bin ,这即是我们后续上板推理需要的模型文件。\n模型推理 这里 Python 推理我参考了 X3M 板子上 /app/ai_inference/02_usb_camera_sample/usb_camera_fcos.py 目录下的推理脚本,直接上代码:\n#!/usr/bin/env python3 import os from hobot_dnn import pyeasy_dnn as dnn from hobot_vio import libsrcampy as srcampy import numpy as np import cv2 import colorsys from time import time # detection model class names def get_classes(): return np.array([\u0026#34;person\u0026#34;, \u0026#34;bicycle\u0026#34;, \u0026#34;car\u0026#34;, \u0026#34;motorcycle\u0026#34;, \u0026#34;airplane\u0026#34;, \u0026#34;bus\u0026#34;, \u0026#34;train\u0026#34;, \u0026#34;truck\u0026#34;, \u0026#34;boat\u0026#34;, \u0026#34;traffic light\u0026#34;, \u0026#34;fire hydrant\u0026#34;, \u0026#34;stop sign\u0026#34;, \u0026#34;parking meter\u0026#34;, \u0026#34;bench\u0026#34;, \u0026#34;bird\u0026#34;, \u0026#34;cat\u0026#34;, \u0026#34;dog\u0026#34;, \u0026#34;horse\u0026#34;, \u0026#34;sheep\u0026#34;, \u0026#34;cow\u0026#34;, \u0026#34;elephant\u0026#34;, \u0026#34;bear\u0026#34;, \u0026#34;zebra\u0026#34;, \u0026#34;giraffe\u0026#34;, \u0026#34;backpack\u0026#34;, \u0026#34;umbrella\u0026#34;, \u0026#34;handbag\u0026#34;, \u0026#34;tie\u0026#34;, \u0026#34;suitcase\u0026#34;, \u0026#34;frisbee\u0026#34;, \u0026#34;skis\u0026#34;, \u0026#34;snowboard\u0026#34;, \u0026#34;sports ball\u0026#34;, \u0026#34;kite\u0026#34;, \u0026#34;baseball bat\u0026#34;, \u0026#34;baseball glove\u0026#34;, \u0026#34;skateboard\u0026#34;, \u0026#34;surfboard\u0026#34;, \u0026#34;tennis racket\u0026#34;, \u0026#34;bottle\u0026#34;, \u0026#34;wine glass\u0026#34;, \u0026#34;cup\u0026#34;, \u0026#34;fork\u0026#34;, \u0026#34;knife\u0026#34;, \u0026#34;spoon\u0026#34;, \u0026#34;bowl\u0026#34;, \u0026#34;banana\u0026#34;, \u0026#34;apple\u0026#34;, \u0026#34;sandwich\u0026#34;, \u0026#34;orange\u0026#34;, \u0026#34;broccoli\u0026#34;, \u0026#34;carrot\u0026#34;, \u0026#34;hot dog\u0026#34;, \u0026#34;pizza\u0026#34;, \u0026#34;donut\u0026#34;, \u0026#34;cake\u0026#34;, \u0026#34;chair\u0026#34;, \u0026#34;couch\u0026#34;, \u0026#34;potted plant\u0026#34;, \u0026#34;bed\u0026#34;, \u0026#34;dining table\u0026#34;, \u0026#34;toilet\u0026#34;, \u0026#34;tv\u0026#34;, \u0026#34;laptop\u0026#34;, \u0026#34;mouse\u0026#34;, \u0026#34;remote\u0026#34;, \u0026#34;keyboard\u0026#34;, \u0026#34;cell phone\u0026#34;, \u0026#34;microwave\u0026#34;, \u0026#34;oven\u0026#34;, \u0026#34;toaster\u0026#34;, \u0026#34;sink\u0026#34;, \u0026#34;refrigerator\u0026#34;, \u0026#34;book\u0026#34;, \u0026#34;clock\u0026#34;, \u0026#34;vase\u0026#34;, \u0026#34;scissors\u0026#34;, \u0026#34;teddy bear\u0026#34;, \u0026#34;hair drier\u0026#34;, \u0026#34;toothbrush\u0026#34;]) # return np.array([\u0026#34;tissue\u0026#34;, \u0026#34;sock\u0026#34;, \u0026#34;shoe\u0026#34;, \u0026#34;cable\u0026#34;, \u0026#34;bin\u0026#34;]) # bgr格式图片转换成 NV12格式 def bgr2nv12_opencv(image): height, width = image.shape[0], image.shape[1] area = height * width yuv420p = cv2.cvtColor( image, cv2.COLOR_BGR2YUV_I420).reshape((area * 3 // 2,)) y = yuv420p[:area] uv_planar = yuv420p[area:].reshape((2, area // 4)) uv_packed = uv_planar.transpose((1, 0)).reshape((area // 2,)) nv12 = np.zeros_like(yuv420p) nv12[:height * width] = y nv12[height * width:] = uv_packed return nv12 def postprocess(model_output, model_hw_shape, origin_image=None, origin_img_shape=None, score_threshold=0.5, nms_threshold=0.6, dump_image=False): input_height = model_hw_shape[0] input_width = model_hw_shape[1] if origin_image is not None: origin_image_shape = origin_image.shape[0:2] else: origin_image_shape = origin_img_shape prediction_bbox = decode(outputs=model_output, score_threshold=score_threshold, origin_shape=origin_image_shape, input_size=512) prediction_bbox = nms(prediction_bbox, iou_threshold=nms_threshold) prediction_bbox = np.array(prediction_bbox) topk = min(prediction_bbox.shape[0], 1000) if topk != 0: idx = np.argpartition(prediction_bbox[..., 4], -topk)[-topk:] prediction_bbox = prediction_bbox[idx] if dump_image and origin_image is not None: draw_bboxs(origin_image, prediction_bbox) return prediction_bbox def draw_bboxs(image, bboxes, gt_classes_index=None, classes=get_classes()): \u0026#34;\u0026#34;\u0026#34;draw the bboxes in the original image \u0026#34;\u0026#34;\u0026#34; num_classes = len(classes) image_h, image_w, channel = image.shape hsv_tuples = [(1.0 * x / num_classes, 1., 1.) for x in range(num_classes)] colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples)) colors = list( map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)), colors)) fontScale = 0.5 bbox_thick = int(0.6 * (image_h + image_w) / 600) for i, bbox in enumerate(bboxes): coor = np.array(bbox[:4], dtype=np.int32) if gt_classes_index == None: class_index = int(bbox[5]) score = bbox[4] else: class_index = gt_classes_index[i] score = 1 bbox_color = colors[class_index] c1, c2 = (coor[0], coor[1]), (coor[2], coor[3]) cv2.rectangle(image, c1, c2, bbox_color, bbox_thick) classes_name = classes[class_index] bbox_mess = \u0026#39;%s: %.2f\u0026#39; % (classes_name, score) t_size = cv2.getTextSize(bbox_mess, 0, fontScale, thickness=bbox_thick // 2)[0] cv2.rectangle(image, c1, (c1[0] + t_size[0], c1[1] - t_size[1] - 3), bbox_color, -1) cv2.putText(image, bbox_mess, (c1[0], c1[1] - 2), cv2.FONT_HERSHEY_SIMPLEX, fontScale, (0, 0, 0), bbox_thick // 2, lineType=cv2.LINE_AA) print(\u0026#34;{} is in the picture with confidence:{:.4f}\u0026#34;.format( classes_name, score)) # cv2.imwrite(\u0026#34;demo.jpg\u0026#34;, image) return image def decode(outputs, score_threshold, origin_shape, input_size=512): def _distance2bbox(points, distance): x1 = points[..., 0] - distance[..., 0] y1 = points[..., 1] - distance[..., 1] x2 = points[..., 0] + distance[..., 2] y2 = points[..., 1] + distance[..., 3] return np.stack([x1, y1, x2, y2], -1) def _scores(cls, ce): cls = 1 / (1 + np.exp(-cls)) ce = 1 / (1 + np.exp(-ce)) return np.sqrt(ce * cls) def _bbox(bbox, stride, origin_shape, input_size): # l t r b | h, w = t, r h, w = bbox.shape[1:3] yv, xv = np.meshgrid(np.arange(h), np.arange(w)) xy = (np.stack((yv, xv), 2) + 0.5) * stride bbox = _distance2bbox(xy, bbox) # opencv read, shape[1] is w, shape[0] is h scale_w = origin_shape[1] / input_size scale_h = origin_shape[0] / input_size scale = max(origin_shape[0], origin_shape[1]) / input_size # origin img is pad resized # bbox = bbox * scale # origin img is resized bbox = bbox * [scale_w, scale_h, scale_w, scale_h] return bbox bboxes = list() strides = [8, 16, 32, 64, 128] # 各个 stride 找符合的模型 for i in range(len(strides)): cls = outputs[i].buffer bbox = outputs[i + 5].buffer ce = outputs[i + 10].buffer scores = _scores(cls, ce) classes = np.argmax(scores, axis=-1) classes = np.reshape(classes, [-1, 1]) max_score = np.max(scores, axis=-1) max_score = np.reshape(max_score, [-1, 1]) bbox = _bbox(bbox, strides[i], origin_shape, input_size) bbox = np.reshape(bbox, [-1, 4]) pred_bbox = np.concatenate([bbox, max_score, classes], axis=1) index = pred_bbox[..., 4] \u0026gt; score_threshold pred_bbox = pred_bbox[index] bboxes.append(pred_bbox) return np.concatenate(bboxes) def nms(bboxes, iou_threshold, sigma=0.3, method=\u0026#39;nms\u0026#39;): def bboxes_iou(boxes1, boxes2): boxes1 = np.array(boxes1) boxes2 = np.array(boxes2) boxes1_area = (boxes1[..., 2] - boxes1[..., 0]) * \\ (boxes1[..., 3] - boxes1[..., 1]) boxes2_area = (boxes2[..., 2] - boxes2[..., 0]) * \\ (boxes2[..., 3] - boxes2[..., 1]) left_up = np.maximum(boxes1[..., :2], boxes2[..., :2]) right_down = np.minimum(boxes1[..., 2:], boxes2[..., 2:]) inter_section = np.maximum(right_down - left_up, 0.0) inter_area = inter_section[..., 0] * inter_section[..., 1] union_area = boxes1_area + boxes2_area - inter_area ious = np.maximum(1.0 * inter_area / union_area, np.finfo(np.float32).eps) return ious classes_in_img = list(set(bboxes[:, 5])) best_bboxes = [] for cls in classes_in_img: cls_mask = (bboxes[:, 5] == cls) cls_bboxes = bboxes[cls_mask] while len(cls_bboxes) \u0026gt; 0: max_ind = np.argmax(cls_bboxes[:, 4]) best_bbox = cls_bboxes[max_ind] best_bboxes.append(best_bbox) cls_bboxes = np.concatenate( [cls_bboxes[:max_ind], cls_bboxes[max_ind + 1:]]) iou = bboxes_iou(best_bbox[np.newaxis, :4], cls_bboxes[:, :4]) weight = np.ones((len(iou),), dtype=np.float32) assert method in [\u0026#39;nms\u0026#39;, \u0026#39;soft-nms\u0026#39;] if method == \u0026#39;nms\u0026#39;: iou_mask = iou \u0026gt; iou_threshold weight[iou_mask] = 0.0 if method == \u0026#39;soft-nms\u0026#39;: weight = np.exp(-(1.0 * iou ** 2 / sigma)) cls_bboxes[:, 4] = cls_bboxes[:, 4] * weight score_mask = cls_bboxes[:, 4] \u0026gt; 0. cls_bboxes = cls_bboxes[score_mask] return best_bboxes def print_properties(pro): print(\u0026#34;tensor type:\u0026#34;, pro.tensor_type) print(\u0026#34;data type:\u0026#34;, pro.dtype) print(\u0026#34;layout:\u0026#34;, pro.layout) print(\u0026#34;shape:\u0026#34;, pro.shape) if __name__ == \u0026#39;__main__\u0026#39;: models = dnn.load(\u0026#39;./models/fcos.bin\u0026#39;) # 打印输入 tensor 的属性 print_properties(models[0].inputs[0].properties) # 打印输出 tensor 的属性 print(len(models[0].outputs)) for output in models[0].outputs: print_properties(output.properties) frame = cv2.imread(\u0026#34;./kite.jpg\u0026#34;) if frame is None: print(\u0026#34;Image is not exist.\u0026#34;) height, width = frame.shape[:2] print(\u0026#34;height: \u0026#34;, height, \u0026#34;width: \u0026#34;, width) # 把图片缩放到模型的输入尺寸 # 获取算法模型的输入tensor 的尺寸 h, w = models[0].inputs[0].properties.shape[2], models[0].inputs[0].properties.shape[3] des_dim = (w, h) resized_data = cv2.resize(frame, des_dim, interpolation=cv2.INTER_AREA) nv12_data = bgr2nv12_opencv(resized_data) # Forward outputs = models[0].forward(nv12_data) # Do post process input_shape = (h, w) prediction_bbox = postprocess( outputs, input_shape, origin_img_shape=(height, width)) if frame.shape[0] != height or frame.shape[1] != width: frame = cv2.resize(frame, (width, height), interpolation=cv2.INTER_AREA) # Draw bboxs box_bgr = draw_bboxs(frame, prediction_bbox) cv2.imwrite(\u0026#34;kite_with_bbox.jpg\u0026#34;, box_bgr) 其实流程还是蛮简单的,就是 加载模型 -\u0026gt; 读取照片 -\u0026gt; Resize 照片到模型推理尺寸 -\u0026gt; 转化为 NV12 输入格式 -\u0026gt; 拿到输出 outputs -\u0026gt; 对数据集进行后处理得到 bbox 与 classes 等数据 -\u0026gt; Resize 照片到原尺寸绘制框 -\u0026gt; 写照片。\n大家拿脚本推理的时候,只需要改变 models 和读取照片的位置即可,这里我采用的示例图片是在模型转化后测试推理使用的,可以在 OE 包的如下路径找到 ai_toolchain/horizon_model_convert_sample/01_common/test_data/det_images/kite.jpg。\n接下来就是运行脚本进行推理,得到的推理结果如下:\n为什么结果是这样的,起初我认为是我推理脚本写错了,因此我直接将权重替换为官方的权重,得到的结果如下:\n很显然,这次的推理是正确的,也就是说明,脚本是没问题,只是权重出了问题,因此我又仔细检查了训练和模型转换的各个步骤,但都没有发现问题。同时,使用官方提供的 mapper 目录下原 onnx 进行转换后,也是没有问题的。那么问题在哪里呢?\n查找问题 因为通过上面的排除可以确定,转化这个过程是没什么问题的,那也就只能是模型定义和训练中出现的问题,但是上面的效果又明显不是训练过拟合或者欠拟合导致的,因为框的位置是大致对的,就是太多了,而且太小了,因此我怀疑是模型上出了问题,可能是有节点不一致。\n确定了方向,接下来我首先对官方原 onnx 模型文件和我自己训练得到的 onnx 模型使用了 01_checker.sh 脚本来进行检查,因为他会输出模型中的各个层,对比结果如下:\n左侧是我自己训练得到的模型,右侧是我官方提供的模型,可以发现,两者存在差异,其实就是官方模型相比于训练得到的模型会多了几个 Mul 节点。\n接下来进一步使用 netron 工具对两个模型进行对比,有区别的对比结果如下图所示:\n左侧为自己训练的模型,右侧为官方模型。可以看到只有 bbox 信息(对于 FCOS 为(l, t, r, b)四元组)在输出时两个模型有区别,多了一步 Relu 激活函数和 Mul 节点,其他的经过对比没有区别。\n同时观察发现,这里 Mul 节点对应的数值,其实是对应的 stride(这个大家可以使用 netron 去看看)\n知道了问题所在,解决方案就有了,只需要改动下面这一行即可:\n# Decode 函数中获取数据的部分 # 各个 stride 找符合的模型 for i in range(len(strides)): cls = outputs[i].buffer bbox = outputs[i + 5].buffer * strides[i] # modified ce = outputs[i + 10].buffer scores = _scores(cls, ce) 很好理解,对 bbox 获得的原始数据乘了 strides[i],这里我没有处理 Relu 函数,因为即使是负数,OpenCV 绘制也是不会出问题的。\n再次运行获得的推理图如下,这次正常了:\n至此,训练 mscoco 数据集模型并进行部署就算结束了,接下来我们看看如何来处理自己得到的数据集。\n训练自采集数据集 对于自采集数据集,最可能是数据处理打包、以及配置文件的配置这两部分存在问题,剩下的模型检查、校准数据准备、模型转化、以及上板推理部分可以说是根本没区别,所以就着重讲一下数据准备和配置部分。\n数据准备 首先数据准备要准备 COCO JSON 格式,他是跟通用 JSON 格式也是有区别的,这个就不详述了。\n然后方便起见,可以复用官方的 mscoco_packer.py 脚本,我们把数据集也存为 train2017、val2017 和 annotations 三个文件夹,例如存在放在 /data/selfcoco 目录下,类似于下面:\n[root@Z690-P selfcoco]# tree . ├── annotations │ ├── instances_train2017.json # 训练集的 label │ └── instances_val2017.json # 验证集的 label ├── train2017 # 训练集照片 └── val2017 # 验证集照片 这时候如果我们按照之前的操作,直接使用 mscoco_packer.py 脚本进行打包,会报错如下:\n报错大意就是访问了字典一个不存在的键,直接查看报错的位置,位于 /usr/local/lib/python3.6/site-packages/hat/data/datasets/mscoco.py,查看后发现 COCO_LABLE_TO_LABLE 这个字典是一个类别的映射,因为 mscoco 数据集类别包含 80 类,按顺序来是 [0, 80),但是 mscoco 数据集原数据集类别序号范围为 [1, 90],但是其中只有 80 个类别序号,所以需要做一个 [1, 90] -\u0026gt; [0, 80) 的类别映射,但是如果我们自制的数据集没有这个类别映射的需求,就不需要映射,把涉及到这个 Dict 的两行都去掉即可。\nBtw:🤣 这里的 COCO_LABLE_TO_LABLE 是不是拼错了,要拼 LABEL 的?\n# 229 行 # anno[0, 4] = COCO_LABLE_TO_LABLE[tar[\u0026#34;category_id\u0026#34;]] anno[0, 4] = tar[\u0026#34;category_id\u0026#34;] # 327 行 # np.array([[COCO_LABLE_TO_LABLE[tar[\u0026#34;category_id\u0026#34;]]]]) np.array([[tar[\u0026#34;category_id\u0026#34;]]]) 随后打包即可\n# 转换训练集 python3 tools/datasets/mscoco_packer.py --src-data-dir /data/selfcoco --target-data-dir /data/selfcoco --split-name train --pack-type lmdb # 转换验证集 python3 tools/datasets/mscoco_packer.py --src-data-dir /data/selfcoco --target-data-dir /data/selfcoco --split-name val --pack-type lmdb 配置文件修改 配置文件除了之前提到的三处需要修改,配置文件中还需要修改与类别相关的参数,大概有如下几个:\nnum_classes:这里就是一个全局变量类别数,例如我这里有五类 [0, 5),那改为 5 即可。 model:model 参数中还有很多涉及到 80 的,经过我查看源码后,发现这些 80 的位置都应该改成 num_classes 参数才可以,例如 model 中的 loss_cls 参数,其中的 num_classes 参数值 80+1 就需要改为 num_classes + 1 ,post_process 参数中的 num_classes 参数值 80 也应该改为 num_classes,这里我认为是官方的疏忽,应该是忘记改了。 修改完后就可以按之前的方法进行训练了:\n# 进入 horizon_model_train_samples 目录 cd /open_explorer/ddk/samples/ai_toolchain/horizon_model_train_samples # 开始训练 python3 tools/train.py --step float --config configs/detection/fcos/fcos_efficientnetb0_mscoco.py 校准数据准备 这里预处理的数据也应该选择我们训练的数据子集,需要修改一下,剩下的都不需要变:\n# 02_preprocess.sh set -e -v cd $(dirname $0) || exit python3 ../../../data_preprocess.py \\ --src_dir /data/selfcoco/train2017 \\ # 重要 --dst_dir ./calibration_data_yuv_f32 \\ --cal_img_num 50 \\ --pic_ext .yuv \\ --read_mode opencv \\ --saved_data_type float32 推理代码修改 这里需要修改 get_classes 函数返回的类别名,改成自己对应的类别 List.\n推理得到结果如下:\n可以看到,识别可以正常的工作(因为我选的训练数据集有点捞,所以过拟合比较严重,就选了一张凑合能看的图,大家见谅)。\n后言 这样我们就完成了 FCOS 网络的训练和部署,但是基于 Python 的推理可能有点慢,大家可以参考 ai_benchmark 等部分进行 C++ 推理,主要关键就是 PostProcess 后处理部分,不过之前 开发者直播KE——AI板端部署实践 张老师已经讲过一部分 API,如果大家有兴趣,我后面也可以给大家出个帖子讲讲 🤗。\n探索的这几天,给我的感觉是,地平线做了很多,写了很多有用的工具、包,但是文档还是不够完善,而且文档有些混乱,版本比较混乱,位置比较混乱、等等,容易找不到、无从下手等等。\n例如对于 FCOS 这部分的文档就很欠缺,对于 FCOS 训练配置的各个选项的详解,大家看到时候可能会有很多问题,例如:\n如何使用 CPU 进行训练而不是 GPU? 如何基于已有的模型进行迁移训练?中断训练后可以再继续进行吗? 可以 freeze 一部分参数进行 fine-tuning 吗? 训练时有数据增强吗?如果不需要可以去掉吗? 不过现在也是在慢慢完善,不断进步,希望可以把这些好用的东西都能让大家快点方便的用起来。\n文中涉及到的一些代码、脚本和模型等,可以在 Github 仓库 中找到。\n文章同步发布在我的博客:https://blog.zzsqwq.cn\n如何用工具链HAT训练fcos自定义数据集\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n在OE包中训练focs模型\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","permalink":"https://blog.zzsqwq.cn/posts/hat-train-fcos/","summary":"\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003e最近想要使用自己采集与标注的数据集来训练与部署一下地平线微调过的 FCOS 网络,在询问和查看文档后发现如果想基于官方微调的模型训练,需要使用提供 HAT(Horizon Algorithm Toolkit,海图) 来进行,具体的文档可以查看:\u003ca href=\"https://developer.horizon.ai/api/v1/fileData/doc/ddk_doc/navigation/ai_toolchain/docs_cn/horizon_algorithm_toolkit/index.html\"\u003eHorizon Algorithm Toolkit 文档\u003c/a\u003e,这是在线的版本,版本可能会比较旧,想看最新版的可以查看离线的版本,位置在 OE(Open Explorer,天工开物) 包的 doc 目录下,如下图:\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/images/hat-train-fcos/doc_position.png\" alt=\"image-20230224155005117\" /\u003e\n\u003c/p\u003e\n\u003cp\u003e想要方便的查看离线文档可以通过 Python 来实现,在 doc 目录下执行:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003epython3\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003em\u003c/span\u003e \u003cspan class=\"n\"\u003ehttp\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eserver\u003c/span\u003e \u003cspan class=\"mi\"\u003e3000\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e这样就可以在本地的 \u003ccode\u003e0.0.0.0:3000\u003c/code\u003e 地址开启一个 http server,随后可以在本地浏览器使用 \u003ccode\u003elocalhost:3000\u003c/code\u003e 或者其他电脑浏览器使用 \u003ccode\u003e{ip}:3000\u003c/code\u003e 来访问文档。\u003c/p\u003e\n\u003cp\u003e但是查看 \u003ca href=\"https://developer.horizon.ai/api/v1/fileData/doc/ddk_doc/navigation/ai_toolchain/docs_cn/horizon_algorithm_toolkit/examples/fcos.html\"\u003e文档\u003c/a\u003e 过后会发现,文档其实也没有那么的全面,讲的比较简单,尝试了一下中间坑还挺多的,社区里面关于这方面的帖子也不多\u003csup id=\"fnref:1\"\u003e\u003ca href=\"#fn:1\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e1\u003c/a\u003e\u003c/sup\u003e\u003csup id=\"fnref:2\"\u003e\u003ca href=\"#fn:2\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e2\u003c/a\u003e\u003c/sup\u003e,因此想记录下我尝试的全流程,也可以作为对上面教程文档的补充。\u003c/p\u003e\n\u003cp\u003e下面主要分为三部分:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e训练的环境配置。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e如何基于官方的 COCO 数据集训练?这里就是指基于 mscoco 发布的包含 80 类的\u003ca href=\"https://cocodataset.org/\"\u003e数据集\u003c/a\u003e。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e如何基于自己的数据集进行训练?这里就是指自己建立的,自定义类别的,可能只有四五类,没有 80 类的数据集。\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e下方涉及到的一些代码、脚本和模型等,可以在 \u003ca href=\"https://github.com/zzsqwq/fcos_tutorial\"\u003eGithub 仓库\u003c/a\u003e 中找到。\u003c/p\u003e\n\u003ch2 id=\"训练的环境配置\"\u003e训练的环境配置\u003c/h2\u003e\n\u003cp\u003e我自己环境配置如下:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eOS: Ubuntu 20.04\u003c/p\u003e\n\u003cp\u003eDocker: 20.10.23\u003c/p\u003e\n\u003cp\u003eNvidia Docker: 2.11.0-1\u003c/p\u003e\n\u003cp\u003eGPU: RTX3090\u003c/p\u003e\n\u003cp\u003eNVIDIA Driver Version: 515.65.01\u003c/p\u003e\n\u003cp\u003eCUDA Version: 11.7\u003c/p\u003e\n\u003cp\u003eOE Version: v2.4.2( gcc-9.3.0 For XJ3 )\u003c/p\u003e","title":"基于地平线 HAT 训练与部署 FCOS 全流程"},{"content":"2022 依旧是被疫情伴随的一年,时间正着看总是要比回看慢很多,现在回头看过往一年似乎一瞬间就过去了。\n今年共发了 11 篇文章,其中还包含了两篇碎碎念,还是没有达到月更,新的一年希望可以。2022 年对我来说变化很大,算是暂时摆脱了学生生活,体验了社畜的感觉,打卡了北上广深中的北和深。\n接下来按月份盘点一些值得纪念的事情吧。\n一月:\n这一月大多是在学校里度过的,封校了很长时间,封校期间报名了送餐志愿者,每天都负责给大家配送三餐,有点累,但是感觉能听到大家感谢的声音以及幸福的笑容还是很值得的,我感觉我一直还挺乐于助人的,帮助别人其实还挺快乐的。值得一提的是,因为之前总喜欢续费超级会员,疫情期间还建了一个宿舍群,送餐期间也兼职在群里传达各种信息,虽然是个吃力不讨好的活,还因为一些过激的言论被挂到知乎说是官僚主义。\n二月:\n二月换了手机(iPhone 13),加入了果粉的队列,并在心中种下了苹果全家桶的种子。还和家人一起去了青岛的海洋馆玩,和从未见过的网友学弟面了基。\n三月:\n三月报名参加了 RMUS 2022 ,同时也在备赛 RMUA 2022 和准备大创的中期检查。搭建了一个新的 RMUA 场地。\n四月:\n移植了一个学术风的 Hexo 主题,搞了一个自己的学术主页,计划用于后面的申请夏令营等。\n五月:\n带队参加了 RMUA 2022,也担任了其中的赛事志愿者。今年的分组不错,可惜还是因为各种原因惨败了,很难受的一个月。回来还被隔离了七天,隔离的时候也无心学习,后面有考试和各种大作业的检查,这段时间是一年中最难受的时候。\n六月:\n六月是考试月,各种考试、各种大作业、各种 DDL,压的人喘不过气来。\n在 6月12日,基地也搬了新的场地,大二上学期刚加入基地的时候,基地也是新搬场地,现在,基地又新搬了场地,我也该退休了。\n七月:\n六月的结束也意味着学期的结束,假期的开始。七月学长邀请我去他公司实习,我欣然答应,于是我们就在学期结束后一起飞到了深圳,开始了社畜生活。在深圳的生活很愉快,也有了自己可以支配的收入,不再依赖于家里面的生活费了,也可以攒些小钱买自己想买的东西,这种感觉很棒。同时这个月还入手了 Airpods 3,空间音频给人的感觉很震撼。\n八月:\n八月继续社畜,做了社畜以后有了比学生生活期间更多的活动,也吃了更多的好吃的,成了KFC、麦当劳、海底捞、肉蟹煲的常客,每天都稳定点两次外卖。这个月还看了《请回答1988》的解说,真的很好看,是令人暖心的剧集。\n九月:\n九月要开学了,但是因为大四上学期已经没什么课了,而且深圳的疫情非常严重,没有返校。本月最重要的是我成了一名铲屎官(猫屎真的好臭😷),已经是人生赢家了,Siri 给他起名为卓卓。\n同时九月也是保研名单公布和保研结束一段时间,再三考虑后决定放弃了保研名额,跟学长一起创业,先在港中文做 RA,后面或许可以去那里读 Ph.D,想出去看看。\n这个月还因为要做 iOS 开发公司给配了 Mac,现在已经拥有 iPhone、iPad、Mac、Airpods,距离 Apple 全家桶只有一步之遥。\n哦对了,这个月还搬了新的住所,因为人逐渐变多了,之前的屋子已经住不下了。九月,真是繁忙的一月。\n十月:\n这个月初入手了 Apple Watch,补齐了个人设备的最后一块拼图算是。iMac 这种没有算进来,因为 iOS、iPadOS、MacOS、WatchOS 四个系统已经集齐了,苹果生态给人的感觉真的很不错。\n有了 Watch 以后,借着新鲜感锻炼了一段时间,但是体重不降反增了,于是动力没了,又回到了肥宅的生活😁。\n同时这个月还和乐乐和雷宝一起去了深圳的欢乐谷游玩,体验了失重的感觉,下次不敢了。\n十一月:平淡的一个月,上班、吃吃吃、玩玩玩。卓卓越来越好看了。\n十二月:\n学长从 HK 带回来了最新版的 Apple TV,苹果生态又添一员。现在的联动已经非常棒了,手机可以直接推流到 Homepod、电视、Mac、耳机等。\n因为疫情放开了,我也体验了一次阳性的感觉,不过只高烧了一天就好了,也没感觉有什么后遗症,同居的六个人已经阳了四个,希望不会短期内再次感染🙏。这个月还和学长一起去了趟北京,不过只住了一天就回来了。\n这个月也抽时间购买了 FirstUI-uniapp 框架,把之前发单小程序的界面重构了一下,算是一步步的把之前的屎山代码给救了回来。因为在公司也担任了 Code Viewer 的角色,越发感觉代码风格对编程很重要,一个好的代码规范能够提升编程的效率,无论是自己还是团队,学编程语言应该必学代码规范。\n总的来说,今年要比去年精彩的多,可能是因为了保研结束了,当了社畜,没有考研的压力,有了很多玩乐的时间,也有了可以自己支配的收入,虽然不是很多,但是生活和娱乐已经够用。\n不过当了社畜,算是脱离了象牙塔进入了社会,也听到了各种各样在学校听不见的声音,引发了蛮多思考🤔。\n同时新的一年也看了更多的书、学到了很多新的知识,Modern C++、Rust、Swift、SwiftUI、Vue3 等等,拓宽了自己知识面。无限进步,无论什么时候都要坚持读书,我感觉读书仍是目前收益非常高的一个选择,即使读一些很久远的书,也能从中获得各种各样的启发,希望新的一年我也可以坚持不懈的读书!\n","permalink":"https://blog.zzsqwq.cn/posts/summary-2022/","summary":"\u003cp\u003e2022 依旧是被疫情伴随的一年,时间正着看总是要比回看慢很多,现在回头看过往一年似乎一瞬间就过去了。\u003c/p\u003e\n\u003cp\u003e今年共发了 11 篇文章,其中还包含了两篇碎碎念,还是没有达到月更,新的一年希望可以。2022 年对我来说变化很大,算是暂时摆脱了学生生活,体验了社畜的感觉,打卡了北上广深中的北和深。\u003c/p\u003e\n\u003cp\u003e接下来按月份盘点一些值得纪念的事情吧。\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003e\u003cstrong\u003e一月\u003c/strong\u003e:\u003c/p\u003e\n\u003cp\u003e这一月大多是在学校里度过的,封校了很长时间,封校期间报名了送餐志愿者,每天都负责给大家配送三餐,有点累,但是感觉能听到大家感谢的声音以及幸福的笑容还是很值得的,我感觉我一直还挺乐于助人的,帮助别人其实还挺快乐的。值得一提的是,因为之前总喜欢续费超级会员,疫情期间还建了一个宿舍群,送餐期间也兼职在群里传达各种信息,虽然是个吃力不讨好的活,还因为一些过激的言论被挂到知乎说是官僚主义。\u003c/p\u003e\n\u003cdiv align=center\u003e\n\u003cimg src=\"/images/summary-2022/1.png\" alt=\"一月疫情回家\" style=\"zoom: 50%;\" /\u003e\n\u003c/div\u003e\n\u003cp\u003e\u003cstrong\u003e二月\u003c/strong\u003e:\u003c/p\u003e\n\u003cp\u003e二月换了手机(iPhone 13),加入了果粉的队列,并在心中种下了苹果全家桶的种子。还和家人一起去了青岛的海洋馆玩,和从未见过的网友学弟面了基。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e三月\u003c/strong\u003e:\u003c/p\u003e\n\u003cp\u003e三月报名参加了 RMUS 2022 ,同时也在备赛 RMUA 2022 和准备大创的中期检查。搭建了一个新的 RMUA 场地。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e四月\u003c/strong\u003e:\u003c/p\u003e\n\u003cp\u003e移植了一个学术风的 Hexo 主题,搞了一个\u003ca href=\"https://zzsqwq.cn\"\u003e自己的学术主页\u003c/a\u003e,计划用于后面的申请夏令营等。\u003c/p\u003e\n\u003cdiv align=center\u003e\n\u003cimg src=\"/images/summary-2022/4.png\" alt=\"学术主页\" style=\"zoom: 50%;\" /\u003e\n\u003c/div\u003e\n\u003cp\u003e\u003cstrong\u003e五月\u003c/strong\u003e:\u003c/p\u003e\n\u003cp\u003e带队参加了 RMUA 2022,也担任了其中的赛事志愿者。今年的分组不错,可惜还是因为各种原因惨败了,很难受的一个月。回来还被隔离了七天,隔离的时候也无心学习,后面有考试和各种大作业的检查,这段时间是一年中最难受的时候。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e六月\u003c/strong\u003e:\u003c/p\u003e\n\u003cp\u003e六月是考试月,各种考试、各种大作业、各种 DDL,压的人喘不过气来。\u003c/p\u003e\n\u003cp\u003e在 6月12日,基地也搬了新的场地,大二上学期刚加入基地的时候,基地也是新搬场地,现在,基地又新搬了场地,我也该退休了。\u003c/p\u003e\n\u003cdiv align=center\u003e\n\u003cimg src=\"/images/summary-2022/6.png\" alt=\"学术主页\" style=\"zoom: 50%;\" /\u003e\n\u003c/div\u003e\n\u003cp\u003e\u003cstrong\u003e七月\u003c/strong\u003e:\u003c/p\u003e\n\u003cp\u003e六月的结束也意味着学期的结束,假期的开始。七月学长邀请我去他公司实习,我欣然答应,于是我们就在学期结束后一起飞到了深圳,开始了社畜生活。在深圳的生活很愉快,也有了自己可以支配的收入,不再依赖于家里面的生活费了,也可以攒些小钱买自己想买的东西,这种感觉很棒。同时这个月还入手了 Airpods 3,空间音频给人的感觉很震撼。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e八月\u003c/strong\u003e:\u003c/p\u003e\n\u003cp\u003e八月继续社畜,做了社畜以后有了比学生生活期间更多的活动,也吃了更多的好吃的,成了KFC、麦当劳、海底捞、肉蟹煲的常客,每天都稳定点两次外卖。这个月还看了《请回答1988》的解说,真的很好看,是令人暖心的剧集。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e九月\u003c/strong\u003e:\u003c/p\u003e\n\u003cp\u003e九月要开学了,但是因为大四上学期已经没什么课了,而且深圳的疫情非常严重,没有返校。本月最重要的是我成了一名铲屎官(猫屎真的好臭😷),已经是人生赢家了,Siri 给他起名为\u003cstrong\u003e卓卓\u003c/strong\u003e。\u003c/p\u003e\n\u003cp\u003e同时九月也是保研名单公布和保研结束一段时间,再三考虑后决定放弃了保研名额,跟学长一起创业,先在港中文做 RA,后面或许可以去那里读 Ph.D,想出去看看。\u003c/p\u003e\n\u003cp\u003e这个月还因为要做 iOS 开发公司给配了 Mac,现在已经拥有 iPhone、iPad、Mac、Airpods,距离 Apple 全家桶只有一步之遥。\u003c/p\u003e\n\u003cp\u003e哦对了,这个月还搬了新的住所,因为人逐渐变多了,之前的屋子已经住不下了。九月,真是繁忙的一月。\u003c/p\u003e\n\u003cdiv align=center\u003e\n\u003cimg src=\"/images/summary-2022/9.png\" alt=\"学术主页\" style=\"zoom: 25%;\" /\u003e\n\u003c/div\u003e\n\u003cp\u003e\u003cstrong\u003e十月\u003c/strong\u003e:\u003c/p\u003e\n\u003cp\u003e这个月初入手了 Apple Watch,补齐了个人设备的最后一块拼图算是。iMac 这种没有算进来,因为 iOS、iPadOS、MacOS、WatchOS 四个系统已经集齐了,苹果生态给人的感觉真的很不错。\u003c/p\u003e","title":"2022 年度总结"},{"content":"前言 最近同居的学长从香港带了个最新版的 Apple TV 回来,但是 Apple TV 在国内用不了,必须要代理才可以,所以考虑到了路由器代理的方案。但是现在家里在用的路由器是 Redmi AX3000,没法刷固件,也不想再买个 R2S 这种软路由了,因此就计划将公司之前用完的 香橙派(OrangePi) 4 LTS 利用一下。它的芯片是 RK3399,用来做路由器绰绰有余,不用可惜了。\n为什么是旁路由? 不熟悉旁路由的同学可以看篇指南:从听说到上手,人人都能看懂的旁路由入门指南\n找了一些常见的固件,貌似只有针对于 OrangePi R1 和 OrangePi R1 Plus 编译的软路由固件,并且讯龙官方也有放出针对这两个板子的 Openwrt 固件1,可以说是就是为软路由而生,价格也比较便宜,200 左右,性能和 R2S 差别不大。\n试了一下在 4 LTS 上跑 R1 和 R1 Plus 的固件2,都无法正常点亮,可能可以自己编译一个对应架构的 OpenWrt,但是有点麻烦,还是没尝试。\n考虑到 4 LTS 上可以使用 Docker,因此可以在上面用 Docker 跑一个 OpenWrt 然后做旁路由,到时候只需要把 Apple TV 或者路由器的网关和 DNS 改一下就可以,因此最终选择使用旁路由方案。\n具体方案 这里直接参考了小苏的教程:https://mlapp.cn/376.html,写的很清晰,而且很好的考虑了没有基础的同学,赞一个!\n里面写的很详细,但是需要注意的是,因为香橙派4 LTS是 ARMv8 架构的,但是直接拉教程里面的默认 latest 镜像是 ARMv7 的,因此需要指定一下镜像的版本,具体的镜像版本可以看 Docker Hub 中的介绍。\ndocker pull registry.cn-shanghai.aliyuncs.com/suling/openwrt:armv8 --- docker run --restart always --name openwrt -d --network macnet --privileged registry.cn-shanghai.aliyuncs.com/suling/openwrt:armv8 /sbin/init 除此以外,根据它的指导来基本就不会有问题,其中如果需要给路由器下所有设备代理就把路由器的网关和 DNS 改为旁路由的 IP,如果是单独给某个设备(例如只给 Apple TV 终端),就可以只给单个设备设置 DNS 和 网关。\nUDP 代理 我们想在 Apple TV 上联机玩狂野飙车8,启动多人对战一直报加入服务器错误,观察了一下发现应该是 UDP 流量没有被代理到,因此开启了 OpenClash 的 TUN 模式,开启以后发现更糟了,直接无法上网。搜了一下发现已经有对应的 Issue,疑似是旁路由和 OpenClash 防火墙设置有冲突,删掉对应的规则即可。\n顺便说一句 Apple TV 真的有点香,这个价位,这个性能。\nhttps://openwrt.org/toh/xunlong/orange_pi_r1_plus\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nhttps://github.com/SuLingGG/OpenWrt-Rpi\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","permalink":"https://blog.zzsqwq.cn/posts/orangepi4-lts-with-openwrt/","summary":"\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003e最近同居的学长从香港带了个最新版的 Apple TV 回来,但是 Apple TV 在国内用不了,必须要代理才可以,所以考虑到了路由器代理的方案。但是现在家里在用的路由器是 Redmi AX3000,没法刷固件,也不想再买个 R2S 这种软路由了,因此就计划将公司之前用完的 \u003ca href=\"http://www.orangepi.cn/html/hardWare/computerAndMicrocontrollers/details/Orange-Pi-4-LTS.html\"\u003e香橙派(OrangePi) 4 LTS\u003c/a\u003e 利用一下。它的芯片是 RK3399,用来做路由器绰绰有余,不用可惜了。\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/images/orangepi4-lts-with-openwrt/orangepi4-lts.jpeg\" alt=\"旁路由成品图\" /\u003e\n\u003c/p\u003e\n\u003ch2 id=\"为什么是旁路由\"\u003e为什么是旁路由?\u003c/h2\u003e\n\u003cp\u003e不熟悉旁路由的同学可以看篇指南:\u003ca href=\"https://sspai.com/post/59708\"\u003e从听说到上手,人人都能看懂的旁路由入门指南\u003c/a\u003e\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003e找了一些常见的固件,貌似只有针对于 OrangePi R1 和 OrangePi R1 Plus 编译的软路由固件,并且讯龙官方也有放出针对这两个板子的 Openwrt 固件\u003csup id=\"fnref:1\"\u003e\u003ca href=\"#fn:1\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e1\u003c/a\u003e\u003c/sup\u003e,可以说是就是为软路由而生,价格也比较便宜,200 左右,性能和 R2S 差别不大。\u003c/p\u003e\n\u003cp\u003e试了一下在 4 LTS 上跑 R1 和 R1 Plus 的固件\u003csup id=\"fnref:2\"\u003e\u003ca href=\"#fn:2\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e2\u003c/a\u003e\u003c/sup\u003e,都无法正常点亮,可能可以自己编译一个对应架构的 OpenWrt,但是有点麻烦,还是没尝试。\u003c/p\u003e\n\u003cp\u003e考虑到 4 LTS 上可以使用 Docker,因此可以在上面用 Docker 跑一个 OpenWrt 然后做旁路由,到时候只需要把 Apple TV 或者路由器的网关和 DNS 改一下就可以,因此最终选择使用旁路由方案。\u003c/p\u003e\n\u003ch2 id=\"具体方案\"\u003e具体方案\u003c/h2\u003e\n\u003cp\u003e这里直接参考了小苏的教程:https://mlapp.cn/376.html,写的很清晰,而且很好的考虑了没有基础的同学,赞一个!\u003c/p\u003e\n\u003cp\u003e里面写的很详细,但是需要注意的是,因为香橙派4 LTS是 ARMv8 架构的,但是直接拉教程里面的默认 latest 镜像是 ARMv7 的,因此需要指定一下镜像的版本,具体的镜像版本可以看 Docker Hub 中的\u003ca href=\"https://hub.docker.com/r/sulinggg/openwrt\"\u003e介绍\u003c/a\u003e。\u003c/p\u003e","title":"使用 OrangePi 4 LTS 做旁路由"},{"content":"前言 本文包含一些在使用 C++ 类时的注意事项,可避免一些常见问题,并能让你在写代码时更加自信。\n因为目前我使用的是 C++ 17,所以仅保证以下内容在 C++ 17 中正确。\n构造函数 对于单个参数的构造函数,推荐添加 explicit 关键字,防止隐式转换错误调用构造函数。 class DemoClass { explicit DemoClass(int test) { this-\u0026gt;test_ = test; } } 显式声明有参构造函数后,编译器不会自动生成无参构造函数,若需要,请添加 DemoClass() = default; class DemoClass { explicit DemoClass(int test) { this-\u0026gt;test_ = test; } DemoClass() = default; } 若子类中没有显式调用父类的构造函数,子类会默认调用父类的无参构造函数,如果父类没有无参构造函数,会报错。 析构函数 基类析构函数应该声明为 virtual,这样可以防止子类无法正确的析构。 由于基类析构函数为 virtual,派生类的析构函数应该显式的 override。 class DemoClass { virtual ~DemoClass() = default; } class ChildClass: public DemoClass { ~ChildClass() override { xxx; } } 成员变量默认值 对于类或局部作用域中未明确指定默认值的成员变量,其值遵循以下规则:\n对于原生类型(primitive types),即 int、float、int*、string* 等,默认值为随机的脏数据。 对于对象(objects),例如自定义类、或 std::string 等,会调用默认(无参)构造函数,若没有默认(无参)构造函数,则报错。 对于引用(reference)类型,例如 std::string\u0026amp;,必须赋初始值或在构造函数中初始化,若为初始化,则报错。 float age; // 脏数据、随机值(无意义),此时访问会出现未定义行为 int *ptr; // 脏数据、随机值(无意义),此时访问会出现未定义行为 string name; // 调用默认构造函数,对于 std::string 来说为空字符串 \u0026#34;\u0026#34; DemoClass demo; // 若 DemoClass 存在无参构造函数,则调用,否则编译错误 string *pname; // 脏数据、随机值(无意义),此时访问会出现未定义行为 string \u0026amp;rname; // 编译错误,必须显式初始化 const string \u0026amp;crname; // 同上,编译错误 成员变量初始化方式 初始化成员变量一般而言有四种方式,一般而言第二种和第四种方式为等价的,不过在下面我们会看到一种例外:\nclass DemoClass { int a = 1; // (1) 通过 a == 1 int a{1}; // (2) 通过 a == 1 int a(1); // (3) 报错,只能用于对对象的初始化 int a = {1}; // (4)通过 a == 1 } 总体而言,推荐使用第二种方式,更加通用、现代、安全。\n只不过在使用存在以 std::initializer_list 为参数做初始化的对象时,推荐使用第三种方式,第二种方式会导致非常贪婪的构造调用,详情可见:Item 7:区别使用()和{}创建对象 - Effective Modern C++\n同时,对于某些对象,例如 std::vector,第二种方式与第三种方式存在区别,此时要根据使用意图区别调用:\nstd::vector vec(10, 20); // vec 包含 10 个元素,值均为 20 std::vector vec{10, 20}; // vec 包含 10, 20 两个元素 此外,在 C++17 之前,在搭配使用 auto 和 {} 时会产生奇怪的行为,同时在这里带 = 和不带 = 的 {} 会出现差别:\nauto a{1}; // C++17 之前 a 为 std::initializer_list\u0026lt;int\u0026gt;,之后为 int auto a = {1}; // a 为 std::initializer_list\u0026lt;int\u0026gt; auto a = 1; // a 为 int auto a{1, 2}; // 报错! auto a = {1, 2}; // a 为 std::initializer_list\u0026lt;int\u0026gt; 更进一步 为什么推荐使用第二种方式?\nC++11 引入了 {} 这种称为统一初始化(uniform initialization)的语法来整合那些混乱且不适于所有情景的初始化语法。\n为什么叫统一初始化?看以下几个例子:\nclass DemoClass{ … private: int x{ 0 }; //没问题,x初始值为0 int y = 0; //也可以 int z(0); //错误! } 这里,z 为一个原生类型,而不是对象,无法使用 () 来对其初始化。\n而 = 也不是总是可用的,不可赋值拷贝构造的对象(例如std::atomic——见Item40)可以使用花括号初始化或者小括号初始化,但是不能使用 = 初始化:\nstd::atomic\u0026lt;int\u0026gt; ai1{ 0 }; //没问题 std::atomic\u0026lt;int\u0026gt; ai2(0); //没问题 std::atomic\u0026lt;int\u0026gt; ai3 = 0; //错误! 因此我们很容易理解为什么 {} 初始化又叫统一初始化,在 C++ 中这三种方式都被指派为初始化表达式(而不是什么函数声明或者拷贝构造),但是只有 {} 任何地方都能被使用。\n参考资料及拓展阅读资料 How do C++ class members get initialized if I don\u0026rsquo;t do it explicitly?\nWhy does auto x{3} deduce an initializer_list?\nmariusbancila.ro\nhttps://cntransgroup.github.io/EffectiveModernCppChinese/3.MovingToModernCpp/item7.html\n","permalink":"https://blog.zzsqwq.cn/posts/cxx-class-skills/","summary":"\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003e本文包含一些在使用 C++ 类时的注意事项,可避免一些常见问题,\u003cstrong\u003e并能让你在写代码时更加自信\u003c/strong\u003e。\u003c/p\u003e\n\u003cp\u003e因为目前我使用的是 C++ 17,所以仅保证以下内容在 C++ 17 中正确。\u003c/p\u003e\n\u003ch2 id=\"构造函数\"\u003e构造函数\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e对于单个参数的构造函数,推荐添加 \u003ccode\u003eexplicit\u003c/code\u003e 关键字,防止隐式转换错误调用构造函数。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C++\" data-lang=\"C++\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eDemoClass\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eexplicit\u003c/span\u003e \u003cspan class=\"nf\"\u003eDemoClass\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003etest\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ethis\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etest_\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003etest\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003col start=\"2\"\u003e\n\u003cli\u003e显式声明有参构造函数后,编译器不会自动生成无参构造函数,若需要,请添加 \u003ccode\u003eDemoClass() = default;\u003c/code\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C++\" data-lang=\"C++\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eDemoClass\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eexplicit\u003c/span\u003e \u003cspan class=\"nf\"\u003eDemoClass\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003etest\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ethis\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etest_\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003etest\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eDemoClass\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003col start=\"3\"\u003e\n\u003cli\u003e若子类中没有显式调用父类的构造函数,子类会默认调用父类的无参构造函数,如果父类没有无参构造函数,会报错。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"析构函数\"\u003e析构函数\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e基类析构函数应该声明为 virtual,这样可以防止子类无法正确的析构。\u003c/li\u003e\n\u003cli\u003e由于基类析构函数为 virtual,派生类的析构函数应该显式的 override。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C++\" data-lang=\"C++\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eDemoClass\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003evirtual\u003c/span\u003e \u003cspan class=\"o\"\u003e~\u003c/span\u003e\u003cspan class=\"n\"\u003eDemoClass\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eChildClass\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"k\"\u003epublic\u003c/span\u003e \u003cspan class=\"n\"\u003eDemoClass\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e~\u003c/span\u003e\u003cspan class=\"n\"\u003eChildClass\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"k\"\u003eoverride\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003exxx\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"成员变量默认值\"\u003e成员变量默认值\u003c/h2\u003e\n\u003cp\u003e对于类或局部作用域中未明确指定默认值的成员变量,其值遵循以下规则:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e对于原生类型(\u003cstrong\u003eprimitive types\u003c/strong\u003e),即 \u003ccode\u003eint\u003c/code\u003e、\u003ccode\u003efloat\u003c/code\u003e、\u003ccode\u003eint*\u003c/code\u003e、\u003ccode\u003estring*\u003c/code\u003e 等,默认值为随机的脏数据。\u003c/li\u003e\n\u003cli\u003e对于对象(\u003cstrong\u003eobjects\u003c/strong\u003e),例如自定义类、或 \u003ccode\u003estd::string\u003c/code\u003e 等,会调用默认(无参)构造函数,若没有默认(无参)构造函数,则报错。\u003c/li\u003e\n\u003cli\u003e对于引用(\u003cstrong\u003ereference\u003c/strong\u003e)类型,例如 \u003ccode\u003estd::string\u0026amp;\u003c/code\u003e,\u003cstrong\u003e必须\u003c/strong\u003e赋初始值或在构造函数中初始化,若为初始化,则报错。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C++\" data-lang=\"C++\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eage\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 脏数据、随机值(无意义),此时访问会出现未定义行为\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003eptr\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 脏数据、随机值(无意义),此时访问会出现未定义行为\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003estring\u003c/span\u003e \u003cspan class=\"n\"\u003ename\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 调用默认构造函数,对于 std::string 来说为空字符串 \u0026#34;\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eDemoClass\u003c/span\u003e \u003cspan class=\"n\"\u003edemo\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 若 DemoClass 存在无参构造函数,则调用,否则编译错误\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003estring\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003epname\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 脏数据、随机值(无意义),此时访问会出现未定义行为\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003estring\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ername\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 编译错误,必须显式初始化\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003estring\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ecrname\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 同上,编译错误\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"成员变量初始化方式\"\u003e成员变量初始化方式\u003c/h2\u003e\n\u003cp\u003e初始化成员变量一般而言有四种方式,一般而言第二种和第四种方式为等价的,不过在下面我们会看到一种例外:\u003c/p\u003e","title":"C++ 类使用注意事项"},{"content":"楔子 昨天听了学弟们关于博客搭建的一些教程,在听的过程中,也想起了我之前对于博客的种种尝试,发现整体的趋势就是,简约再简约。\n这引发了我对我过去几年的审视,感觉自己的审美一直在变化,对于美的认识和感受也是一直在变的,故写此文来记一些我对美认识的思考。\n简约是我最终的归宿 遥记得我还在小学和初中时,非常迷恋 QQ飞车 这款游戏,这款游戏里面有一个虚拟人物,人物可以搭配各种装饰,包括但不限于上衣、裤子、发型、发饰、翅膀等,起初我是喜欢要多花哨有多花哨造型,各种发饰、翅膀、脸部特效搞的飞起,现在想起来真是非常搞笑,而且喜欢五颜六色的,当时觉得,真的是太好看了。\n但是过了一段时间,就开始感觉不对劲了,这么花哨,这么丑,这怎么可能是我当时亲手选择的造型。后来就逐渐向简约范靠拢,装饰越简单,色调越单一越喜欢。\n下面的几张图大致可以窥见这个过程:\n而长大后,对于 Blog 的搭建貌似也是这个过程。一开始喜欢相对花哨的,包括各种炫酷的背景、动效等,因此一开始选择了高定制度、有各种花哨特效的 Hexo 框架,不过当时已经在飞车中喜欢上了简约风格,因此主题也选择了 Hexo 中相对简洁的 NexT 主题。\n后来发现 Hexo 实在操作过程有些过于繁杂,从操作的意义上来说,他无法做到足够的简洁、简约和高效。\n故而我选择了操作更加方便(例如发表博文、操作主题元素)更加方便的动态博客——Typecho。\n起初,我选择延续了在 Hexo 上的 NexT 主题,后来发现了更加符合我审美的 Handsome 主题,第一眼就是非常喜欢,后来忍痛买了主题,用了一段时间后,又逐渐觉得主题没有那么好看,有些看腻了,而且动态博客的升级、安装插件,也是十分繁杂。\n最后,偶然之下,发现了现在在使用的 Hugo 框架,它生成迅速、无需升级、也有着很多简约风的主题,完美符合我的需求,果断迁移了过来,具体流程可见:记一次博客迁移记录 - Zs\u0026rsquo;s Blog ,一直用到现在,还是对这个框架和主题算是相对满意的。\n总体而言,无论是操作还是页面,都是越来越简约、统一了。不知道未来,我会不会觉得这个也不够简约和统一,再去找寻其他的框架呢。\n各种产品的变迁 除了上面我自己对美认识的变化,我觉得整个社会对美的认识也是存在变化的。\n往大了讲,是各种建筑、各种设施外观的变化。\n往小了讲,我们用的手机、手机上的软件(例如 QQ、微信),他们的外观每年都在迭代,可能每次变化时有人吐槽有人叫好,但是整体而言,至少对我来说,他是整体都是越来越好看的,虽然逐渐变得臃肿,但是 UI 确实是“实打实”的在进步。下图是 QQ 的变化(左侧是网友仿的一个老版 QQ 界面1,右图是最新版 Mac QQ),可见一二:\n那就引发了我一个思考,大家对于美的认识是被塑造了呢,还是说这个东西就是客观上的变好看了,美毕竟是一个比较主观的东西。\n如果他是主观上变好看了,那么他是真的好看了吗?而且为什么可以做到如此的统一,让大多数人都觉得变好看了。\n如果他是客观上变好看了,那么到底是什么因素的存在让人觉得他好看呢?\n我觉得美这个东西,很不像生活中常见的发展规律,例如芯片的研发,需要数学、物理、化学等学科实际理论的支持。\n2001 年的人是没有办法设计出 Apple M2 的芯片的,因为受到了各种硬件的制约。而 2001 年的设计师有没有可能设计出最新版 Mac QQ 这样的界面呢,如果不能,是什么制约着它呢?如果能,为什么没有出现这种设计,是因为当时大家觉得他不好看吗?\n因为我不是学设计和美术等专业的,并且这种很很直觉的东西我不知道该怎么去搜索,因此想在这里和大家探讨一下。如果有已经相对成熟的理论,还请大家能够告知与我,解答困扰我好久的疑问。\nAI 绘图 看网上有人调侃说,愿意称 2022 年为 AI 绘图元年。\n今年确实是突然涌现出非常多的 AI 绘图模型,并且画的还都是有模有样。这也让我想起来之前在 2021年6月 参加过学院的一个 01 学术沙龙2,主题为 “计算 + 艺术 = ∞”。当时在会上和老师们探讨过,是否机器可以理解作品中美的元素,能够理解作品中美的模式?当时大家都是各有各的看法,我个人是持乐观态度的。我觉得美的元素和美的模式,可能是客观存在的,机器人能够让一幅画符合某个模式,来让人觉得这幅画美。\n但是,机器人能否创作出独创性作品,而不是学习、融合之前元素内容,这个还不好说。会不会,这世界上艺术(画作)美的元素、或者美的模式存在是确定的、种类也是确定的,这样如果机器人全部学习到,岂不是可以看作是拿到了整个解空间的基向量,可以创作出任意风格、任意元素的内容了。\n希望不会是这样。\nhttps://www.cnblogs.com/zym/archive/2013/03/01/2939441.html\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nhttps://jsj.nwpu.edu.cn/info/1598/9734.htm\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","permalink":"https://blog.zzsqwq.cn/posts/beauty-think/","summary":"\u003ch2 id=\"楔子\"\u003e楔子\u003c/h2\u003e\n\u003cp\u003e昨天听了学弟们关于博客搭建的一些教程,在听的过程中,也想起了我之前对于博客的种种尝试,发现整体的趋势就是,简约再简约。\u003c/p\u003e\n\u003cp\u003e这引发了我对我过去几年的审视,\u003cstrong\u003e感觉\u003c/strong\u003e自己的审美一直在变化,对于美的认识和感受也是一直在变的,故写此文来记一些我对美认识的思考。\u003c/p\u003e\n\u003ch2 id=\"简约是我最终的归宿\"\u003e简约是我最终的归宿\u003c/h2\u003e\n\u003cp\u003e遥记得我还在小学和初中时,非常迷恋 QQ飞车 这款游戏,这款游戏里面有一个虚拟人物,人物可以搭配各种装饰,包括但不限于上衣、裤子、发型、发饰、翅膀等,起初我是喜欢要多花哨有多花哨造型,各种发饰、翅膀、脸部特效搞的飞起,现在想起来真是非常搞笑,而且喜欢五颜六色的,当时觉得,真的是太好看了。\u003c/p\u003e\n\u003cp\u003e但是过了一段时间,就开始感觉不对劲了,这么花哨,这么丑,这怎么可能是我当时亲手选择的造型。后来就逐渐向简约范靠拢,装饰越简单,色调越单一越喜欢。\u003c/p\u003e\n\u003cp\u003e下面的几张图大致可以窥见这个过程:\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/images/beauty-think/qq-car.png\" alt=\"qq-car\" /\u003e\n\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003e而长大后,对于 Blog 的搭建貌似也是这个过程。一开始喜欢相对花哨的,包括各种炫酷的背景、动效等,因此一开始选择了高定制度、有各种花哨特效的 Hexo 框架,不过当时已经在飞车中喜欢上了简约风格,因此主题也选择了 Hexo 中相对简洁的 \u003ca href=\"https://theme-next.iissnan.com\"\u003eNexT 主题\u003c/a\u003e。\u003c/p\u003e\n\u003cp\u003e后来发现 Hexo 实在操作过程有些过于繁杂,从操作的意义上来说,他无法做到足够的简洁、简约和高效。\u003c/p\u003e\n\u003cp\u003e故而我选择了操作更加方便(例如发表博文、操作主题元素)更加方便的动态博客——\u003ca href=\"https://typecho.org\"\u003eTypecho\u003c/a\u003e。\u003c/p\u003e\n\u003cp\u003e起初,我选择延续了在 Hexo 上的 \u003ca href=\"https://github.com/zgq354/typecho-theme-next\"\u003eNexT 主题\u003c/a\u003e,后来发现了更加符合我审美的 \u003ca href=\"https://www.ihewro.com/archives/489/\"\u003eHandsome 主题\u003c/a\u003e,第一眼就是非常喜欢,后来忍痛买了主题,用了一段时间后,又逐渐觉得主题没有那么好看,有些看腻了,而且动态博客的升级、安装插件,也是十分繁杂。\u003c/p\u003e\n\u003cp\u003e最后,偶然之下,发现了现在在使用的 Hugo 框架,它生成迅速、无需升级、也有着很多简约风的主题,完美符合我的需求,果断迁移了过来,具体流程可见:\u003ca href=\"https://blog.zzsqwq.cn/posts/221/\"\u003e记一次博客迁移记录 - Zs\u0026rsquo;s Blog\u003c/a\u003e ,一直用到现在,还是对这个框架和主题算是相对满意的。\u003c/p\u003e\n\u003cp\u003e总体而言,无论是操作还是页面,都是越来越简约、统一了。不知道未来,我会不会觉得这个也不够简约和统一,再去找寻其他的框架呢。\u003c/p\u003e\n\u003ch2 id=\"各种产品的变迁\"\u003e各种产品的变迁\u003c/h2\u003e\n\u003cp\u003e除了上面我自己对美认识的变化,我觉得整个社会对美的认识也是存在变化的。\u003c/p\u003e\n\u003cp\u003e往大了讲,是各种建筑、各种设施外观的变化。\u003c/p\u003e\n\u003cp\u003e往小了讲,我们用的手机、手机上的软件(例如 QQ、微信),他们的外观每年都在迭代,可能每次变化时有人吐槽有人叫好,但是整体而言,至少对我来说,他是整体都是越来越好看的,虽然逐渐变得臃肿,但是 UI 确实是“实打实”的在进步。下图是 QQ 的变化(左侧是网友仿的一个老版 QQ 界面\u003csup id=\"fnref:1\"\u003e\u003ca href=\"#fn:1\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e1\u003c/a\u003e\u003c/sup\u003e,右图是最新版 Mac QQ),可见一二:\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/images/beauty-think/qq.png\" alt=\"qq\" /\u003e\n\u003c/p\u003e\n\u003cp\u003e那就引发了我一个思考,大家对于美的认识是被塑造了呢,还是说这个东西就是客观上的变好看了,美毕竟是一个比较主观的东西。\u003c/p\u003e\n\u003cp\u003e如果他是主观上变好看了,那么他是真的好看了吗?而且为什么可以做到如此的统一,让大多数人都觉得变好看了。\u003c/p\u003e\n\u003cp\u003e如果他是客观上变好看了,那么到底是什么因素的存在让人觉得他好看呢?\u003c/p\u003e\n\u003cp\u003e我觉得美这个东西,很不像生活中常见的发展规律,例如芯片的研发,需要数学、物理、化学等学科实际理论的支持。\u003c/p\u003e\n\u003cp\u003e2001 年的人是没有办法设计出 Apple M2 的芯片的,因为受到了各种硬件的制约。而 2001 年的设计师有没有可能设计出最新版 Mac QQ 这样的界面呢,如果不能,是什么制约着它呢?如果能,为什么没有出现这种设计,是因为当时大家觉得他不好看吗?\u003c/p\u003e\n\u003cp\u003e因为我不是学设计和美术等专业的,并且这种很很直觉的东西我不知道该怎么去搜索,因此想在这里和大家探讨一下。如果有已经相对成熟的理论,还请大家能够告知与我,解答困扰我好久的疑问。\u003c/p\u003e\n\u003ch2 id=\"ai-绘图\"\u003eAI 绘图\u003c/h2\u003e\n\u003cp\u003e看网上有人调侃说,愿意称 2022 年为 AI 绘图元年。\u003c/p\u003e","title":"关于美的一些思考"},{"content":"前言 我们使用搜索引擎可能是为了搜集信息、或者是解决一些问题。但如果不能正确的使用搜索引擎,使用关键字等,可能搜到的答案就与问题相关不大,或者与我们的问题相差甚远。\n这篇文章意在分享我个人在学习、工作中使用搜索引擎的一些技巧与思考,可能后续会不断的更新,如有纰漏,还请大家指正。\n应该使用什么搜索平台? 想要提高搜索的效率,选择一个好的搜索引擎或者内容平台颇为重要。\n下面列举的是我平时会使用的一些平台,列出的顺序代表了我个人对于他们的推荐程度:\n通用搜索引擎:Google、Bing、DuckDuckGo、Baidu 编程相关问题:Stack Overflow、Github Issue、segmentfault、稀土掘金、腾讯云开发者社区、CSDN、华为云开发者社区 日常问题:V2EX 第一类为通用搜索引擎,例如 为什么最近头发掉的更多了? 在其上可以搜索任何问题,其中 Google 的使用门槛相对较高,而 Bing 针对国内用户来说是一个相对不错的选择,不建议常用 Baidu,因为其上广告非常多,有用信息密度相对较小。\n第二类为编程相关问题,例如 CMake 为什么报错了? 其中 Stack Overflow、Github 虽均为国外的平台,但是国内是可以访问的,不过在 Baidu 搜索引擎中词条相对靠后,同时也需要使用英文来进行问题检索。(Btw,Stack 系列还有例如 Stack Exchange 平台,它的模式与前者相同,但是更偏日常一些。)除此以外,后面的平台均为国内平台,所列是我平时常见的一些,整体而言,前面的文章质量普遍会比后面的高一些,其中腾讯云开发者社区、CSDN、华为云开发者社区三者内容重叠度较高。\n第三类为日常问题,例如 Mac 上有什么好用的 App ?可以在 V2EX 上寻找答案,当然,它也是包罗万象的,只不过我常用它来解决日常各类小问题。\n如何正确的知道问题所在? 我们遇到一个问题,要首先能够定位这个问题的关键。\n例如编译中出错了,可能有很多 log,你必须能够精确定位到到底哪一条 log 才是这次编译出错的关键,进而才能解决这个问题。\n以 CMake 为例,编译时报错 log 一般为红色,警告 log 一般为黄色,普通 log 一般为白色。得益于这种等级/颜色分明的 log ,我们可以快速的定位报错。我们日常编程中,为了便于 Debug,最好也遵循这个规范,例如在 C++ 中打印错误 log 时推荐使用 std::stderr 而不是 std::stdout 。\n见过很多身边的同学遇到了报错,就一股脑粘贴所有的报错 log,然后贴到搜索引擎中,发现相关的错误基本没有。这就是没有其中错误的关键,报错时的 log 可能 100 行只有 10 行是关键的,甚至只有一行是关键的,例如 100 行 log 中只有 未定义的引用(undefined reference to \u0026lsquo;xxx\u0026rsquo;) 这一句是最关键的。\n搜索不到怎么办? 即使你选择了正确的平台,筛选出了关键的报错信息,你可能仍然无法搜索到对应的问题,这怎么办呢?\n首先,你可能需要转换一下语言,例如之前问题采用中文,你应该将其翻译成英文再重新搜索,记得翻译时要保证专有名词的正确性。\n如果还是不行,这个时候我认为应该首先静下心来思考一下这是属于什么问题,是这个程序特有的问题,还是这个程序使用的某个库或部件导致的问题?你可能需要仔细思考来进一步提取错误(问题)中的关键所在,使用提取的关键字继续搜索或者去查对应的程序或者库的 Q\u0026amp;A ,如果还是无法找到,就应该去看相应部分的文档,去 RTFM(Read The Fantastic Manual)。\n最后的最后,还是无法找到的话,那你就应该考虑去对应程序、库或部件的 Github Issue 或者论坛、或非定向的 Stack Overflow 等平台提交问题,在提问之前,你最好仔细阅读过 提问的智慧1,不然可能无法获得到热情、友善的回复。\n上图所示是我之前 有关 Microsoft Edge 的一个提问 ,应该可以算是一个相对正确的示范。\n最好积累一个错误文档 感觉这个的作用有点类似于高中时候老师们推崇的错题本了,虽然我一直觉得没啥用,也几乎没有照做过。\n但是在平常解决问题时我确实是会遇到,上次明明遇到过类似的问题,我也解决了,但是再遇到又忘了如何解决了。可能是因为随着年纪的增大记性越来越差了🤣,不过如果大家不嫌麻烦可以养成每次遇错都能记录一下,估计坚持下来会非常的有用(虽然我自己都没做到)。\nEnglish version: http://www.catb.org/~esr/faqs/smart-questions.html\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","permalink":"https://blog.zzsqwq.cn/posts/how-to-search/","summary":"\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003e我们使用搜索引擎可能是为了搜集信息、或者是解决一些问题。但如果不能正确的使用搜索引擎,使用关键字等,可能搜到的答案就与问题相关不大,或者与我们的问题相差甚远。\u003c/p\u003e\n\u003cp\u003e这篇文章意在分享我个人在学习、工作中使用搜索引擎的一些技巧与思考,可能后续会不断的更新,如有纰漏,还请大家指正。\u003c/p\u003e\n\u003ch2 id=\"应该使用什么搜索平台\"\u003e应该使用什么搜索平台?\u003c/h2\u003e\n\u003cp\u003e想要提高搜索的效率,选择一个好的搜索引擎或者内容平台颇为重要。\u003c/p\u003e\n\u003cp\u003e下面列举的是我平时会使用的一些平台,列出的顺序代表了我个人对于他们的推荐程度:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e通用搜索引擎:\u003ca href=\"https://google.com\"\u003eGoogle\u003c/a\u003e、\u003ca href=\"https://bing.com\"\u003eBing\u003c/a\u003e、\u003ca href=\"https://duckduckgo.com\"\u003eDuckDuckGo\u003c/a\u003e、\u003ca href=\"https://baidu.com\"\u003eBaidu\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e编程相关问题:\u003ca href=\"https://stackoverflow.com\"\u003eStack Overflow\u003c/a\u003e、\u003ca href=\"https://github.com\"\u003eGithub Issue\u003c/a\u003e、\u003ca href=\"https://segmentfault.com\"\u003esegmentfault\u003c/a\u003e、\u003ca href=\"https://juejin.cn\"\u003e稀土掘金\u003c/a\u003e、\u003ca href=\"https://cloud.tencent.com/developer\"\u003e腾讯云开发者社区\u003c/a\u003e、\u003ca href=\"https://www.csdn.net\"\u003eCSDN\u003c/a\u003e、\u003ca href=\"https://developer.huaweicloud.com\"\u003e华为云开发者社区\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e日常问题:\u003ca href=\"https://www.v2ex.com\"\u003eV2EX\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e第一类为通用搜索引擎,例如 \u003cem\u003e为什么最近头发掉的更多了?\u003c/em\u003e 在其上可以搜索任何问题,其中 Google 的使用门槛相对较高,而 Bing 针对国内用户来说是一个相对不错的选择,不建议常用 Baidu,因为其上广告非常多,有用信息密度相对较小。\u003c/p\u003e\n\u003cp\u003e第二类为编程相关问题,例如 \u003cem\u003eCMake 为什么报错了?\u003c/em\u003e 其中 Stack Overflow、Github 虽均为国外的平台,但是国内是可以访问的,不过在 Baidu 搜索引擎中词条相对靠后,\u003cstrong\u003e同时也需要使用英文来进行问题检索\u003c/strong\u003e。(Btw,Stack 系列还有例如 \u003ca href=\"https://stackexchange.com\"\u003eStack Exchange\u003c/a\u003e 平台,它的模式与前者相同,但是更偏日常一些。)除此以外,后面的平台均为国内平台,所列是我平时常见的一些,整体而言,前面的文章质量普遍会比后面的高一些,其中腾讯云开发者社区、CSDN、华为云开发者社区三者内容重叠度较高。\u003c/p\u003e\n\u003cp\u003e第三类为日常问题,例如 \u003cem\u003eMac 上有什么好用的 App\u003c/em\u003e ?可以在 V2EX 上寻找答案,当然,它也是包罗万象的,只不过我常用它来解决日常各类小问题。\u003c/p\u003e\n\u003ch2 id=\"如何正确的知道问题所在\"\u003e如何正确的知道问题所在?\u003c/h2\u003e\n\u003cp\u003e我们遇到一个问题,要首先能够定位这个问题的关键。\u003c/p\u003e\n\u003cp\u003e例如编译中出错了,可能有很多 log,你必须能够精确定位到到底哪一条 log 才是这次编译出错的关键,进而才能解决这个问题。\u003c/p\u003e\n\u003cp\u003e以 CMake 为例,编译时报错 log 一般为\u003cfont color=\"red\"\u003e红色\u003c/font\u003e,警告 log 一般为\u003cfont color=\"yellow\"\u003e黄色\u003c/font\u003e,普通 log 一般为白色。得益于这种等级/颜色分明的 log ,我们可以快速的定位报错。我们日常编程中,为了便于 Debug,最好也遵循这个规范,例如在 \u003ccode\u003eC++\u003c/code\u003e 中打印错误 log 时推荐使用 \u003ccode\u003estd::stderr\u003c/code\u003e 而不是 \u003ccode\u003estd::stdout\u003c/code\u003e 。\u003c/p\u003e\n\u003cp\u003e见过很多身边的同学遇到了报错,就一股脑粘贴所有的报错 log,然后贴到搜索引擎中,发现相关的错误基本没有。这就是没有其中错误的关键,报错时的 log 可能 100 行只有 10 行是关键的,甚至只有一行是关键的,例如 100 行 log 中只有 \u003cstrong\u003e未定义的引用(undefined reference to \u0026lsquo;xxx\u0026rsquo;)\u003c/strong\u003e 这一句是最关键的。\u003c/p\u003e","title":"如何善用搜索引擎?"},{"content":"为什么要使用条件变量? 前言 最近看了很多与线程有关的 C++ 新特性,条件变量是见的比较多的一个特性。\n看的时候我发现,想要理解一个新的特性,关键的要看它的引入到底解决了哪些问题,没有什么特性我们要实现相同的功能要怎么做?\n以我的理解来看,条件变量是一个线程间互相同步与通知的手段,他通过主动唤醒的方式减小了各个线程的开销,取代了简单但是消耗较大的一直被动循环检验与等待。\n没有条件变量我们如何实现相同的需求? 这里采用现代C++教程1 中关于条件变量的一个例子作为基础:\n不使用条件变量版本 #include \u0026lt;queue\u0026gt; #include \u0026lt;chrono\u0026gt; #include \u0026lt;mutex\u0026gt; #include \u0026lt;thread\u0026gt; #include \u0026lt;iostream\u0026gt; #include \u0026lt;condition_variable\u0026gt; int main() { std::queue\u0026lt;int\u0026gt; produced_nums; std::mutex mtx; // 生产者 auto producer = [\u0026amp;]() { for (int i = 0; ; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(900)); std::unique_lock\u0026lt;std::mutex\u0026gt; lock(mtx); std::cout \u0026lt;\u0026lt; \u0026#34;producing \u0026#34; \u0026lt;\u0026lt; i \u0026lt;\u0026lt; std::endl; produced_nums.push(i); } }; // 消费者 auto consumer = [\u0026amp;]() { while (true) { { std::unique_lock\u0026lt;std::mutex\u0026gt; lock(mtx); if(produced_nums.empty()) continue; } std::unique_lock\u0026lt;std::mutex\u0026gt; lock(mtx); // 短暂取消锁,使得生产者有机会在消费者消费空前继续生产 lock.unlock(); // 消费者慢于生产者 std::this_thread::sleep_for(std::chrono::milliseconds(1000)); lock.lock(); while (!produced_nums.empty()) { std::cout \u0026lt;\u0026lt; \u0026#34;consuming \u0026#34; \u0026lt;\u0026lt; produced_nums.front() \u0026lt;\u0026lt; std::endl; produced_nums.pop(); } } }; // 分别在不同的线程中运行 std::thread p(producer); std::thread cs[2]; for (int i = 0; i \u0026lt; 2; ++i) { cs[i] = std::thread(consumer); } p.join(); for (int i = 0; i \u0026lt; 2; ++i) { cs[i].join(); } return 0; } 使用条件变量版本 #include \u0026lt;queue\u0026gt; #include \u0026lt;chrono\u0026gt; #include \u0026lt;mutex\u0026gt; #include \u0026lt;thread\u0026gt; #include \u0026lt;iostream\u0026gt; #include \u0026lt;condition_variable\u0026gt; int main() { std::queue\u0026lt;int\u0026gt; produced_nums; std::mutex mtx; std::condition_variable cv; bool notified = false; // 通知信号 // 生产者 auto producer = [\u0026amp;]() { for (int i = 0; ; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(900)); std::unique_lock\u0026lt;std::mutex\u0026gt; lock(mtx); std::cout \u0026lt;\u0026lt; \u0026#34;producing \u0026#34; \u0026lt;\u0026lt; i \u0026lt;\u0026lt; std::endl; produced_nums.push(i); notified = true; cv.notify_all(); // 此处也可以使用 notify_one } }; // 消费者 auto consumer = [\u0026amp;]() { while (true) { std::unique_lock\u0026lt;std::mutex\u0026gt; lock(mtx); while (!notified) { // 避免虚假唤醒 cv.wait(lock); } // 短暂取消锁,使得生产者有机会在消费者消费空前继续生产 lock.unlock(); // 消费者慢于生产者 std::this_thread::sleep_for(std::chrono::milliseconds(1000)); lock.lock(); while (!produced_nums.empty()) { std::cout \u0026lt;\u0026lt; \u0026#34;consuming \u0026#34; \u0026lt;\u0026lt; produced_nums.front() \u0026lt;\u0026lt; std::endl; produced_nums.pop(); } notified = false; } }; // 分别在不同的线程中运行 std::thread p(producer); std::thread cs[2]; for (int i = 0; i \u0026lt; 2; ++i) { cs[i] = std::thread(consumer); } p.join(); for (int i = 0; i \u0026lt; 2; ++i) { cs[i].join(); } return 0; } 这两段代码在效果上是等效的,都是一个生产者两个消费者。\n前者使用了 while 循环来一直检查是否可以消费,后者使用了 cv.wait(lock) 条件变量来实现阻塞等待可消费的提醒。\n可以发现在这个例子里,前者是主动的去检查是否可以消费,后者是被动的被提醒可以消费,而主动则代表着需要一直询问查询,主动的 while 循环检查始终在重复如下流程:\n而这个上锁、检查、释放锁的过程就是非常冗余、消耗资源、效率低下的,而条件变量解决了这个问题,条件变量做的事:\n这里需要注意的一点是,在条件变量调用 wait() 时,做了两件事,一个是阻塞线程等待其他线程唤醒、另一个是释放锁,只有这样才会让别的线程有机会获得锁,而被唤醒后又会自动上锁。\n为什么要和 mutex 与 lock 一起用? 我们常见的搭配就是 condition_variable、mutex、unique_lock 一起使用,那么为什么要这么做呢?\n一个比较常见的说法是,在调用 wait() 函数与线程真正的阻塞等待状态是存在一定时间差的,那么就会存在唤醒丢失的问题,一种情况如下:\n线程A: ------- 调用 wait() 函数 ------- 进入等待状态 ------ 线程B: -------------------------唤醒A------------------- 而我们希望的是:\n线程A: ------- 调用 wait() 函数 ------- 进入等待状态 ------ 线程B: -------------------------------------------唤醒A- 我们总是要确保,在线程 A 真正进入等待状态后再进行唤醒,因此这里需要一个 lock 来保证我们对于一个线程空闲/等待的改变是原子性的,也就是不应该被其他线程中途干扰。\n为什么使用 unique_lock 而不使用 scoped_lock 或 lock_guard 首先三个函数都是 RAII 的锁管理函数,可以有效解决 lock 后忘记 unlock 的情形,而目前在 C++17 后推荐统一使用 scoped_lock 而不是 lock_guard。\n而使用 unique_lock 是因为我们在使用条件变量时,需要在条件变量 wait 时解除 lock,只有 unique_lock 能够满足这个条件,实现自己更细粒度的锁区间的划分。\n什么是虚假唤醒? 可以注意到在第一部分代码中有这么一段:\nauto consumer = [\u0026amp;]() { while (true) { std::unique_lock\u0026lt;std::mutex\u0026gt; lock(mtx); while (!notified) { // 避免虚假唤醒 cv.wait(lock); } // ... notified = false; } }; 避免虚假唤醒,那么什么是虚假唤醒呢?\n虚假唤醒简而言之就是,没有满足消费的条件却被唤醒后进行了消费。\n这个发生的可能多是在系统调度层面,具体的可以参考此知乎问题:为什么条件锁会产生虚假唤醒现象(spurious wakeup)?\n而解决的方案就是在消费之前再检查一下是否满足消费的条件,而这个消费条件多是用一个形如 notified 的 bool 变量来标识是否可以消费。\n如果不检查,带条件变量的执行流程就会像如下这样:\n其中少了一步检查是否可以消费的过程。\n后记 本文记录了我在学习条件变量过程中的一些疑问,如有错误之处,敬请交流指正。\nhttps://changkun.de/modern-cpp/\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","permalink":"https://blog.zzsqwq.cn/posts/why-use-condition-variable/","summary":"\u003ch1 id=\"为什么要使用条件变量\"\u003e为什么要使用条件变量?\u003c/h1\u003e\n\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003e最近看了很多与线程有关的 C++ 新特性,条件变量是见的比较多的一个特性。\u003c/p\u003e\n\u003cp\u003e看的时候我发现,想要理解一个新的特性,关键的要看它的引入到底解决了哪些问题,没有什么特性我们要实现相同的功能要怎么做?\u003c/p\u003e\n\u003cp\u003e以我的理解来看,条件变量是一个线程间互相同步与通知的手段,他通过\u003cstrong\u003e主动唤醒\u003c/strong\u003e的方式减小了各个线程的开销,取代了简单但是消耗较大的一直\u003cstrong\u003e被动循环检验与等待\u003c/strong\u003e。\u003c/p\u003e\n\u003ch2 id=\"没有条件变量我们如何实现相同的需求\"\u003e没有条件变量我们如何实现相同的需求?\u003c/h2\u003e\n\u003cp\u003e这里采用现代C++教程\u003csup id=\"fnref:1\"\u003e\u003ca href=\"#fn:1\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e1\u003c/a\u003e\u003c/sup\u003e 中关于条件变量的一个例子作为基础:\u003c/p\u003e\n\u003ch3 id=\"不使用条件变量版本\"\u003e不使用条件变量版本\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C++\" data-lang=\"C++\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;queue\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;chrono\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;mutex\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;thread\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;condition_variable\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003equeue\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eproduced_nums\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003emutex\u003c/span\u003e \u003cspan class=\"n\"\u003emtx\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 生产者\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eauto\u003c/span\u003e \u003cspan class=\"n\"\u003eproducer\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"p\"\u003e]()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003ethis_thread\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003esleep_for\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003echrono\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003emilliseconds\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e900\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eunique_lock\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003emutex\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003elock\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003emtx\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;producing \u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eproduced_nums\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epush\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 消费者\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eauto\u003c/span\u003e \u003cspan class=\"n\"\u003econsumer\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"p\"\u003e]()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eunique_lock\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003emutex\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003elock\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003emtx\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eproduced_nums\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eempty\u003c/span\u003e\u003cspan class=\"p\"\u003e())\u003c/span\u003e \u003cspan class=\"k\"\u003econtinue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eunique_lock\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003emutex\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003elock\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003emtx\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 短暂取消锁,使得生产者有机会在消费者消费空前继续生产\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003elock\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eunlock\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 消费者慢于生产者\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003ethis_thread\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003esleep_for\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003echrono\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003emilliseconds\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1000\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003elock\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003elock\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"n\"\u003eproduced_nums\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eempty\u003c/span\u003e\u003cspan class=\"p\"\u003e())\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;consuming \u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eproduced_nums\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efront\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eproduced_nums\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epop\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 分别在不同的线程中运行\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"kr\"\u003ethread\u003c/span\u003e \u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eproducer\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"kr\"\u003ethread\u003c/span\u003e \u003cspan class=\"n\"\u003ecs\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecs\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"kr\"\u003ethread\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econsumer\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ejoin\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecs\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003ejoin\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"使用条件变量版本\"\u003e使用条件变量版本\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C++\" data-lang=\"C++\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;queue\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;chrono\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;mutex\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;thread\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;condition_variable\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003equeue\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eproduced_nums\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003emutex\u003c/span\u003e \u003cspan class=\"n\"\u003emtx\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003econdition_variable\u003c/span\u003e \u003cspan class=\"n\"\u003ecv\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"n\"\u003enotified\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 通知信号\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 生产者\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eauto\u003c/span\u003e \u003cspan class=\"n\"\u003eproducer\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"p\"\u003e]()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003ethis_thread\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003esleep_for\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003echrono\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003emilliseconds\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e900\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eunique_lock\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003emutex\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003elock\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003emtx\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;producing \u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eproduced_nums\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epush\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003enotified\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecv\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003enotify_all\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 此处也可以使用 notify_one\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 消费者\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eauto\u003c/span\u003e \u003cspan class=\"n\"\u003econsumer\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"p\"\u003e]()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eunique_lock\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003emutex\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003elock\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003emtx\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"n\"\u003enotified\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 避免虚假唤醒\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003ecv\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ewait\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003elock\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 短暂取消锁,使得生产者有机会在消费者消费空前继续生产\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003elock\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eunlock\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 消费者慢于生产者\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003ethis_thread\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003esleep_for\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003echrono\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003emilliseconds\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1000\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003elock\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003elock\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"n\"\u003eproduced_nums\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eempty\u003c/span\u003e\u003cspan class=\"p\"\u003e())\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;consuming \u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eproduced_nums\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efront\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eproduced_nums\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epop\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003enotified\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 分别在不同的线程中运行\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"kr\"\u003ethread\u003c/span\u003e \u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eproducer\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"kr\"\u003ethread\u003c/span\u003e \u003cspan class=\"n\"\u003ecs\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecs\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"kr\"\u003ethread\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econsumer\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ejoin\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecs\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003ejoin\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e这两段代码在效果上是等效的,都是一个生产者两个消费者。\u003c/p\u003e","title":"为什么要使用条件变量?"},{"content":"背景 之前看到过学长学姐做过个人主页,多是用来申请一些学校的夏令营使用的,觉得非常的 Nice,自己也想搞一个。\n大家之前好像大多用的是基于 Hexo 的一个主题 — hexo-theme-academia,但是由于之前我用过 Hexo,觉得他有一些比较明显的弊端,例如环境配置比较麻烦、需要安装 Nodejs、npm 等环境,然后再安装 Hexo。其次它的构建速度比较慢,用起来感觉比较僵硬。\n后来随着了解增多,尝试了 Typecho、WordPress,Hugo 等主题后,目前还是决定使用 Hugo。它构建速度快,而且安装简单,在 Ubuntu 上只需要一行 sudo apt install hugo 即可,不可谓不简单。因此萌生了移植一个 Hugo 版本主题的想法,刚好可以锻炼一下自己。\n欢迎点击 这里 查看我的个人主页。\n一些难点 之前从来没有了解过 Hugo 主题的写法以及 Hexo 主题的写法,不过看了一下仓库的组织形式还算好理解。\n这类静态博客生成器都是需要写一些模板文件,然后根据配置文件进行个性化构建。\nHugo 的文档 十分的完善,学习就像是学习一门编程语言,里面有很多函数和变量,还有各种条件结构、循环结构等。原主题是采用的 pug + stylus 的方式,而不是传统的 html + css 。不过这两者之间的转换并不麻烦,而且有一些工具可以参考着转换,例如 pug2html 以及 stylus2css 。\n后续就参考着一点点的移植就可以,同时我也改写了一下配置文件(使用的 yaml 格式),大概是更易于配置了。\n同时,得益于 Hugo 的强大,我很方便的完成了对多语言的支持。\n最终效果 目前已经更新到了 v1.1.0 版本,欢迎大家体验,有问题可以及时反馈!\n主题链接:https://github.com/zzsqwq/hugo-academia-theme\n演示站:https://zzsqwq.github.io/academic-pages-demo/\n英文文档:https://github.com/zzsqwq/hugo-academia-theme/blob/master/README.md\n中文文档:https://github.com/zzsqwq/hugo-academia-theme/blob/master/README.zh_cn.md\n英文效果图:\n中文效果图:\n","permalink":"https://blog.zzsqwq.cn/posts/my-hugo-academia-theme/","summary":"\u003ch2 id=\"背景\"\u003e背景\u003c/h2\u003e\n\u003cp\u003e之前看到过学长学姐做过个人主页,多是用来申请一些学校的夏令营使用的,觉得非常的 Nice,自己也想搞一个。\u003c/p\u003e\n\u003cp\u003e大家之前好像大多用的是基于 Hexo 的一个主题 — \u003ca href=\"https://github.com/PhosphorW/hexo-theme-academia\"\u003ehexo-theme-academia\u003c/a\u003e,但是由于之前我用过 Hexo,觉得他有一些比较明显的弊端,例如环境配置比较麻烦、需要安装 Nodejs、npm 等环境,然后再安装 Hexo。其次它的构建速度比较慢,用起来感觉比较僵硬。\u003c/p\u003e\n\u003cp\u003e后来随着了解增多,尝试了 Typecho、WordPress,Hugo 等主题后,目前还是决定使用 Hugo。它构建速度快,而且安装简单,在 Ubuntu 上只需要一行 \u003ccode\u003esudo apt install hugo\u003c/code\u003e 即可,不可谓不简单。因此萌生了移植一个 Hugo 版本主题的想法,刚好可以锻炼一下自己。\u003c/p\u003e\n\u003cp\u003e欢迎点击 \u003ca href=\"https://zzsqwq.cn\"\u003e这里\u003c/a\u003e 查看我的个人主页。\u003c/p\u003e\n\u003ch2 id=\"一些难点\"\u003e一些难点\u003c/h2\u003e\n\u003cp\u003e之前从来没有了解过 Hugo 主题的写法以及 Hexo 主题的写法,不过看了一下仓库的组织形式还算好理解。\u003c/p\u003e\n\u003cp\u003e这类静态博客生成器都是需要写一些模板文件,然后根据配置文件进行个性化构建。\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://gohugo.io/documentation/\"\u003eHugo 的文档\u003c/a\u003e 十分的完善,学习就像是学习一门编程语言,里面有很多函数和变量,还有各种条件结构、循环结构等。原主题是采用的 pug + stylus 的方式,而不是传统的 html + css 。不过这两者之间的转换并不麻烦,而且有一些工具可以参考着转换,例如 \u003ca href=\"https://pughtml.com/\"\u003epug2html\u003c/a\u003e 以及 \u003ca href=\"https://verytoolz.com/stylus-css.html\"\u003estylus2css\u003c/a\u003e 。\u003c/p\u003e\n\u003cp\u003e后续就参考着一点点的移植就可以,同时我也改写了一下配置文件(使用的 yaml 格式),大概是更易于配置了。\u003c/p\u003e\n\u003cp\u003e同时,得益于 Hugo 的强大,我很方便的完成了对多语言的支持。\u003c/p\u003e\n\u003ch2 id=\"最终效果\"\u003e最终效果\u003c/h2\u003e\n\u003cp\u003e目前已经更新到了 v1.1.0 版本,欢迎大家体验,有问题可以及时反馈!\u003c/p\u003e\n\u003cp\u003e主题链接:https://github.com/zzsqwq/hugo-academia-theme\u003c/p\u003e\n\u003cp\u003e演示站:https://zzsqwq.github.io/academic-pages-demo/\u003c/p\u003e\n\u003cp\u003e英文文档:https://github.com/zzsqwq/hugo-academia-theme/blob/master/README.md\u003c/p\u003e\n\u003cp\u003e中文文档:https://github.com/zzsqwq/hugo-academia-theme/blob/master/README.zh_cn.md\u003c/p\u003e\n\u003cp\u003e英文效果图:\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/images/hugo-academia-theme/demo-en.png\" alt=\"demo-en\" /\u003e\n\u003c/p\u003e\n\u003cp\u003e中文效果图:\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/images/hugo-academia-theme/demo-zh_cn.png\" alt=\"demo-zh_cn\" /\u003e\n\u003c/p\u003e","title":"一个基于 Hugo 的个人主页主题"},{"content":"背景 在使用 Docker 搭建 Gitlab/Gitee 会导致无法与主机端共用 22 端口,这导致 ssh 连接的时候会使用形如 ssh://git@git.xxxx.cn:4022/zs/zsblog.git 的 ssh 链接,而不是像官方 Gitlab 那种非常干净的 git@git.xxxx.cn/zs/zsblog.git 链接。这对于我这种强迫症而言非常的难受啊,但因为主机的 22 端口已经被占用了,无法共用,所以需要考虑两者共享端口的问题。\n虽说是两者共用,但其实还是使用类似于端口转发的特点,简单说就是在主机设置 git 用户,然后通过一个脚本将 git 用户的所有 ssh 流量转发到 Gitlab 容器中,从而完成对应的事情。\n关于 Gitee 的设置,Gitee 官方的 Docker 部署教程1已经说的很清楚了,按照该步骤执行完全没问题。\n而关于 Gitlab 貌似没有比较详尽的教程,搜索后发现了一个 Issue2 以及一篇博文3,后者讲的比较清楚,但是经过实践后发现存在一定问题,因此决定将可行的方案记录下来。\n具体步骤 一、初始设置 在开始之前,docker-compose.yml 中设置比较关键的几个配置如下:\ngitlab-web: image: \u0026#39;gitlab/gitlab-ce:latest\u0026#39; container_name: \u0026#39;gitlab\u0026#39; restart: always environment: GITLAB_OMNIBUS_CONFIG: | gitlab_rails[\u0026#39;gitlab_shell_ssh_port\u0026#39;] = 4022 ports: - \u0026#39;3090:80\u0026#39; - \u0026#39;4022:22\u0026#39; - \u0026#39;6060:6060\u0026#39; volumes: - \u0026#39;/srv/gitlab/config:/etc/gitlab\u0026#39; - \u0026#39;/srv/gitlab/logs:/var/log/gitlab\u0026#39; - \u0026#39;/srv/gitlab/data:/var/opt/gitlab\u0026#39; - .... #一些其他的配置 如上设置基本可以确保 Gitlab 形如 ssh://git@git.xxxx.cn:4022/zs/zsblog.git 的链接可以使用。\n二、在 Host 宿主机创建与 Gitlab 相同的 git user 为了确保后续一些麻烦的权限问题,我们需要在宿主机也创建一个 git 用户。\n首先我们要检查 Gitlab 容器中 git 用户的 UID 以及 GID,如果不出意外的话,两者都已被硬编码为 998 。不过为了以防万一,我们可以通过下述指令进一步确认:\n❯ docker exec -it gitlab cat /etc/passwd | awk -F\u0026#39;:\u0026#39; \u0026#39;{if($1==\u0026#34;git\u0026#34;) printf(\u0026#34;uid: %s; gid: %s\\n\u0026#34;), $3, $4}\u0026#39; # 不出意外结果如下,证明 git 账户的 UID 与 GID 都为 998. uid: 998; gid: 998 这条指令会给出我们对应的 UID 以及 GID。\n接下来我们需要在宿主机中也创建 git 用户,确保 UID 及 GID 都与 Gitlab 容器内的一致。大家可以通过如下指令查看是否已有 git 用户,以及其 UID 与 GID。\n❯ cat /etc/passwd | awk -F\u0026#39;:\u0026#39; \u0026#39;{if($1==\u0026#34;git\u0026#34;) printf(\u0026#34;uid: %s; gid: %s\\n\u0026#34;), $3, $4}\u0026#39; 如果没有任何结果,说明没有 git 用户 如果有结果,并且 UID 与 GID 不为 998,说明需要重新该一下对应的 UID 与 GID,大家可以自行搜索解决方案。 我们还需要查看 /etc/passwd 与 /etc/group 两个文件确保 998 没有被使用,如果有使用也需要做对应改变。 如果没有 git 用户,则使用下面指令创建并指定家目录为 /home/git (在 root 用户下)\n❯ groupadd -g 998 git ❯ useradd -m -u 998 -g git -s /bin/sh -d /home/git git 如果已有,则确保其 UID 与 GID 和 Gitlab 容器中 git 用户相同,并确保有家目录 /home/git。\n三、复制 Gitlab 密钥文件 Gitlab 的密钥文件目前存放在容器的 /var/opt/gitlab/.ssh 中,然后根据你在 docker-compose.yml 配置的映射位置看,好比我配置的映射是 /srv/gitlab/data:/var/opt/gitlab,你就可以直接在 /srv/gitlab/data/.ssh 目录下找到对应的密钥文件。\n然后首先在 root 用户权限下执行\n❯ cp -r /srv/gitlab/data/.ssh /home/git/.ssh 将对应的文件夹复制到 git 用户家目录下,然后执行\n❯ chown -R git:git /home/git/.ssh 将所有的文件的权限及组权限都更改为 git 用户\n现在 git 用户的 .ssh 目录结构应该如下,也要确保 .ssh 文件权限为 700,authorized_keys 权限为 6004:\n❯ ls -la total 72 drwx------ 2 git git 4096 Apr 24 15:40 . drwxr-xr-x 5 git git 4096 Apr 24 02:00 .. -rw------- 1 git git 50122 Apr 24 02:00 authorized_keys -rw-r--r-- 1 git git 0 Apr 24 01:57 authorized_keys.lock -rw------- 1 git git 1679 Apr 24 01:48 id_rsa -rw-r--r-- 1 git git 390 Apr 24 01:48 id_rsa.pub -rw-r--r-- 1 git git 222 Apr 24 02:00 known_hosts 四、生成密钥文件 切换到 git 用户并生成密钥对\n❯ su - git ❯ ssh-keygen #然后一路回车 然后将公钥加入 authorized_keys\n❯ cat ~/.ssh/id_rsa.pub \u0026gt;\u0026gt; ~/.ssh/authorized_keys 五、创建脚本文件 我们不妨看一下现在的 authorized_keys 文件,里面应该有形如下面的内容一些行\ncommand=\u0026#34;/opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell key-105\u0026#34;,no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-ed25519 xxxxxxxx 这里说明我们提交时会执行一个 /opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell 脚本,这里本应该执行的是容器内的脚本,但是我们现在把它放在了容器外,因此我们需要设置一个脚本将请求转发进去,因此选择在本机的 /opt/gitlab/embedded/service/gitlab-shell/bin 目录下创建一个名为 gitlab-shell 的脚本,命令如下:\n# 创建文件夹 ❯ sudo mkdir -p /opt/gitlab/embedded/service/gitlab-shell/bin # 进入文件夹 ❯ cd /opt/gitlab/embedded/service/gitlab-shell/bin # 创建文件 ❯ sudo vim gitlab-shell 文件内容如下:\n#!/bin/sh ssh -i /home/git/.ssh/id_rsa -p 4022 -o StrictHostKeyChecking=no git@127.0.0.1 \u0026#34;SSH_ORIGINAL_COMMAND=\\\u0026#34;$SSH_ORIGINAL_COMMAND\\\u0026#34; $0 $@\u0026#34; 需要注意的是,这里的 4022 是指在 docker-compose.yml 文件映射的 4022:22 端口,如果你是 xxx:22 ,则需要在这里填写 xxx,对应起来。内\n然后不要忘记添加执行权限\n❯ sudo chmod +x /opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell 六、挂载额外的文件到 Gitlab 容器 修改我们的 docker-compose.yml ,注释掉 gitlab_rails['gitlab_shell_ssh_port'] = 4022 以及添加 '/home/git/.ssh/:/var/opt/gitlab/.ssh' ,将 git 用户的 .ssh 目录挂载到容器内。\ngitlab-web: image: \u0026#39;gitlab/gitlab-ce:latest\u0026#39; container_name: \u0026#39;gitlab\u0026#39; restart: always environment: GITLAB_OMNIBUS_CONFIG: | .... ports: - \u0026#39;3090:80\u0026#39; - \u0026#39;4022:22\u0026#39; - \u0026#39;6060:6060\u0026#39; volumes: - \u0026#39;/srv/gitlab/config:/etc/gitlab\u0026#39; - \u0026#39;/srv/gitlab/logs:/var/log/gitlab\u0026#39; - \u0026#39;/srv/gitlab/data:/var/opt/gitlab\u0026#39; - \u0026#39;/home/git/.ssh/:/var/opt/gitlab/.ssh\u0026#39; - .... #一些其他的配置 最后,重启容器即可生效。\n❯ docker-compose up -d 简单的原理说明 使用的原理就是将主机 git 用户的所有 ssh 流量都转发到容器内部。\n转发使用的是宿主机中的/opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell 脚本,而因为已经将主机 git 用户 id_rsa.pub 添加到了 authorized_keys 中,因此可以直接免密转发内容到容器内部。\n随后,容器内的 gitlab-shell 脚本对请求进行处理,完成 ssh 请求。\n这里很巧妙的使用了同一个位置的脚本,这也是需要将 git 用户的 .ssh 目录挂载到 Gitlab 内部的原因,但是每个脚本却作用不同,十分的巧妙。\n使用 Docker 安装 ↩\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nSharing SSH port between host and the container\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nExposing ssh port in dockerized gitlab-ce\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n公钥添加到authorized_keys到文件中之后仍无法免密登陆\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","permalink":"https://blog.zzsqwq.cn/posts/docker-gitlab-ssh/","summary":"\u003ch2 id=\"背景\"\u003e背景\u003c/h2\u003e\n\u003cp\u003e在使用 Docker 搭建 Gitlab/Gitee 会导致无法与主机端共用 22 端口,这导致 ssh 连接的时候会使用形如 \u003ccode\u003essh://git@git.xxxx.cn:4022/zs/zsblog.git\u003c/code\u003e 的 ssh 链接,而不是像官方 Gitlab 那种非常干净的 \u003ccode\u003egit@git.xxxx.cn/zs/zsblog.git\u003c/code\u003e 链接。这对于我这种强迫症而言非常的难受啊,但因为主机的 22 端口已经被占用了,无法共用,所以需要考虑两者共享端口的问题。\u003c/p\u003e\n\u003cp\u003e虽说是两者共用,但其实还是使用类似于端口转发的特点,简单说就是在主机设置 \u003ccode\u003egit\u003c/code\u003e 用户,然后通过一个脚本将 \u003ccode\u003egit\u003c/code\u003e 用户的所有 ssh 流量转发到 Gitlab 容器中,从而完成对应的事情。\u003c/p\u003e\n\u003cp\u003e关于 Gitee 的设置,Gitee 官方的 Docker 部署教程\u003csup id=\"fnref:1\"\u003e\u003ca href=\"#fn:1\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e1\u003c/a\u003e\u003c/sup\u003e已经说的很清楚了,按照该步骤执行完全没问题。\u003c/p\u003e\n\u003cp\u003e而关于 Gitlab 貌似没有比较详尽的教程,搜索后发现了一个 Issue\u003csup id=\"fnref:2\"\u003e\u003ca href=\"#fn:2\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e2\u003c/a\u003e\u003c/sup\u003e 以及一篇博文\u003csup id=\"fnref:3\"\u003e\u003ca href=\"#fn:3\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e3\u003c/a\u003e\u003c/sup\u003e,后者讲的比较清楚,但是经过实践后发现存在一定问题,因此决定将可行的方案记录下来。\u003c/p\u003e\n\u003ch2 id=\"具体步骤\"\u003e具体步骤\u003c/h2\u003e\n\u003ch3 id=\"一初始设置\"\u003e一、初始设置\u003c/h3\u003e\n\u003cp\u003e在开始之前,\u003ccode\u003edocker-compose.yml\u003c/code\u003e 中设置比较关键的几个配置如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egitlab-web:\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\timage: \u003cspan class=\"s1\"\u003e\u0026#39;gitlab/gitlab-ce:latest\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\tcontainer_name: \u003cspan class=\"s1\"\u003e\u0026#39;gitlab\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\trestart: always\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\tenvironment:\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\tGITLAB_OMNIBUS_CONFIG: \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\tgitlab_rails\u003cspan class=\"o\"\u003e[\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;gitlab_shell_ssh_port\u0026#39;\u003c/span\u003e\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e4022\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\tports:\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t- \u003cspan class=\"s1\"\u003e\u0026#39;3090:80\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t- \u003cspan class=\"s1\"\u003e\u0026#39;4022:22\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t- \u003cspan class=\"s1\"\u003e\u0026#39;6060:6060\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\tvolumes:\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t- \u003cspan class=\"s1\"\u003e\u0026#39;/srv/gitlab/config:/etc/gitlab\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t- \u003cspan class=\"s1\"\u003e\u0026#39;/srv/gitlab/logs:/var/log/gitlab\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t- \u003cspan class=\"s1\"\u003e\u0026#39;/srv/gitlab/data:/var/opt/gitlab\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t- .... \u003cspan class=\"c1\"\u003e#一些其他的配置\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e如上设置基本可以确保 Gitlab 形如 \u003ccode\u003essh://git@git.xxxx.cn:4022/zs/zsblog.git\u003c/code\u003e 的链接可以使用。\u003c/p\u003e","title":"Docker-Gitlab 与主机共用 ssh 的 22 端口"},{"content":"前言 春节期间,走亲访友是必不可少的。交谈的多了,免不得一些问题的讨论。\n读了很多书,经历了很多事,似乎想法也有一些”离经叛道“,记一下自己目前的一些想法,不知道多年后的自己看这篇文章会是什么想法,还会一如既往的坚持吗。\n讨论的话题 打点关系 无论是父母,还是各方亲戚,大家好像都喜欢打点关系,以此来获得一些好处。\n最常见的是求人办事,很多时候是我们常说的”走后门“,想让孩子上个好点的小学,避免不了又送礼又吃饭。\n事件上升的恶劣一些,定然就是贪污受贿,这肯定是错的,大家都知道,但是度在哪里呢。\n和我儿时的哥哥探讨中,他认为,这种送礼打点关系是必要的,送点小礼没啥问题。而我总觉得,这就是0、1、无穷的区别,有一就有二,有二就有无穷。\n从出生到现在,试问自己从没遇到过必须送礼才能办成的事,或许以后会遇到,但我想、我应该宁愿放弃这个机会也不会去送礼打点。\n大家都对我说:“你现在是这个想法,是没有经历过社会的毒打,你踏入社会就也会这样了。”,我无言。\n或许吧,或许以后也会变成善于打点关系、整天辗转于酒局的人。\n至少我现在,还是个滴酒不沾、不屑于打点的鸟人。\n酒文化 我是个滴酒不沾的人\n有两点比较重要的原因\n一个是因为酒真的很难喝,好喝也就罢了,难喝为什么要喝呢?\n二是因为我真的很讨厌饭桌上推杯换盏,你推我我推你,大家都喝得烂醉如泥。村里有很多喝酒出事去世的例子,小时候看见一个哥哥的朋友,喝醉后在大街上和别人干架,然后在欢喜的日子里一起进医院···何必呢?\n推杯换盏还导致饭菜里会混入多多少少的酒,真的不好吃。\n大家为什么都不能别这么执拗,这里用执拗可能不合适,不过没想到什么好的词语。人家明明都说了不喝、不吃,为什么还总要一遍遍的推脱?最后立场不坚定的,只能不情愿地吃了。立场坚定的,又闹得双方不愉快似的。\n还有很多明明想喝、想吃,却又怕尴尬嘴上说着不喝不吃,一样可恶。\n硬唠 平时在家总喜欢窝在自己的屋子里,倒腾自己的事情。\n亲戚来了,似乎不出去跟他们聊天就是个错误。总是要数落你一下,在饭桌上调侃你一下,跟家长阴阳怪气一下你。\n不想说的是,真的感觉没有什么共同话题,聊不到一起去,实在是没什么话说,只能在那里低头玩手机,哦对了,手机也不得玩,玩多了也会被说。只能在那里干坐着东看西看,听大家侃大山,却因为离家过久大多事都没听说过,时间白白的浪费。\n人际关系真的蛮烦的。\n关于入党 最近舅家的哥哥萌生了入党的想法,说:”就算无论花多少钱,也得入党。“\n我问,那你入党又是为了做什么呢?\n他说,入党好啊,入党好啊,入党可以在村委里谋个一官半职,可以轻松一些,赚钱也多。\n我说你不应该为了自己的私利来入党,他说,人不为己天诛地灭,没有人不顾自己的私利。\n实话的讲,我哥哥是个不错的人,乐于与村里人交善,村民家里出什么事他也喜欢帮忙。但是这个入党的观念真的让我不理解,入党是应该认为认同,而不是因为利益驱使。\n大家入党好似都是为了后续能谋个公务员的出路,如果能贯彻为人民服务的宗旨还好,如果一心为了钱,很容易会变成蛀虫、老虎,那这样的话,不如踏踏实实另谋出路。\n后记 春节期间思考了很多,感觉与周围的很多亲戚们都格格不入。\n文章算是想到什么写什么,可能看起来杂乱无章,见谅。文章也只是我自己的一些看法,不代表普遍性,也无言对错,大家看看就好。\n还好的是,我的亲戚们大多不会问我,考的咋样,有对象了没……\n之前与一个舅家的哥哥很要好(与上文不是同一个),因为之前感觉我们两人观念很类似,亲戚们也都觉得我们两个像。\n这个春节与他进一步交流了一些,似乎观念不尽相同了。\n现在他步入社会,参加了工作,开始应付酒局,也会打点关系了。也开始教导我应该善于打点。\n我以后也会这样吗?\n","permalink":"https://blog.zzsqwq.cn/posts/224/","summary":"\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003e春节期间,走亲访友是必不可少的。交谈的多了,免不得一些问题的讨论。\u003c/p\u003e\n\u003cp\u003e读了很多书,经历了很多事,似乎想法也有一些”离经叛道“,记一下自己目前的一些想法,不知道多年后的自己看这篇文章会是什么想法,还会一如既往的坚持吗。\u003c/p\u003e\n\u003ch2 id=\"讨论的话题\"\u003e讨论的话题\u003c/h2\u003e\n\u003ch3 id=\"打点关系\"\u003e打点关系\u003c/h3\u003e\n\u003cp\u003e无论是父母,还是各方亲戚,大家好像都喜欢打点关系,以此来获得一些好处。\u003c/p\u003e\n\u003cp\u003e最常见的是求人办事,很多时候是我们常说的”走后门“,想让孩子上个好点的小学,避免不了又送礼又吃饭。\u003c/p\u003e\n\u003cp\u003e事件上升的恶劣一些,定然就是贪污受贿,这肯定是错的,大家都知道,但是度在哪里呢。\u003c/p\u003e\n\u003cp\u003e和我儿时的哥哥探讨中,他认为,这种送礼打点关系是必要的,送点小礼没啥问题。而我总觉得,这就是0、1、无穷的区别,有一就有二,有二就有无穷。\u003c/p\u003e\n\u003cp\u003e从出生到现在,试问自己从没遇到过必须送礼才能办成的事,或许以后会遇到,但我想、我应该宁愿放弃这个机会也不会去送礼打点。\u003c/p\u003e\n\u003cp\u003e大家都对我说:“你现在是这个想法,是没有经历过社会的毒打,你踏入社会就也会这样了。”,我无言。\u003c/p\u003e\n\u003cp\u003e或许吧,或许以后也会变成善于打点关系、整天辗转于酒局的人。\u003c/p\u003e\n\u003cp\u003e至少我现在,还是个滴酒不沾、不屑于打点的鸟人。\u003c/p\u003e\n\u003ch3 id=\"酒文化\"\u003e酒文化\u003c/h3\u003e\n\u003cblockquote\u003e\n\u003cp\u003e我是个滴酒不沾的人\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e有两点比较重要的原因\u003c/p\u003e\n\u003cp\u003e一个是因为酒真的很难喝,好喝也就罢了,难喝为什么要喝呢?\u003c/p\u003e\n\u003cp\u003e二是因为我真的很讨厌饭桌上推杯换盏,你推我我推你,大家都喝得烂醉如泥。村里有很多喝酒出事去世的例子,小时候看见一个哥哥的朋友,喝醉后在大街上和别人干架,然后在欢喜的日子里一起进医院···何必呢?\u003c/p\u003e\n\u003cp\u003e推杯换盏还导致饭菜里会混入多多少少的酒,真的不好吃。\u003c/p\u003e\n\u003cp\u003e大家为什么都不能别这么执拗,这里用执拗可能不合适,不过没想到什么好的词语。人家明明都说了不喝、不吃,为什么还总要一遍遍的推脱?最后立场不坚定的,只能不情愿地吃了。立场坚定的,又闹得双方不愉快似的。\u003c/p\u003e\n\u003cp\u003e还有很多明明想喝、想吃,却又怕尴尬嘴上说着不喝不吃,一样可恶。\u003c/p\u003e\n\u003ch3 id=\"硬唠\"\u003e硬唠\u003c/h3\u003e\n\u003cp\u003e平时在家总喜欢窝在自己的屋子里,倒腾自己的事情。\u003c/p\u003e\n\u003cp\u003e亲戚来了,似乎不出去跟他们聊天就是个错误。总是要数落你一下,在饭桌上调侃你一下,跟家长阴阳怪气一下你。\u003c/p\u003e\n\u003cp\u003e不想说的是,真的感觉没有什么共同话题,聊不到一起去,实在是没什么话说,只能在那里低头玩手机,哦对了,手机也不得玩,玩多了也会被说。只能在那里干坐着东看西看,听大家侃大山,却因为离家过久大多事都没听说过,时间白白的浪费。\u003c/p\u003e\n\u003cp\u003e人际关系真的蛮烦的。\u003c/p\u003e\n\u003ch3 id=\"关于入党\"\u003e关于入党\u003c/h3\u003e\n\u003cp\u003e最近舅家的哥哥萌生了入党的想法,说:”就算无论花多少钱,也得入党。“\u003c/p\u003e\n\u003cp\u003e我问,那你入党又是为了做什么呢?\u003c/p\u003e\n\u003cp\u003e他说,入党好啊,入党好啊,入党可以在村委里谋个一官半职,可以轻松一些,赚钱也多。\u003c/p\u003e\n\u003cp\u003e我说你不应该为了自己的私利来入党,他说,人不为己天诛地灭,没有人不顾自己的私利。\u003c/p\u003e\n\u003cp\u003e实话的讲,我哥哥是个不错的人,乐于与村里人交善,村民家里出什么事他也喜欢帮忙。但是这个入党的观念真的让我不理解,入党是应该认为认同,而不是因为利益驱使。\u003c/p\u003e\n\u003cp\u003e大家入党好似都是为了后续能谋个公务员的出路,如果能贯彻为人民服务的宗旨还好,如果一心为了钱,很容易会变成蛀虫、老虎,那这样的话,不如踏踏实实另谋出路。\u003c/p\u003e\n\u003ch2 id=\"后记\"\u003e后记\u003c/h2\u003e\n\u003cp\u003e春节期间思考了很多,感觉与周围的很多亲戚们都格格不入。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e文章算是想到什么写什么,可能看起来杂乱无章,见谅。文章也只是我自己的一些看法,不代表普遍性,也无言对错,大家看看就好。\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e还好的是,我的亲戚们大多不会问我,考的咋样,有对象了没……\u003c/p\u003e\n\u003cp\u003e之前与一个舅家的哥哥很要好(与上文不是同一个),因为之前感觉我们两人观念很类似,亲戚们也都觉得我们两个像。\u003c/p\u003e\n\u003cp\u003e这个春节与他进一步交流了一些,似乎观念不尽相同了。\u003c/p\u003e\n\u003cp\u003e现在他步入社会,参加了工作,开始应付酒局,也会打点关系了。也开始教导我应该善于打点。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e我以后也会这样吗?\u003c/strong\u003e\u003c/p\u003e","title":"关于春节期间的一些碎碎念"},{"content":"前言 最近看了一些 js 有关的知识,其中令我这种初学者感到很头疼的一个问题就是异步问题。\n今天就我碰到的一个小问题详解一个关于异步的小技巧。\n背景 我在程序中需要鉴权,来判断一个用户是普通用户还是管理员,针对不同的用户渲染不同的页面。\n每个用户具有唯一的 ID,因此我只需要将管理员的 ID 放到数据库,然后加载程序的时候一一比对即可。\n但是我的主程序初始化与页面的初始化是异步的,管理员的判断逻辑我放在了主程序初始化中,这也就意味着很可能我页面在加载时,主程序还没有判断完用户的身份。\n每个人默认不是管理员,因此这就会导致一个问题——管理员可能也会显示成普通用户的页面,因为渲染页面的时候程序还不知道这个用户是管理员。\n方案 这个方案其实是我从官方的代码上学到的,其实就结合代码给大家讲一下。\n官方这里是在获取用户的 userInfo 时用到的。\n主程序初始化部分代码:\n这里主程序的逻辑就是在 getSetting 调用成功后,判断是否已经获得过 userInfo ,如果已经获得过,则可以直接调用 getUserInfo 函数获取值,赋值成一个主程序的全局变量,所有页面都可以用。\n接下来就是一个比较奇怪的点了\n可以看到官方的注释为\n由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回\n所以此处加入 callback 以防止这种情况\n这里判断了主程序内是否含有 userInfoReadyCallback 这个函数,如果有的话就执行。\nqq.getSetting({ success: res =\u0026gt; { if (res.authSetting[\u0026#39;scope.userInfo\u0026#39;]) { // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框 qq.getUserInfo({ success: res =\u0026gt; { // 可以将 res 发送给后台解码出 unionId this.globalData.userInfo = res.userInfo // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 if (this.userInfoReadyCallback) { this.userInfoReadyCallback(res) } } }) } } }) 页面初始化部分代码:\n页面初始化部分的逻辑首先判断全局变量中是否包含 userInfo 这个这个变量,我们从上文得知,如果我们在此段程序执行前主程序已经执行完毕,那么这里是包含 userInfo 这个函数的,我们直接赋值给当前的环境变量。\n而如果没有 userInfo 没有定义,也就是主程序还未完成变量的初始化,这就出现了我们之前提到的问题,页面加载时主程序未初始化完。\n定义了 userInfoReadyCallback 函数,接受 res 参数,进行赋值。\nif (app.globalData.userInfo) { this.setData({ userInfo: app.globalData.userInfo, hasUserInfo: true }) } else if (this.data.canIUse) { // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 app.userInfoReadyCallback = res =\u0026gt; { this.setData({ userInfo: res.userInfo, hasUserInfo: true }) } } else { //...... 读完上面的程序大家应该已经可以搞懂了,其实类似于设置了两个标志(flag)。\n一个标志是全局变量 userInfo、一个是全局函数 userInfoReadyCallback 。\n如果 userInfo 已经定义,说明页面初始化前页面主程序变量已初始化完毕,渲染不会出问题。\n而如果 userInfo 未定义,说明与上面相反,则在页面中定义userInfoReadyCallback 函数,后续主程序初始化到最后得知该函数已定义,则调用其来进行初始化。\n这样就总能够保证局部 userInfo 这个变量的取值总是正确的,也即页面总是渲染正确的!\n后记 这个问题应该总是可以解决两个页面同时加载但却存在变量依赖的问题。\n大家如果有什么更加优秀的解决方案也希望不吝赐教。\n","permalink":"https://blog.zzsqwq.cn/posts/223/","summary":"\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003e最近看了一些 js 有关的知识,其中令我这种初学者感到很头疼的一个问题就是异步问题。\u003c/p\u003e\n\u003cp\u003e今天就我碰到的一个小问题详解一个关于异步的小技巧。\u003c/p\u003e\n\u003ch2 id=\"背景\"\u003e背景\u003c/h2\u003e\n\u003cp\u003e我在程序中需要鉴权,来判断一个用户是\u003cstrong\u003e普通用户\u003c/strong\u003e还是\u003cstrong\u003e管理员\u003c/strong\u003e,针对不同的用户渲染不同的页面。\u003c/p\u003e\n\u003cp\u003e每个用户具有唯一的 ID,因此我只需要将管理员的 ID 放到数据库,然后加载程序的时候一一比对即可。\u003c/p\u003e\n\u003cp\u003e但是我的主程序初始化与页面的初始化是异步的,管理员的判断逻辑我放在了主程序初始化中,这也就意味着很可能我页面在加载时,主程序还没有判断完用户的身份。\u003c/p\u003e\n\u003cp\u003e每个人默认不是管理员,因此这就会导致一个问题——\u003cstrong\u003e管理员可能也会显示成普通用户的页面\u003c/strong\u003e,因为渲染页面的时候程序还不知道这个用户是管理员。\u003c/p\u003e\n\u003ch2 id=\"方案\"\u003e方案\u003c/h2\u003e\n\u003cp\u003e这个方案其实是我从官方的代码上学到的,其实就结合代码给大家讲一下。\u003c/p\u003e\n\u003cp\u003e官方这里是在获取用户的 userInfo 时用到的。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e主程序初始化部分代码\u003c/strong\u003e:\u003c/p\u003e\n\u003cp\u003e这里主程序的逻辑就是在 \u003ccode\u003egetSetting\u003c/code\u003e 调用成功后,判断是否已经获得过 userInfo ,如果已经获得过,则可以直接调用 \u003ccode\u003egetUserInfo\u003c/code\u003e 函数获取值,赋值成一个主程序的全局变量,所有页面都可以用。\u003c/p\u003e\n\u003cp\u003e接下来就是一个比较奇怪的点了\u003c/p\u003e\n\u003cp\u003e可以看到官方的注释为\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回\u003c/p\u003e\n\u003cp\u003e所以此处加入 callback 以防止这种情况\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e这里判断了主程序内是否含有 \u003ccode\u003euserInfoReadyCallback\u003c/code\u003e 这个函数,如果有的话就执行。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003eqq\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003egetSetting\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003esuccess\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"nx\"\u003eres\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eres\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eauthSetting\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;scope.userInfo\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e])\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003eqq\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003egetUserInfo\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003esuccess\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"nx\"\u003eres\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 可以将 res 发送给后台解码出 unionId\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003ethis\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eglobalData\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003euserInfo\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eres\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003euserInfo\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 所以此处加入 callback 以防止这种情况\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ethis\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003euserInfoReadyCallback\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ethis\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003euserInfoReadyCallback\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eres\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e\u003cstrong\u003e页面初始化部分代码:\u003c/strong\u003e\u003c/p\u003e","title":"一个 Javascript 中异步的小技巧"},{"content":"前言 更换博客系统的想法已经萌生很久了,一个是感觉 Handsome 这个主题有点看腻了,但是在 Typecho 中好似已经没有更好的博客主题可选择了。\n有一个看起来貌似很不错,主题名叫 maupassant。效果如下图所示,顺附链接\npagecho/maupassant(github.com)\n不过一直没有下定决心更换,后来也尝试过使用 WordPress,又觉得 WordPress 体量有点太大了。\n每天逛 Github 的时候看到了很多很不错的静态博客主题,那天看到一个学长分析学校校园网的博客,第一眼就感觉很不错,找寻了一下发现博客基于 Hugo,主题是 hugo-PaperMod。\n于是顺着寻找了一下,发现 Hugo 中很多博客主题非常的不错。此外,Hugo 相比于 Hexo 也有很多优点:博客构建速度快,基于模板的概念组织内容,环境配置容易,在 Ubuntu 下一行命令即可,而 Hexo 依赖于 Node.js,体量稍微有点大。\n于是决定把博客迁移到 Hugo,并且采用主题 Coder 。\n过程 Typecho 文章导出 这里采用了 lizheming 大大的迁移插件:lizheming/typecho-export-hugo\n具体导出为 zip 的时候可能会提示损坏,这样的话可以直接去服务器 \\tmp\\Export2Hugo 下面打包。\n安装 hugo 过程基于 Windows 平台,很简单,在 这里 下载 hugo 最新的 release 版本,找到对应自己系统的即可。下载后解压到某个目录下,设置一下环境变量即可。这里牵扯到 hugo 和 hugo_extended 两个版本的区别,以下是某个 issue 中的解释:\nI agree.\nThe only functional difference is SASS/SCSS The technical build time difference is that it requires a C++ build chain for the target platform to build, the reason why we currently only build the extended for 3 platforms (Windows, Linux, MacOS) Binaries are slightly less portable as you need a compatible Libc version on your computer (for Windows we build a fully static version as Libc is rather uncommon unless you have Visual Studio or something installed). via: Please document the difference between the \u0026ldquo;extended\u0026rdquo; and non-\u0026ldquo;extended\u0026rdquo; versions\n我认为,直接使用 extended 版本就完事了。使用了 extended 不会报错,而不用 extended 版本可能会报错。\n构建网站 首先在合适的目录下生成一个新的网站\n$ hugo new site zsblog 然后进入目录后,初始化一个 git 仓库\n$ git init [可选]将自己心仪的目录设置为 git 的 submodule ,需要注意的是,hugo 中的主题配置多是基于 submodule 的,这种方式很灵活,也便于更新,当然,需要先学习一下 submodule 的用法:) ,这里以 coder 主题为例:\n$ git submodule add https://github.com/luizdepra/hugo-coder.git themes/hugo-coder 然后基于对应主题的 exampleSite 来设定对应的配置文件 config.toml,这里很蛋疼的是 coder 主题居然偏爱 toml 配置格式,为什么不是 yaml/json 呢?\n补充:hugo 支持三种格式的配置文件 yaml, toml, json.\n然后启动博客即可\n$ hugo server 这里很有意思的是,启动多个 server 不会冲突,hugo 会选择另外一个端口部署。同时,启动 server 不会显式生成静态文件。\n最后就是上传到 Github,然后可以选用 Github Pages 进行部署,注意 Baseurl 的设定。\n利用 Github Actions 进行持续部署 我这里采用的是将我的博客部署到我的服务器,使用 Github Actions 进行 CI/CD。\n使用了 actions/checkout@v2、peaceiris/actions-hugo@v2、peaceiris/actions-gh-pages、burnett01/rsync-deployments@5.1 这几个模板,向大佬表示感谢!\n其中有一个很坑的地方是之前用的 rsync 模板是 contention/rsync-deployments,不知道是为啥···我用这个的时候,只要使用 --exclude 参数他就犯病,显示成功但是却没有上传到云端服务器,搁那里 debug 了半天发现是插件好像有点 bug ?有点麻了..\n具体的配置文件如下:\nname: Zs-Hugo-Blog on: push: branches: - master # Set a branch to deploy pull_request: jobs: deploy: runs-on: ubuntu-20.04 concurrency: group: ${{ github.workflow }}-${{ github.ref }} steps: - uses: actions/checkout@v2 with: submodules: true # Fetch Hugo themes (true OR recursive) fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod - name: Setup Hugo uses: peaceiris/actions-hugo@v2 with: hugo-version: \u0026#39;latest\u0026#39; extended: true - name: Build run: hugo --minify - name: Deploy uses: peaceiris/actions-gh-pages@v3 if: ${{ github.ref == \u0026#39;refs/heads/master\u0026#39; }} with: github_token: ${{ secrets.HUGO_DEPLOY }} publish_dir: ./public - uses: actions/checkout@v2 with: ref: \u0026#39;gh-pages\u0026#39; - name: rsync deployments uses: burnett01/rsync-deployments@5.1 with: switches: -avzr --delete --exclude=\u0026#34;.htaccess\u0026#34; --exclude=\u0026#34;/usr/\u0026#34; path: ./ remote_path: /www/wwwroot/new_blog/ remote_host: zzsqwq.cn remote_user: www remote_key: ${{ secrets.SSH_KEY }} 一些其他配置 再者我还配置了 Google analytics,hugo 对 Google analytics 的支持很不错,点击 这里 查看详情。\n此外还有配置了基于 Utterances 的评论系统,起初想要尝试使用 Commento 的,自己搭建了个服务,搞了半天也没搞好,无法在我的网站正常加载,最后还是采用了 Utterances,几分钟就搞好了,可恶。\n同时,为了保持原先博客的链接活性,我将原博客部署到了 https://lastblog.zzsqwq.cn ,在 Apache 中将原博客链接全部重定向到当前网站,这样就不会产生死链了,配置如下:\n#rewrite RewriteEngine On RewriteRule ^/?index.php/(.*)$ https://lastblog.zzsqwq.cn/index.php/$1 [R,L] 后记 其中还有一些 RSS 的配置、评论系统宽度的修改等一些小问题,就不细说了。\n有个比较蛋疼的问题就是目前 Utterances 评论系统的配色不能随着博客亮暗的切换改变,后续计划改善一下\n同时,为了保持主题的可配置性,我 fork 了一份主题,并且针对做了一些修改,仓库地址:zzsqwq/hugo-coder\n","permalink":"https://blog.zzsqwq.cn/posts/221/","summary":"\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003e更换博客系统的想法已经萌生很久了,一个是感觉 Handsome 这个主题有点看腻了,但是在 Typecho 中好似已经没有更好的博客主题可选择了。\u003c/p\u003e\n\u003cp\u003e有一个看起来貌似很不错,主题名叫 maupassant。效果如下图所示,顺附链接\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/pagecho/maupassant\"\u003epagecho/maupassant(github.com)\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"https://camo.githubusercontent.com/6f925dcec164e50cad950577db00910d3821d388e3f018d4b7d900cc2ce081c0/68747470733a2f2f6464796465672e6279333330322e6c69766566696c6573746f72652e636f6d2f793270315a67484552346549466145486877616639364d765a48345f694c75664549446a376f38616344674931475846447450492d65524167766f6b466f52396972627a373338674d6d57635f4e3779657847367568423144636d656c623063586738486578706941645a3548512f6d2e706e67\" alt=\"maupassant\" /\u003e\n\u003c/p\u003e\n\u003cp\u003e不过一直没有下定决心更换,后来也尝试过使用 WordPress,又觉得 WordPress 体量有点太大了。\u003c/p\u003e\n\u003cp\u003e每天逛 Github 的时候看到了很多很不错的静态博客主题,那天看到一个学长\u003ca href=\"https://zincnode.com/posts/campusnetwork/\"\u003e分析学校校园网的博客\u003c/a\u003e,第一眼就感觉很不错,找寻了一下发现博客基于 \u003ca href=\"https://gohugo.io/\"\u003eHugo\u003c/a\u003e,主题是 \u003ca href=\"https://github.com/adityatelange/hugo-PaperMod\"\u003ehugo-PaperMod\u003c/a\u003e。\u003c/p\u003e\n\u003cp\u003e于是顺着寻找了一下,发现 Hugo 中很多博客主题非常的不错。此外,Hugo 相比于 Hexo 也有很多优点:博客构建速度快,基于模板的概念组织内容,环境配置容易,在 Ubuntu 下一行命令即可,而 Hexo 依赖于 Node.js,体量稍微有点大。\u003c/p\u003e\n\u003cp\u003e于是决定把博客迁移到 Hugo,并且采用主题 \u003ca href=\"https://github.com/luizdepra/hugo-coder\"\u003eCoder\u003c/a\u003e 。\u003c/p\u003e\n\u003ch2 id=\"过程\"\u003e过程\u003c/h2\u003e\n\u003ch3 id=\"typecho-文章导出\"\u003eTypecho 文章导出\u003c/h3\u003e\n\u003cp\u003e这里采用了 lizheming 大大的迁移插件:\u003ca href=\"https://github.com/lizheming/typecho-export-hugo\"\u003elizheming/typecho-export-hugo\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e具体导出为 zip 的时候可能会提示损坏,这样的话可以直接去服务器 \u003ccode\u003e\\tmp\\Export2Hugo\u003c/code\u003e 下面打包。\u003c/strong\u003e\u003c/p\u003e\n\u003ch3 id=\"安装-hugo\"\u003e安装 hugo\u003c/h3\u003e\n\u003cp\u003e过程基于 Windows 平台,很简单,在 \u003ca href=\"https://github.com/gohugoio/hugo/releases/tag/v0.90.1\"\u003e这里\u003c/a\u003e 下载 hugo 最新的 release 版本,找到对应自己系统的即可。下载后解压到某个目录下,设置一下环境变量即可。这里牵扯到 hugo 和 hugo_extended 两个版本的区别,以下是某个 issue 中的解释:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eI agree.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eThe only functional difference is SASS/SCSS\u003c/li\u003e\n\u003cli\u003eThe technical build time difference is that it requires a C++ build chain for the target platform to build, the reason why we currently only build the extended for 3 platforms (Windows, Linux, MacOS)\u003c/li\u003e\n\u003cli\u003eBinaries are slightly less portable as you need a compatible Libc version on your computer (for Windows we build a fully static version as Libc is rather uncommon unless you have Visual Studio or something installed).\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003evia: \u003ca href=\"https://github.com/gohugoio/hugoDocs/issues/1152\"\u003ePlease document the difference between the \u0026ldquo;extended\u0026rdquo; and non-\u0026ldquo;extended\u0026rdquo; versions\u003c/a\u003e\u003c/p\u003e","title":"记一次博客迁移记录"},{"content":"前言 近期著名 Markdown 编辑器 Typora 宣布收费了,起初感觉很难受,后来感慨之余也觉得算是合理,毕竟 Typora 用起来感觉是真的很良心,也在考虑是否买一份支持一下。\n已于2021/12/10购入,还是选择回归了 Typora 了哈哈哈\n虽说左右分屏的设计可能更符合 Markdown 的初衷,但是像 Typora 这种所见即所得(WYSIWYG) 的书写体验确实是感觉习惯了就回不去了。\n因此近期也搜集了 Markdown 编辑器作为 Typora 的替代品,在这里给大家分享一下。\n特别声明,下面的分享多是我日常体验中的一些感受,可能不够客观,比较片面,大家可以自己使用体验一下!\n一、Obsidian 界面预览 特点 具有文档的双向链接\n支持行级和块级公式\n官网可以购买 sync 套餐保持各个客户端同步\n可以购买 publish 服务将 markdown 发布为排版美观的界面\n有丰富的插件,例如日历、待办清单、Git同步等等。\n有Linux,Windows,iPad等多平台支持。\n使用体验 Obsidian 中文为黑曜石。我觉得它的图标很好看。\n在我使用的一段时间内,他给我的感觉是,功能十分丰富的一个 Markdown 文件管理工具。如果你购买了他的同步服务,那你可以很轻松的在各平台同步你的 Markdown 文件夹,并且基于他强大的插件,可以很完成很多 Markdown 文件份外的事,例如待办清单、日历等等。\n他虽没有所见即所得的模式,但是依靠其一款第三方插件,可以达成类似的效果,不过还是用起来不如 Typora 这种顺手。同时,它的各端同步如果不开启官方的服务,用起来还是挺麻烦的,经过我的一阵倒腾,我总结了如下几个方案:\n使用第三方Git管理插件,可以定时推送文件夹中的内容到仓库,这样可以完成 linux 与 Windwos 平台的同步,只需要在某一方推送某一方拉取即可。而 Windows 平台与 iPad 平台的同步,可以借助 Apple 的 iCloud,Windows上有对应的客户端,这也是 Obsidian 官方支持的。不过在我使用的过程中我发现,这样异常的麻烦,使用 Git 来管理很可能会产生冲突,导致需要手动处理冲突,久而久之就会觉得很烦。\n使用自建云盘如 NextCloud + Obsidian,或者 Seafile + Obsidian。 这个是我觉得目前非常可行的一个方案,最近我也有在尝试 NextCloud,它的多端同步做的非常不错,依靠此可以在各个平台同步文件夹,加上 Obsidian 强悍的能力,是不错的组合!\n二、Mark Text 界面预览 特点 开源!!\n所见即所得(WYSIWYG)\n支持行级和块级公式\n界面简洁且美观\nWindows,Linux 等多平台支持,不支持 iPad\n缺点:目前仍不支持中文\n使用体验 Mark Text 是 Github 上一个开源的项目\n个人认为他是在对标 Typora 的一个软件,有着和 Typora 非常相近的写作手感,并且界面简洁美观,我个人真的是非常喜欢,也是我目前在用的一款编辑器,本篇文章就是使用此编辑器书写。\n它的可配置程度虽然没有 Typora 那么高,但是平常的使用已经足够。不过值得说道的是,他不支持导出 Word 文档,而且对用公式的补全做的不够完美。\n可能还是有一些 bug 的,软件的最后一次 release 还是在 2020 年了(说明非常的稳定啊哈哈)。不过贵在他是个开源的软件,有很多大佬愿意为之奉献,期待后续的更新!\n三、Zettlr 界面预览 特点 开源!!\n可导出的格式非常的多,如 Latex、Word 等都可以。\n可以说是所见即所得,不过和 Typora 的理念略有不同。\n支持 Windows、Linux 等平台。\n支持语言的种类要比 Mark Text 多很多。\n缺点:自认为界面没有 Mark Text 和 Typora 这种好看。\n使用体验 上面的有个特点我描述的是 “可以说是所见即所得,不过和 Typora 的理念略有不同”\n我感觉它的所见即所得不是纯正的所见即所得,还是会保留部分源代码的元素在上面。不过他支持导出的格式要比 Mark Text 多不少。\n同时他也支持任务清单这种小功能,但是我认为它没有 Mark Text 美观和好用。使用的也不算太多,就不过多的评价了~\n四、VSCode + 插件 界面预览 特点 基于 VSCode 这个宇宙第一编辑器,不需要装别的软件\n可选的插件很多,不差这个一个\n多是基于 vditor,对 vditor 有钟爱的同学不要错过!\n所见即所得\n使用体验 因为我自己没有深度体验这个东西,但是我认为功能还是很强大的~\n虽然说,他可能没有一个单独的软件配置项那么多,但是贵在他只是一个集成于 VSCode 的插件,不要安装一个那么大体量的软件。\n同时可以很快的在代码与文档之间切换,这应该也算是一个优势了。\n后记 本来想把这个博文做成一个各类软件推荐文的,但是写着写着发现光是 Markdown 类的已经可以写很多了,为了防止篇幅过长,就单做一个 Markdown 编辑器的推荐文吧~\n如果大家有更好的 Markdown 编辑器推荐,欢迎在下面留言!\n","permalink":"https://blog.zzsqwq.cn/posts/220/","summary":"\u003ch1 id=\"前言\"\u003e前言\u003c/h1\u003e\n\u003cp\u003e近期著名 Markdown 编辑器 \u003ca href=\"https://typora.io/\"\u003eTypora\u003c/a\u003e 宣布收费了,起初感觉很难受,后来感慨之余也觉得算是合理,毕竟 Typora 用起来感觉是真的很良心,也在考虑是否买一份支持一下。\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e已于2021/12/10购入,还是选择回归了 Typora 了哈哈哈\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e虽说左右分屏的设计可能更符合 Markdown 的初衷,但是像 Typora 这种所见即所得(WYSIWYG) 的书写体验确实是感觉习惯了就回不去了。\u003c/p\u003e\n\u003cp\u003e因此近期也搜集了 Markdown 编辑器作为 Typora 的替代品,在这里给大家分享一下。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e特别声明,下面的分享多是我日常体验中的一些感受,可能不够客观,比较片面,大家可以自己使用体验一下!\u003c/strong\u003e\u003c/p\u003e\n\u003ch1 id=\"一obsidian\"\u003e一、Obsidian\u003c/h1\u003e\n\u003ch2 id=\"界面预览\"\u003e界面预览\u003c/h2\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"https://blog.zzsqwq.cn/usr/uploads/2021/12/1150718291.png\" alt=\"Obsidian\" /\u003e\n\u003c/p\u003e\n\u003ch2 id=\"特点\"\u003e特点\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e具有文档的双向链接\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e支持行级和块级公式\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e官网可以购买 \u003ca href=\"https://obsidian.md/sync\"\u003esync\u003c/a\u003e 套餐保持各个客户端同步\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e可以购买 \u003ca href=\"https://obsidian.md/publish\"\u003epublish\u003c/a\u003e 服务将 markdown 发布为排版美观的界面\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e有丰富的插件\u003c/strong\u003e,例如日历、待办清单、Git同步等等。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e有Linux,Windows,\u003cstrong\u003eiPad\u003c/strong\u003e等多平台支持。\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"使用体验\"\u003e使用体验\u003c/h2\u003e\n\u003cp\u003e\u003ca href=\"https://obsidian.md/\"\u003eObsidian\u003c/a\u003e 中文为黑曜石。我觉得它的图标很好看。\u003c/p\u003e\n\u003cp\u003e在我使用的一段时间内,他给我的感觉是,功能十分丰富的一个 Markdown 文件管理工具。如果你购买了他的同步服务,那你可以很轻松的在各平台同步你的 Markdown 文件夹,并且基于他强大的插件,可以很完成很多 Markdown 文件份外的事,例如待办清单、日历等等。\u003c/p\u003e\n\u003cp\u003e他虽没有所见即所得的模式,但是依靠其一款第三方插件,可以达成类似的效果,不过还是用起来不如 Typora 这种顺手。同时,\u003cstrong\u003e它的各端同步如果不开启官方的服务,用起来还是挺麻烦的\u003c/strong\u003e,经过我的一阵倒腾,我总结了如下几个方案:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e使用第三方Git管理插件,可以定时推送文件夹中的内容到仓库,这样可以完成 linux 与 Windwos 平台的同步,只需要在某一方推送某一方拉取即可。而 Windows 平台与 iPad 平台的同步,可以借助 Apple 的 iCloud,Windows上有对应的客户端,这也是 Obsidian 官方支持的。不过在我使用的过程中我发现,这样异常的麻烦,使用 Git 来管理很可能会产生冲突,导致需要手动处理冲突,久而久之就会觉得很烦。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e使用自建云盘如 \u003cstrong\u003eNextCloud + Obsidian\u003c/strong\u003e,或者 Seafile + Obsidian。 这个是我觉得目前非常可行的一个方案,最近我也有在尝试 NextCloud,它的多端同步做的非常不错,依靠此可以在各个平台同步文件夹,加上 Obsidian 强悍的能力,是不错的组合!\u003c/p\u003e","title":"Markdown 编辑器推荐"},{"content":"2021版小新Pro14 Ubuntu 20.04 配置指南 补充 最近重装了 Ubuntu 20.04,又找了相关的一些帖子,发现 聯想Yoga 14s 2021款裝機小記 中提到了下文中提到的屏幕闪烁的问题,解决办法是:只需要在内核参数中加入 i915.enable_psr=0 即可。\n具体操作步骤如下:\n$ sudo vim /etc/default/grub 在 GRUB_CMDLINE_LINUX_DEFAULT 这一行的最后添加 i915.enable_psr=0,保存后终端运行:\n$ sudo update-grub 然后重启即可。\n前言 苦于沉重游戏本的迫害,新买了一台小新Pro14 2021款,上手感觉还挺不错的。如下是配置:\nCPU:酷睿 i5-11300H 显卡:集成显卡 Intel 锐炬Iris Xe 内存:16G 外存:512 SSD 屏幕:分辨率 2880x1800、400nits、100%sRGB 这里需要注意的是,不同时间出的小新Pro14配置是不太一样的,所以我这里列了一下配置。主要区别在于有一部分是2.2K分辨率+MX450显卡,而我这个是2.8K分辨率+锐炬Iris Xe显卡。\n为了工作的需要,要装一个Ubuntu,先是装了之前用过的 Ubuntu 18.04,安装后发现触摸板无法使用,一系列探索后无果,在朋友的推荐下,还是决定安装 Ubuntu 20.04 试一下,踩了一些坑,在这里记录一下。\n问题列表 如果你遇到了以下问题,那么这篇文章的方法可能会对你有益处:\nUbuntu 18.04 相关 Ubuntu 18.04 无法使用触摸板 Ubuntu 18.04 无法使用内置键盘 Ubuntu 18.04 无法调节亮 Ubuntu 18.04 查看GPU发现是llvm,而不是Iris Xe Ubuntu 20.04 相关 Ubuntu 20.04 进入后屏幕花屏、黑屏 Ubuntu 20.04 查看GPU发现是llvm,而不是Iris Xe 现在达成的效果 Ubuntu 20.04 能够正常使用,触摸板以及外界屏幕,亮度调节均无问题。\n开机时也能够使用键盘。\n但是开机登录界面还是存在花屏、闪屏的问题,我通过自动登录解决。BIOS界面仍旧会闪屏。\n安装 Ubuntu 18.04 的问题 首先安装Ubuntu 18.04 还是比较顺利,没有什么坑。\n安装的话就是按流程来一遍——压缩卷、进入BIOS关闭安全启动模式(这里网上有部分同学说也需要关闭 Intel Platform Trust Technology 、但是我不关闭也是可以的)、然后Try Ubuntu看一下效果(这里Try Ubuntu我没法使用鼠标,不过安装的时候可以)、开始安装。\n安装过程一般没啥问题,进入系统后我们就会发现一些问题,首先是你的**触摸板用不了,然后键盘也用不了。**再就是屏幕没法调节亮度(这个是小问题我觉得,好像也可以通过安装插件解决,大家可以自行搜索。)\n经过查询资料,这里有同学已经提出很好的解决方案:https://zhuanlan.zhihu.com/p/322377515\n简而言之,键盘用不了需要在 grub 启动项中加入 i8042.dumbkbd 参数,然后运行\nsudo update-grub2 即可在每次启动后保证键盘可用。\n关于没法使用触摸板和调节亮度,办法就是升级内核,据说是内核升级到5.9.8以上可用,Ubuntu 18.04内置版本是5.4.0.84好像是,但是我在更新后会花屏、黑屏等来回鬼畜,试了好多四五个内核依旧不管用,我猜想是因为我是2.8K的屏幕而网上的教程多是基于2.2K屏幕的,锐炬显卡对于高分辨率的屏幕支持并没有那么优秀。\n于是一直被这个问题折磨,搜了很多的教程也没有解决办法,最后决定换Ubuntu 20.04 尝试一下,之前一直觉得系统版本是个不可逾越的鸿沟,但是随着实践的越来越多,发现很多版本不兼容的问题都是有可解决办法的,因此也下定决心尝试一下未曾试过的 20.04。\n安装Ubuntu 20.04 的问题 首先是关于安装的问题\n在安装Ubuntu 18.04 的时候只有四个选项,应该是一个 Try Ubuntu、一个直接安装,一个高级模式,一个进BIOS\n而安装Ubuntu 20.04 的时候却有五个选项,分别是Ubuntu、Ubuntu(safe graphics)、OEM install(for manufacturers)、还有就是一个是高级模式、一个是进BIOS\n说一下三个安装方式的区别\n第一个模式与第二个模式的区别就是,第二个模式对于grub启动项目中添加了一个 nomodeset 选项,那么这个选项是做什么的?以下是他的解释:\nThe newest kernels have moved the video mode setting into the kernel. So all the programming of the hardware specific clock rates and registers on the video card happen in the kernel rather than in the X driver when the X server starts.. This makes it possible to have high resolution nice looking splash (boot) screens and flicker free transitions from boot splash to login screen. Unfortunately, on some cards this doesn’t work properly and you end up with a black screen. Adding the nomodeset parameter instructs the kernel to not load video drivers and use BIOS modes instead until X is loaded.\n大概意思是在最新的内核中,已经能够在BIOS引导阶段启用显卡,这样做的目的是很好的适应高分辨率屏,但是很遗憾的是某些显卡并不能很好的适配,通过 nomodeset 参数可以防止以不支持的显卡驱动视频流。\n很遗憾,锐炬显卡刚好没有被适配,所以选第一个选项(Ubuntu)来安装也会屏幕一闪一闪的,因此我们安装选择Ubuntu(safe graphics)选项来进行安装然后流程是一样的,蛮顺利。\n这里装完就没有触摸板的问题,屏幕亮度调节也没有问题。不过键盘依旧有问题,可以根据上面描述进行更改。\n然后更鬼畜的问题来了,只要这么一搞,从BIOS引导阶段开始,就会一直闪屏,尤其是输入密码进行登录的时候,会卡个好长时间,几乎无法使用,不过很有意思的是,只要外接屏幕,外接的屏幕显示不会有问题。\n因此求助于搜索引擎,因为怀疑是显卡的问题,所以搜索了关键词 Ubuntu Iris Xe,找到了以下两个比较有用的答案:\nStackOverflow:Ubuntu 20.04 no driver loaded for Intel Iris Xe Graphics\nIntel:Intel Iris Xe MAX Graphics with Linux\n这两个帖子都说了一个问题吧,就是如何在 Ubuntu 20.04 上更好的使用锐炬显卡\n这个问题实质解决的是没有在Ubuntu 20.04 上启动起来显卡,所以你会在你的 Ubuntu-\u0026gt;Settings-\u0026gt;About 页面看到的是 llvm 有关的字眼,而不是上面我截图所示的 Mesa Intel® Xe Graphics (TGL GT2)。\n解决这个问题比较关键的步骤是\nsudo apt update sudo apt install linux-oem-20.04 sudo reboot 这样开机再启动应该就会正常启动显卡了,这个方式在Ubuntu18.04是否奏效我没有实验过,可能可以安装对应的 linux-oem-18.04 包。\n在 Intel 官方的教程中,还添加了 grub 启动项等,我并没有发现他们的实际作用,在他后续的测试中我也没有达到期待的效果,因此没有继续尝试,如果有同学跟着文档做成功了,可以一起来讨论一下。\n但是!!!\n安装完成后,我还是会花屏和黑屏,问题依旧没有解决。我突发奇想,考虑到我外接屏幕没有问题,而自带的屏幕有问题,**因为外接屏是 1920x1080 而内置屏幕是 2880x1800,我联想到会不会是高分辨率屏幕的问题,所以尝试着把外接屏的显示比例调成了 150%(需要开启 Fractional Scaling),没想到歪打正着,居然好了,看起来也更加的顺眼,比例也更加协调。**具体的内部原因还不是很清楚。 已解决,见本文开头。\n但是还是有一个小瑕疵,就是在BIOS引导阶段与输入密码登录的界面,我仍旧是会花屏、闪屏,我考虑到这是还没有初始化屏幕设置的问题,尝试搜索了修改BIOS比例、提前初始化login界面的分辨率,依旧没有找到比较好的解决办法,\n因此最后只好启动自动登录来跳过登录界面,这样就看上去算是一个完好的系统了QAQ。。\n这里给出一些可能有价值的资料,大家可以自行查阅\nHow to change the login screen resolution in Ubuntu 18.04\nCustom Resolution Ubuntu 20.04\nHow can I change the resolution of the GRUB menu?\n根据上述第三个教程,我修改了 GRUB 的显示分辨率为 1920x1080,还是会闪屏。\n如果有大佬有想法或者解决了,欢迎留言一起探讨。\n后记与感想 折腾了一下午加一晚上,终于把系统整的能用了,不过又要重新配置各种软件,还是挺麻烦的。\n不过尝试新鲜事物、好比Windows11、最新款的电脑,还是挺高血压的,需要应付各种Bug,这可能也是一种平衡?hhhh,想要尝试新的事物、走在前沿、就必须要有付出。\n此外,发现查英文的资料要比中文靠谱的多,尤其是这种比较新的问题、要多去StackOverflow和AskUbuntu等论坛和官网查看,有奇效。\n参考资料 联想小新pro14安装Ubuntu20.04 Ubuntu 20.04 no driver loaded for Intel Iris Xe Graphics Intel Iris Xe MAX Graphics with Linux How to change the login screen resolution in Ubuntu 18.04 Custom Resolution Ubuntu 20.04 How can I change the resolution of the GRUB menu? ","permalink":"https://blog.zzsqwq.cn/posts/215/","summary":"\u003ch1 id=\"2021版小新pro14-ubuntu-2004-配置指南\"\u003e2021版小新Pro14 Ubuntu 20.04 配置指南\u003c/h1\u003e\n\u003ch2 id=\"补充\"\u003e补充\u003c/h2\u003e\n\u003cp\u003e最近重装了 Ubuntu 20.04,又找了相关的一些帖子,发现 \u003ca href=\"https://blog.ryey.icu/lenovo-yoga-14s-2021.html#toc-entry-3\"\u003e聯想Yoga 14s 2021款裝機小記\u003c/a\u003e 中提到了下文中提到的\u003cstrong\u003e屏幕闪烁的问题\u003c/strong\u003e,解决办法是:只需要在内核参数中加入 \u003ccode\u003ei915.enable_psr=0\u003c/code\u003e 即可。\u003c/p\u003e\n\u003cp\u003e具体操作步骤如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ sudo vim /etc/default/grub\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e在 GRUB_CMDLINE_LINUX_DEFAULT 这一行的最后添加 \u003ccode\u003ei915.enable_psr=0\u003c/code\u003e,保存后终端运行:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ sudo update-grub\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e然后重启即可。\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003e苦于沉重游戏本的迫害,新买了一台小新Pro14 2021款,上手感觉还挺不错的。如下是配置:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eCPU:酷睿 i5-11300H\u003c/li\u003e\n\u003cli\u003e显卡:集成显卡 Intel 锐炬Iris Xe\u003c/li\u003e\n\u003cli\u003e内存:16G\u003c/li\u003e\n\u003cli\u003e外存:512 SSD\u003c/li\u003e\n\u003cli\u003e屏幕:分辨率 2880x1800、400nits、100%sRGB\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"https://blog.zzsqwq.cn/usr/uploads/2021/11/3138090261.png\" alt=\"电脑配置信息\" /\u003e\n\u003c/p\u003e\n\u003cp\u003e这里需要注意的是,不同时间出的小新Pro14配置是不太一样的,所以我这里列了一下配置。主要区别在于有一部分是2.2K分辨率+MX450显卡,而我这个是2.8K分辨率+锐炬Iris Xe显卡。\u003c/p\u003e\n\u003cp\u003e为了工作的需要,要装一个Ubuntu,先是装了之前用过的 Ubuntu 18.04,安装后发现触摸板无法使用,一系列探索后无果,在朋友的推荐下,还是决定安装 Ubuntu 20.04 试一下,踩了一些坑,在这里记录一下。\u003c/p\u003e\n\u003ch2 id=\"问题列表\"\u003e问题列表\u003c/h2\u003e\n\u003cp\u003e如果你遇到了以下问题,那么这篇文章的方法可能会对你有益处:\u003c/p\u003e\n\u003ch3 id=\"ubuntu-1804-相关\"\u003eUbuntu 18.04 相关\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003eUbuntu 18.04 无法使用触摸板\u003c/li\u003e\n\u003cli\u003eUbuntu 18.04 无法使用内置键盘\u003c/li\u003e\n\u003cli\u003eUbuntu 18.04 无法调节亮\u003c/li\u003e\n\u003cli\u003eUbuntu 18.04 查看GPU发现是llvm,而不是Iris Xe\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"ubuntu-2004-相关\"\u003eUbuntu 20.04 相关\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003eUbuntu 20.04 进入后屏幕花屏、黑屏\u003c/li\u003e\n\u003cli\u003eUbuntu 20.04 查看GPU发现是llvm,而不是Iris Xe\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"现在达成的效果\"\u003e现在达成的效果\u003c/h2\u003e\n\u003cp\u003eUbuntu 20.04 能够正常使用,触摸板以及外界屏幕,亮度调节均无问题。\u003c/p\u003e","title":"2021版小新Pro14 Ubuntu 20.04 配置指南"},{"content":"前言 前段时间在 Github 学完了关于 git 的小游戏 learnGitBranching ,受益匪浅。\n它通过可视化的方式将分支的关系,每条命令的作用等都明明白白的体现出来,可以很直观的感受到你每条命令对整个分支树,每一个 ref 的作用。\n通过这种学习感觉自己对 Git 的理解更加深入一步,能够理解其中的原理,而不是浅尝辄止,照猫画虎。\n学习中记了一些零零散散的思路,想要写一篇笔记记录出来,之前已经写过一个简单的 Git 教程,这篇教程将会更加深入,希望可以帮助大家更好的掌握 Git。\n窃认为,想要学好 Git ,必须要理解清楚其中的分区以及引用,学会了这两个,各种基本操作就很容易理解了。接下来的笔记也基本以此思路展开。\nGit中的分区 首先,Git中存在三大分区,分别是工作区、暂存区、版本库。其中,\n工作区即我们工作的目录,暂存区是我们执行 git add 后文件存在的区域。\n我们可以通过 git status 对两种状态进行查看,例如:\n~/test master* base ❯ git status On branch master Changes to be committed: (use \u0026#34;git restore --staged \u0026lt;file\u0026gt;...\u0026#34; to unstage) modified: test Changes not staged for commit: (use \u0026#34;git add \u0026lt;file\u0026gt;...\u0026#34; to update what will be committed) (use \u0026#34;git restore \u0026lt;file\u0026gt;...\u0026#34; to discard changes in working directory) modified: test 上图中存在两部分, 分别为 Changes to be committed 这里是表示的版本库与暂存区的区别,还有Changes not staged for commit ,它表示的是工作区与暂存区的区别。\n版本库是我们执行 git commit -m \u0026quot;xxx\u0026quot; 后,文件存在的区域。在上述过程中,Git 记录暂存区与版本库的差异,生成版本号,记录下来。我们可以通过 git log 来查看我们产生的更改,内容如下:\ncommit 9da52a0e4800547ca46bd6bb919d1105cea43f1e (HEAD -\u0026gt; master) Author: zs \u0026lt;2459958352@qq.com\u0026gt; Date: Thu Jul 22 22:09:45 2021 +0800 test commit 其中包含了版本号、当前节点上的 ref 记录、作者、邮箱、日期以及此次提交的注释。\nGit中的引用 在 Git 中,引用到处可见,引用类似于给某一个 commit-id 即某一次提交的 SHA-1 值起一个简单的名字,如 branch ,tag 这些都是引用。\nGit 中存在一个命令, git update-ref ,你可能几乎没见过,但可能天天在用。\n当运行类似于 git branch \u0026lt;branch\u0026gt; 这样的命令时,Git 实际上会运行 git update-ref 命令,例如,运行 git branch zs,就等效于\n$ git update-ref refs/heads/zs \u0026lt;commit-id\u0026gt; 这里的 commit-id 就是当前提交的 commit-id ,那他是如何获得的呢?\n使用过 Git 的人一定知道,Git 中存在一个名叫 HEAD 的引用,它可能是引用,也可能是引用的引用。即它很多时候是指向某一个引用,如指向分支 master 这个引用。不过,它也可以与引用分离,称为游离的HEAD,即不指向某个引用,而指向单独的一个 commit 。\n可以通过 git commit commit-id 来实现,不过,我们一般不推荐这种操作。下面的讨论,我们都是基于 HEAD 是指向某一分支的。\n下面是关于一个引用的小例子:\n~/test master* base ❯ git branch zs ~/test master* base ❯ cat .git/refs/heads/zs 9da52a0e4800547ca46bd6bb919d1105cea43f1e ~/test master* base ❯ git update-ref refs/heads/test 9da52a ~/test master* base ❯ cat .git/HEAD ref: refs/heads/master ~/test master* base ❯ cat .git/refs/heads/master 9da52a0e4800547ca46bd6bb919d1105cea43f1e ~/test master* base ❯ cat .git/refs/heads/test 9da52a0e4800547ca46bd6bb919d1105cea43f1e 可以发现,例子中 HEAD 指向 master ,master,zs,test 同时都指向 id 为 9da52a 的提交。\n撤销更改 撤销本地更改 通过版本库撤销暂存区更改,工作区不改 $ git reset HEAD^ #撤销一次更改 $ git reset HEAD~nums #撤销HEAD往前nums次更改 直接通过版本库撤销工作区的更改 $ git reset HEAD^ --hard #撤销一次更改 $ git reset HEAD~nums --hard #撤销HEAD往前nums次更改 可以发现只要加了 --hard ,就可以直接也把工作区改掉,不过建议三思而后行!\n撤销远程更改 上面说的是你本地的工作区 or 暂存区的撤销\n如果你已经把更改推送到了远端仓库,那么你想要去掉那次改动怎么办?\n可能你会想,直接通过 git reset 切换到上面的某个需要的节点,然后再改?But,很容易想到这样会产生严重的冲突。一旦commit已经被push到远程仓库,那么是坚决不允许去reset它的。\n还好,Git 给我们提供了一个更好的选择,你可以通过 git revert 产生一个类似于补丁的东西来消除掉更改,很容易理解,这样没有改变树的结构,相对于 git reset 他会往前走而不是回溯,这不会对之前的历史产生重要的影响。\n需要注意的是, git revert 的用法:\n$ git revert HEAD #撤销掉HEAD这次更改,回到HEAD的上次版本 $ git revert \u0026lt;commit_id\u0026gt; #撤销掉这次cmmit的修改 两种合并方式 我们知道,Git 中存在两种合并分支的方式,分别为 git merge 和 git rebase 。\n两种方式各有优劣,简单说,rabase 是把两条分支的提交记录整理到某一主分支上,它有着历史的完整记录。而 merge 虽然也是整理了提交,但是某一分支的中间提交更改的过程合并后并不会体现在主分支上,中间过程可以说是在主分支上不可见的。\n很容易发现,rebase 产生的主分支提交记录会更加的详细,它记录了每一步小的改动。而 merge 产生的更简洁,有点类似于封装的意味,只是告诉你我这个提交完成了这个任务的开发,内部的实现细节却不会告诉你。\n而 rebase 相比与 merge 也会更加繁琐一些,你也可以通过 git rebase -i 来通过可视化界面(可视化文本列表)的方式,来对记录做取舍与改动,不过还是没有 merge 方便,远程仓库的合并操作一般都是使用 merge 。\n需要注意的是,两种方法的使用习惯很不一样:\n$ git merge \u0026lt;branch\u0026gt; 代表的是将 \u0026lt;branch\u0026gt; 分支合并到当前 HEAD 所在的分支。\n$ git rebase \u0026lt;branch1\u0026gt; \u0026lt;branch2\u0026gt; 代表的是将 branch2 合并到 \u0026lt;branch1\u0026gt; 的位置。如果省略 \u0026lt;branch2\u0026gt; ,那么就是合并 HEAD 所在分支到 \u0026lt;branch1\u0026gt; 分支。\n可以发现 merge 体现的是一种, merge xx 到当前位置。而 rebase 体现的是将自己合并到 xx 那里去。一个是别人过来,一个是自己过去。建议两个命令改成 merge from ,rebase into,哈哈。\n顺便提一下, merge 会导致一个节点有多个父节点,通过上文我们知道可以通过 ~ 在一条线上移动,在这里,我们可以通过 ^ 来指定第几个父节点,如 HEAD^3 就是指 HEAD 所在节点的第三个父节点。\n整理提交记录 我们有时会需要把另一个分支的部分更改放到主分支上来,即整理我们所有的提交记录,拿到我们所需要的来组成一个完整功能。\n为了完成这件事,我们想到,这有点像合并分支,不过可能不需要某一个分支上的全部更改,只需要其中的一部分就可以了。\n上面提到,通过 git rebase -i 可以进行交互式的 rebase ,可以对提交记录进行取舍,因此这样就可以满足我们的需求,只不过可能合并的时候需要想明白是从哪里变到哪里,有一些烧脑。\n幸运的是,Git 还给我们提供了另一个更加简洁的方式——git cherry-pick ,语法如下:\n$ git cherry-pick \u0026lt;commid-id\u0026gt; 你可以通过这种方式,将树上的任意一个节点的提交添加到当前 HEAD 所在分支的下方,这真是功能强大的命令!你也可以通过空格间隔,来顺序摘取多个提交。\n两条万能指令 除了上面我觉得值得说道的问题,我还想推荐两条我认为非常有用的指令,掌握了他们,你就可以在分支树上随心所欲的移动!\n移动分支 $ git branch -f \u0026lt;branch\u0026gt; \u0026lt;commit-id\u0026gt; 通过这条指令,你可以将 \u0026lt;branch\u0026gt; 的引用指向 commit-id ,如果你读懂了上面的内容,你会发现它只是通过 update-ref 更新了对应的引用。\n移动 HEAD $ git checkout \u0026lt;branch\u0026gt; $ git checkout \u0026lt;commit-id\u0026gt; 通过这条指令,你可以自由的移动 HEAD 引用,前者让他指向了 \u0026lt;branch\u0026gt; 分支,后者让他指向了SHA-1为 \u0026lt;commit-id\u0026gt; 的提交。\n推荐的资料 在学习的过程中,看了很多资料,一并推荐给大家!\nlearnGitBranching:有趣的闯关游戏,但也干货满满。\nGit三大分区概念:讲解了关于分区的概念,还有直观清晰的图片!\nGit的引用:来自 Git 官方的讲解,十分硬核。\n","permalink":"https://blog.zzsqwq.cn/posts/201/","summary":"\u003ch1 id=\"前言\"\u003e前言\u003c/h1\u003e\n\u003cp\u003e前段时间在 Github 学完了关于 git 的小游戏 \u003ca href=\"https://github.com/pcottle/learnGitBranching\"\u003elearnGitBranching\u003c/a\u003e ,受益匪浅。\u003c/p\u003e\n\u003cp\u003e它通过可视化的方式将分支的关系,每条命令的作用等都明明白白的体现出来,可以很直观的感受到你每条命令对整个分支树,每一个 ref 的作用。\u003c/p\u003e\n\u003cp\u003e通过这种学习感觉自己对 Git 的理解更加深入一步,能够理解其中的原理,而不是浅尝辄止,照猫画虎。\u003c/p\u003e\n\u003cp\u003e学习中记了一些零零散散的思路,想要写一篇笔记记录出来,之前已经写过一个简单的 Git 教程,这篇教程将会更加深入,希望可以帮助大家更好的掌握 Git。\u003c/p\u003e\n\u003cp\u003e窃认为,想要学好 Git ,必须要理解清楚其中的分区以及引用,学会了这两个,各种基本操作就很容易理解了。接下来的笔记也基本以此思路展开。\u003c/p\u003e\n\u003ch1 id=\"git中的分区\"\u003eGit中的分区\u003c/h1\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"https://blog.zzsqwq.cn/usr/uploads/2021/07/612956951.jpg\" alt=\"Git中的三大分区,图片来源自掘金GabrielPanda\" /\u003e\n\u003c/p\u003e\n\u003cp\u003e首先,Git中存在三大分区,分别是\u003cstrong\u003e工作区、暂存区、版本库\u003c/strong\u003e。其中,\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e工作区\u003c/strong\u003e即我们工作的目录,\u003cstrong\u003e暂存区\u003c/strong\u003e是我们执行 \u003ccode\u003egit add\u003c/code\u003e 后文件存在的区域。\u003c/p\u003e\n\u003cp\u003e我们可以通过 \u003ccode\u003egit status\u003c/code\u003e 对两种状态进行查看,例如:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode class=\"language-sheel\" data-lang=\"sheel\"\u003e~/test master*\nbase ❯ git status \nOn branch master\nChanges to be committed:\n (use \u0026#34;git restore --staged \u0026lt;file\u0026gt;...\u0026#34; to unstage)\n\tmodified: test\n\nChanges not staged for commit:\n (use \u0026#34;git add \u0026lt;file\u0026gt;...\u0026#34; to update what will be committed)\n (use \u0026#34;git restore \u0026lt;file\u0026gt;...\u0026#34; to discard changes in working directory)\n\tmodified: test\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e上图中存在两部分, 分别为 \u003ccode\u003eChanges to be committed\u003c/code\u003e 这里是表示的版本库与暂存区的区别,还有\u003ccode\u003eChanges not staged for commit\u003c/code\u003e ,它表示的是工作区与暂存区的区别。\u003c/p\u003e","title":"关于Git的一些理解"},{"content":"前言 最近基地的打印机突然又好起来了。\n因为基地的打印机型号比较老——HP LaserJet 1020,没有无线打印的功能。所以之前一位学长1 用树莓派配置了打印机的无线打印功能,但是后来发现有一些问题,有时候发送打印请求树莓派无法接收,而且不知道为何,学长之前用的是树莓派自己创建WiFi,连接对应WiFi才能打印,但是这个显然不是最优的解决办法。\n考虑到之间已经配置好基地WiFi,我决定重新配置一下打印功能,使其连接基地WiFi即可实现局域网打印。\n配置过程 查看树莓派内容 通过ssh连接树莓派,发现里面除了Github上的一个开源项目create_ap ,就没有什么其他的内容了,连接屏幕后发现没有任何图像信号,无从下手,因此考虑重新刷机。\n对树莓派进行刷机 把数据备份了一下,看了一下树莓派版本是2015年生产的 Raspberry Pi 3 model B V1.2 ,是老古董了。\n去官网看了一下,因为我对Ubuntu比较熟悉,我计划安装一个 Ubuntu20.04版本的,考虑到版本比较老,就装了server版本的,相比与desktop版本负担更小一些。\n其实就是下一个官方的软件,Raspberry Pi Imager ,直接用读卡器对树莓派的存储卡刷机即可。\n这里是对应的镜像以及教程: 镜像下载 安装教程\n配置网络相关 Ubuntu的server版本有个比较蛋疼的问题就是上网比较困难,如果是用的学校网线,必须要PPPOE拨号才能上网,但是server版本居然没有 net-tools 和 network-manager ,连接WiFi啥的试了很多办法但还是没有什么作用。\n解决办法:用网线直接连接树莓派和有网的路由器,安装 net-tools 和 network-manager ,执行\n$ sudo nmtui 选择 Activate a connect 连接无线的WiFi,执行\n$ sudo ifconfig 查看WiFi对应的IP,至此,树莓派可以摆脱屏幕,我们可以使用电脑进行使用 ssh 连接。\n这里也可以使用网线进行连接,具体操作如下\n用网线连接树莓派和自己的电脑。\n在树莓派的利用 nmtui 选择 Edit a connection ,Add一个Ethernet connect,对IPv4 CONFIGURATION进行设置,首先讲 Automatic 设置为 Manual,设置 Address 为 静态IP 如 192.168.3.2 ,Gateway 设置为 192.168.3.1 。\n在自己电脑利用 nmtui 同上不过设置 Address 为 192.168.3.3 ,只要是位于同一网段即可。\n这时候就可以通过网线进行 ssh 连接了。\n配置cups 以下大多参考:如何正确地用树莓派共享打印机\n大佬言:\n其实,这一步的工作量非常少,因为软件包 CUPS 就是为共享打印机而生。我们要做的只是将打印机用 USB 线缆连接树莓派,然后安装并配置 CUPS。\n然而,事实并非如此。\n换源 在安装之前需要换源,如果不换源的话,安装会十分缓慢,具体的流程可以看上面的blog,因为我们基地的WiFi自带代理,因此这一步我没有做。\n安装驱动及打印程序 首先更新源并安装Hp的打印机驱动 hplip $ sudo apt update $ sudo apt install hplip 然后安装Apple开源的远程打印工具 cups,并配置相应权限 $ sudo apt install cups # Install cups package $ sudo usermod -aG lpadmin pi # Add user to lpadmin group,pi is your user name $ sudo cupsctl --remote-any # open remote access 然后使用在同一局域网的电脑,访问 https://树莓派IP:631,可以进入如下界面,按照下图设置右侧的Server Settings 连接打印机和树莓派,点击Add Printer添加打印机,在弹出的窗口中输入对应的用户信息,使用在上一步中用户组中添加的用户\n然后按着一步步的指引,选择HP LaserJet 1020打印机,然后按照提示,选择和名称对应的驱动,我们会发现 LaserJet 1020 对应驱动会提示:HP laserjet requires proprietary plugin,也就是我们不仅需要这个通用的驱动,而且需要一些额外的插件,打印机才能正常工作。\n查阅资料发现:HP官方已经给出了说明,我们需要查看hplip版本,然后安装对应的驱动插件。\n首先我们查看一下版本,发现是3.20.3版本 $ sudo apt show hplip Package: hplip Version: 3.20.3+dfsg0-2 Priority: optional Section: utils Origin: Ubuntu Maintainer: Ubuntu Developers \u0026lt;ubuntu-devel-discuss@lists.ubuntu.com\u0026gt; Original-Maintainer: Debian Printing Team \u0026lt;debian-printing@lists.debian.org\u0026gt; Bugs: https://bugs.launchpad.net/ubuntu/+filebug Installed-Size: 518 kB 然后在 插件列表 中找到 3.20.3 对应的hplip-3.20.3-plugin.run和hplip-3.20.3-plugin.run.asc,使用wget下载到树莓派本地。\n运行 hp-setup -i 使用命令行进行安装,按照提示命令,进行插件的安装。\n[scode type=\u0026ldquo;yellow\u0026rdquo;]这里建议提前下好安装,而不是直接联网下载,速度较快,指定路径需要为绝对路径[/scode]\n至此,我们可以尝试使用手机或者电脑搜索打印机来进行打印测试,没有其他意外的话,可以发现打印成功!\n结语 其实这个配置过程远没有这么简单,期间还有很多小问题,但是大致的流程大概就是如上述所示,全写出来可能太啰嗦,大家如果配置过程中遇到更多的疑问,可以在下方评论一起探讨~\n参考链接 What is the HPLIP Binary Plug-In and How Do I Install It? Plugins Other Plugins cups 使用树莓派搭建无线打印机 如何正确地用树莓派共享打印机 学长的博客在这里:\tdykai\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","permalink":"https://blog.zzsqwq.cn/posts/198/","summary":"\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003e最近基地的打印机突然又好起来了。\u003c/p\u003e\n\u003cp\u003e因为基地的打印机型号比较老——HP LaserJet 1020,没有无线打印的功能。所以之前一位学长\u003csup id=\"fnref:1\"\u003e\u003ca href=\"#fn:1\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e1\u003c/a\u003e\u003c/sup\u003e 用树莓派配置了打印机的无线打印功能,但是后来发现有一些问题,有时候发送打印请求树莓派无法接收,而且不知道为何,学长之前用的是树莓派自己创建WiFi,连接对应WiFi才能打印,但是这个显然不是最优的解决办法。\u003c/p\u003e\n\u003cp\u003e考虑到之间已经配置好基地WiFi,我决定重新配置一下打印功能,使其连接基地WiFi即可实现局域网打印。\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"配置过程\"\u003e配置过程\u003c/h2\u003e\n\u003ch3 id=\"查看树莓派内容\"\u003e查看树莓派内容\u003c/h3\u003e\n\u003cp\u003e通过ssh连接树莓派,发现里面除了Github上的一个开源项目\u003ca href=\"https://github.com/oblique/create_ap\"\u003ecreate_ap\u003c/a\u003e ,就没有什么其他的内容了,连接屏幕后发现没有任何图像信号,无从下手,因此考虑重新刷机。\u003c/p\u003e\n\u003chr\u003e\n\u003ch3 id=\"对树莓派进行刷机\"\u003e对树莓派进行刷机\u003c/h3\u003e\n\u003cp\u003e把数据备份了一下,看了一下树莓派版本是2015年生产的 \u003ccode\u003eRaspberry Pi 3 model B V1.2\u003c/code\u003e ,是老古董了。\u003c/p\u003e\n\u003cp\u003e去官网看了一下,因为我对Ubuntu比较熟悉,我计划安装一个 Ubuntu20.04版本的,考虑到版本比较老,就装了\u003cstrong\u003eserver\u003c/strong\u003e版本的,相比与desktop版本负担更小一些。\u003c/p\u003e\n\u003cp\u003e其实就是下一个官方的软件,\u003ccode\u003eRaspberry Pi Imager\u003c/code\u003e ,直接用读卡器对树莓派的存储卡刷机即可。\u003c/p\u003e\n\u003cp\u003e这里是对应的镜像以及教程: \u003ca href=\"https://ubuntu.com/download/raspberry-pi\"\u003e镜像下载\u003c/a\u003e \u003ca href=\"https://ubuntu.com/tutorials/how-to-install-ubuntu-desktop-on-raspberry-pi-4#1-overview\"\u003e安装教程\u003c/a\u003e\u003c/p\u003e\n\u003chr\u003e\n\u003ch3 id=\"配置网络相关\"\u003e配置网络相关\u003c/h3\u003e\n\u003cp\u003eUbuntu的server版本有个比较蛋疼的问题就是上网比较困难,如果是用的学校网线,必须要PPPOE拨号才能上网,但是server版本居然没有 \u003ccode\u003enet-tools\u003c/code\u003e 和 \u003ccode\u003enetwork-manager\u003c/code\u003e ,连接WiFi啥的试了很多办法但还是没有什么作用。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e解决办法:用网线直接连接树莓派和有网的路由器,安装 \u003ccode\u003enet-tools\u003c/code\u003e 和 \u003ccode\u003enetwork-manager\u003c/code\u003e ,执行\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ sudo nmtui\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e选择 \u003ccode\u003eActivate a connect \u003c/code\u003e 连接无线的WiFi,执行\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ sudo ifconfig\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e查看WiFi对应的IP,至此,树莓派可以摆脱屏幕,我们可以使用电脑进行使用 \u003ccode\u003essh\u003c/code\u003e 连接。\u003c/p\u003e\n\u003cp\u003e这里也可以使用网线进行连接,具体操作如下\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e用网线连接树莓派和自己的电脑。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e在树莓派的利用 \u003ccode\u003enmtui\u003c/code\u003e 选择 \u003ccode\u003eEdit a connection \u003c/code\u003e ,Add一个Ethernet connect,对IPv4 CONFIGURATION进行设置,首先讲 \u003ccode\u003eAutomatic\u003c/code\u003e 设置为 \u003ccode\u003eManual\u003c/code\u003e,设置 \u003ccode\u003eAddress\u003c/code\u003e 为 \u003cstrong\u003e静态IP\u003c/strong\u003e 如 \u003ccode\u003e192.168.3.2\u003c/code\u003e ,\u003ccode\u003eGateway\u003c/code\u003e 设置为 \u003ccode\u003e192.168.3.1\u003c/code\u003e 。\u003c/p\u003e","title":"利用树莓派为HP LaserJet 1020配置无线打印功能"},{"content":"问题描述 ​Ubuntu下想要使用QQ有一个比较好的解决方案就是deepin-wine的版本,deepin-wine版本的QQ一共有两个版本,分别是 8.9.1 和 9.1.8 ,前者安装后发现无法登陆,登录时会提示版本过低的问题,于是我换到9.1.8版本后,启动初始化后就无任何信息了,于是开始排查问题\n解决方案 ​首先我们根据上文的启示,因为每一个应用程序对应了一个 xxx.desktop 文件,因此在应用库中的QQ一定也有一个对应的 desktop 文件\n​我们进入到 /usr/share/applications ,运行\n$ ls | grep -i qq ​可以发现其中有一个名为 deepin.com.qq.im.desktop 的文件,我们打开后发现内容如下:\n#!/usr/bin/env xdg-open [Desktop Entry] Encoding=UTF-8 Type=Application X-Created-By=Deepin WINE Team Categories=chat; Icon=deepin.com.qq.im Exec=\u0026#34;/opt/deepinwine/apps/Deepin-QQ/run.sh\u0026#34; -u %u Name=QQ Name[zh_CN]=QQ Comment=Tencent QQ Client on Deepin Wine StartupWMClass=QQ.exe MimeType= ​可以看到Exec那一栏为 Exec=\u0026quot;/opt/deepinwine/apps/Deepin-QQ/run.sh\u0026quot; -u %u ,发现他是运行目录下的一个 run.sh 脚本来启动的。\n​我们进入目录下直接运行该脚本,查看log信息:\nbase ❯ ./run.sh Run Deepin-QQ 9.1.8deepin0 c:/Program Files/Tencent/QQ/Bin/QQ.exe run Deepin-QQ progress pid Gtk-Message: 01:16:58.069: GtkDialog mapped without a transient parent. This is discouraged. total 0 lrwxrwxrwx 1 zs zs 10 6月 16 01:16 c: -\u0026gt; ../drive_c lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com1 -\u0026gt; /dev/ttyS0 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com10 -\u0026gt; /dev/ttyS9 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com11 -\u0026gt; /dev/ttyS10 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com12 -\u0026gt; /dev/ttyS11 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com13 -\u0026gt; /dev/ttyS12 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com14 -\u0026gt; /dev/ttyS13 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com15 -\u0026gt; /dev/ttyS14 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com16 -\u0026gt; /dev/ttyS15 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com17 -\u0026gt; /dev/ttyS16 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com18 -\u0026gt; /dev/ttyS17 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com19 -\u0026gt; /dev/ttyS18 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com2 -\u0026gt; /dev/ttyS1 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com20 -\u0026gt; /dev/ttyS19 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com21 -\u0026gt; /dev/ttyS20 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com22 -\u0026gt; /dev/ttyS21 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com23 -\u0026gt; /dev/ttyS22 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com24 -\u0026gt; /dev/ttyS23 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com25 -\u0026gt; /dev/ttyS24 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com26 -\u0026gt; /dev/ttyS25 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com27 -\u0026gt; /dev/ttyS26 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com28 -\u0026gt; /dev/ttyS27 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com29 -\u0026gt; /dev/ttyS28 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com3 -\u0026gt; /dev/ttyS2 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com30 -\u0026gt; /dev/ttyS29 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com31 -\u0026gt; /dev/ttyS30 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com32 -\u0026gt; /dev/ttyS31 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com4 -\u0026gt; /dev/ttyS3 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com5 -\u0026gt; /dev/ttyS4 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com6 -\u0026gt; /dev/ttyS5 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com7 -\u0026gt; /dev/ttyS6 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com8 -\u0026gt; /dev/ttyS7 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com9 -\u0026gt; /dev/ttyS8 lrwxrwxrwx 1 zs zs 8 6月 16 01:16 y: -\u0026gt; /home/zs lrwxrwxrwx 1 zs zs 1 6月 16 01:16 z: -\u0026gt; / CallApp Deepin-QQ c:/Program Files/Tencent/QQ/Bin/QQ.exe 2021年 06月 16日 星期三 01:16:58 CST:kill QQ.exe block 2021年 06月 16日 星期三 01:16:58 CST:No wine process found /home/zs/.deepinwine/Deepin-QQ/drive_c/Program Files/Tencent/QQ/Bin Starting process c:/Program Files/Tencent/QQ/Bin/QQ.exe ... /opt/deepinwine/apps/Deepin-QQ base ❯ wine: cannot find L\u0026#34;C:\\\\windows\\\\system32\\\\winemenubuilder.exe\u0026#34; wine version: 2.18 libGL error: No matching fbConfigs or visuals found libGL error: failed to load driver: swrast X Error of failed request: GLXBadContext Major opcode of failed request: 152 (GLX) Minor opcode of failed request: 6 (X_GLXIsDirect) Serial number of failed request: 207 Current serial number in output stream: 206 ​可以发现最下面的log信息有一些异常,首先第一行是因为我们是Ubuntu系统,可以暂且不关注\n​接下来可以看到有一个LibGL的错误,我们通过Google搜索\nlibGL error: No matching fbConfigs or visuals found libGL error: failed to load driver: swrast X Error of failed request: GLXBadContext Major opcode of failed request: 152 (GLX) Minor opcode of failed request: 6 (X_GLXIsDirect) Serial number of failed request: 207 Current serial number in output stream: 206 ​发现类似的错误及解决方案如下:\nSOLVED] LibGL errors with osu! and wine\nSteam: libGL error: No matching fbConfigs or visuals found libGL error: failed to load driver: swrast\n​从搜索结果来看,这个问题还是非常常见的,用steam也会遇到,一般都是因为电脑安装了64位的NVIDIA显卡驱动,但是因为应用是32位的导致不能兼容,因此无法启动\n​最终解决方案有两个\n如果是不常用NVIDIA驱动的人,普通的办公一下,可以搜索网上教程关闭独显,只启用集显,可以发现QQ可以正常启动, 重新安装32位的NVIDIA驱动 最后 虽然已经知道了解决方案,但是最终我还是选择卸载掉QQ,安装了wine版本的TIM,感觉和QQ没什么区别,而且更加简洁,而且可以流畅运行,没有N卡兼容问题!大家可以考虑一下~\n而且QQ和TIM某些情况下会出现bug,字体全部变为方块,在 deepin-wine-ubuntu 的 Issues 中找到了解决方案 Ubuntu 安装QQ后中文方块解决方法 ,大家有同样困扰的也可以看一下~\n","permalink":"https://blog.zzsqwq.cn/posts/195/","summary":"\u003ch3 id=\"问题描述\"\u003e问题描述\u003c/h3\u003e\n\u003cp\u003e​Ubuntu下想要使用QQ有一个比较好的解决方案就是deepin-wine的版本,deepin-wine版本的QQ一共有两个版本,分别是 8.9.1 和 9.1.8 ,前者安装后发现无法登陆,登录时会提示版本过低的问题,于是我换到9.1.8版本后,启动初始化后就无任何信息了,于是开始排查问题\u003c/p\u003e\n\u003ch3 id=\"解决方案\"\u003e解决方案\u003c/h3\u003e\n\u003cp\u003e​首先我们根据上文的启示,因为每一个应用程序对应了一个 \u003ccode\u003exxx.desktop\u003c/code\u003e 文件,因此在应用库中的QQ一定也有一个对应的 \u003ccode\u003edesktop\u003c/code\u003e 文件\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"https://blog.zzsqwq.cn/usr/uploads/2021/06/75817321.png\" alt=\"QQ的启动方式\" /\u003e\n\u003c/p\u003e\n\u003cp\u003e​我们进入到 \u003ccode\u003e/usr/share/applications\u003c/code\u003e ,运行\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ ls \u003cspan class=\"p\"\u003e|\u003c/span\u003e grep -i qq\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e​可以发现其中有一个名为 \u003ccode\u003edeepin.com.qq.im.desktop\u003c/code\u003e 的文件,我们打开后发现内容如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#!/usr/bin/env xdg-open\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e[\u003c/span\u003eDesktop Entry\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003eEncoding\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003eUTF-8\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003eType\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003eApplication\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eX-Created-By\u003cspan class=\"o\"\u003e=\u003c/span\u003eDeepin WINE Team\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003eCategories\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003echat\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003eIcon\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003edeepin.com.qq.im\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003eExec\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;/opt/deepinwine/apps/Deepin-QQ/run.sh\u0026#34;\u003c/span\u003e -u %u\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003eName\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003eQQ\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eName\u003cspan class=\"o\"\u003e[\u003c/span\u003ezh_CN\u003cspan class=\"o\"\u003e]=\u003c/span\u003eQQ\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003eComment\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003eTencent QQ Client on Deepin Wine\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003eStartupWMClass\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003eQQ.exe\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003eMimeType\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e​可以看到Exec那一栏为 \u003ccode\u003eExec=\u0026quot;/opt/deepinwine/apps/Deepin-QQ/run.sh\u0026quot; -u %u\u003c/code\u003e ,发现他是运行目录下的一个 \u003ccode\u003erun.sh\u003c/code\u003e 脚本来启动的。\u003c/p\u003e\n\u003cp\u003e​我们进入目录下直接运行该脚本,查看log信息:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ebase ❯ ./run.sh \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eRun Deepin-QQ 9.1.8deepin0 c:/Program Files/Tencent/QQ/Bin/QQ.exe\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003erun Deepin-QQ progress pid \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eGtk-Message: 01:16:58.069: GtkDialog mapped without a transient parent. This is discouraged.\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003etotal \u003cspan class=\"m\"\u003e0\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e10\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e16\u003c/span\u003e 01:16 c: -\u0026gt; ../drive_c\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e10\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com1 -\u0026gt; /dev/ttyS0\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e10\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com10 -\u0026gt; /dev/ttyS9\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e11\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com11 -\u0026gt; /dev/ttyS10\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e11\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com12 -\u0026gt; /dev/ttyS11\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e11\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com13 -\u0026gt; /dev/ttyS12\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e11\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com14 -\u0026gt; /dev/ttyS13\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e11\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com15 -\u0026gt; /dev/ttyS14\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e11\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com16 -\u0026gt; /dev/ttyS15\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e11\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com17 -\u0026gt; /dev/ttyS16\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e11\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com18 -\u0026gt; /dev/ttyS17\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e11\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com19 -\u0026gt; /dev/ttyS18\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e10\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com2 -\u0026gt; /dev/ttyS1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e11\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com20 -\u0026gt; /dev/ttyS19\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e11\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com21 -\u0026gt; /dev/ttyS20\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e11\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com22 -\u0026gt; /dev/ttyS21\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e11\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com23 -\u0026gt; /dev/ttyS22\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e11\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com24 -\u0026gt; /dev/ttyS23\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e11\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com25 -\u0026gt; /dev/ttyS24\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e11\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com26 -\u0026gt; /dev/ttyS25\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e11\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com27 -\u0026gt; /dev/ttyS26\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e11\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com28 -\u0026gt; /dev/ttyS27\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e11\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com29 -\u0026gt; /dev/ttyS28\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e10\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com3 -\u0026gt; /dev/ttyS2\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e11\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com30 -\u0026gt; /dev/ttyS29\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e11\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com31 -\u0026gt; /dev/ttyS30\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e11\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com32 -\u0026gt; /dev/ttyS31\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e10\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com4 -\u0026gt; /dev/ttyS3\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e10\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com5 -\u0026gt; /dev/ttyS4\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e10\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com6 -\u0026gt; /dev/ttyS5\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e10\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com7 -\u0026gt; /dev/ttyS6\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e10\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com8 -\u0026gt; /dev/ttyS7\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e10\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e15\u003c/span\u003e 23:36 com9 -\u0026gt; /dev/ttyS8\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e8\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e16\u003c/span\u003e 01:16 y: -\u0026gt; /home/zs\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elrwxrwxrwx \u003cspan class=\"m\"\u003e1\u003c/span\u003e zs zs \u003cspan class=\"m\"\u003e1\u003c/span\u003e 6月 \u003cspan class=\"m\"\u003e16\u003c/span\u003e 01:16 z: -\u0026gt; /\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eCallApp Deepin-QQ c:/Program Files/Tencent/QQ/Bin/QQ.exe\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e2021年 06月 16日 星期三 01:16:58 CST:kill QQ.exe block\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e2021年 06月 16日 星期三 01:16:58 CST:No wine process found\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e/home/zs/.deepinwine/Deepin-QQ/drive_c/Program Files/Tencent/QQ/Bin\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eStarting process c:/Program Files/Tencent/QQ/Bin/QQ.exe ...\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e/opt/deepinwine/apps/Deepin-QQ\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ebase ❯ wine: cannot find L\u003cspan class=\"s2\"\u003e\u0026#34;C:\\\\windows\\\\system32\\\\winemenubuilder.exe\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ewine version: 2.18\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elibGL error: No matching fbConfigs or visuals found\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elibGL error: failed to load driver: swrast\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eX Error of failed request: GLXBadContext\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e Major opcode of failed request: \u003cspan class=\"m\"\u003e152\u003c/span\u003e \u003cspan class=\"o\"\u003e(\u003c/span\u003eGLX\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e Minor opcode of failed request: \u003cspan class=\"m\"\u003e6\u003c/span\u003e \u003cspan class=\"o\"\u003e(\u003c/span\u003eX_GLXIsDirect\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e Serial number of failed request: \u003cspan class=\"m\"\u003e207\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e Current serial number in output stream: \u003cspan class=\"m\"\u003e206\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e​可以发现最下面的log信息有一些异常,首先第一行是因为我们是Ubuntu系统,可以暂且不关注\u003c/p\u003e","title":"deepin-wine-qq-9.1.8版本无法正常启动的解决方案"},{"content":"前言 前一阵学校有五一数模节校赛,和朋友一起参加做B题,波士顿房价预测,算是第一次自己动手实现一个简单的小网络吧,虽然很简单,但还是想记录一下。\n题目介绍 波士顿住房数据由哈里森和鲁宾菲尔德于1978年Harrison and Rubinfeld1收集。它包括了波士顿大区每个调查行政区的506个观察值。1980年Belsley et al.2曾对此数据做过分析。\n数据一共14列,每一列的含义分别如下:\n英文简称 详细含义 CRIM 城镇的人均犯罪率 ZN 大于25,000平方英尺的地块的住宅用地比例。 INDUS 每个镇的非零售业务英亩的比例。 CHAS 查尔斯河虚拟变量(如果环河,则等于1;否则等于0) NOX 一氧化氮的浓度(百万分之几) RM 每个住宅的平均房间数 AGE 1940年之前建造的自有住房的比例 DIS 到五个波士顿就业中心的加权距离 RAD 径向公路通达性的指标 TAX 每一万美元的全值财产税率 PTRATIO 各镇的师生比率 B 计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例 LSTAT 底层人口的百分比(%) price 自有住房数的中位数,单位(千美元) 基于上述数据,请完成以下问题:\n建立波士顿房价预测模型并对预测结果进行评价。\n问题分析 首先这道题目的很明确,数据一共是 $506×14$ 的一个矩阵,有十三维的自变量,通过建立一个模型来拟合回归出最终的因变量 price,即户主拥有住房价值的中位数。这是一个回归问题,综合考虑有以下两个思路\n通过各种回归算法(GradientBoostingRegressor,RandomForestRegressor,ExtraTreesRegressor,LinearRegressor等)结合全部或部分自变量来回归最终的price\n建立前馈神经网络模型,根据通用逼近定理,我们可以拟合此回归模型。\n我们对上述模型来进行实现并确定评估标准来对他们进行比较,选择最优的模型作为预测模型。\n算法流程 传统的回归算法 自变量的选择 首先,考虑到数据集中13列自变量其中某一些可能和最终的房价并无强相关性,如果全部使用进行预测可能会对模型引入噪声,因此我们首先计算了房价price与各个自变量之间的相关系数 $r$ ,其中 $r$ 计算公式如下: $$ r = \\frac{\\sum(x_i-\\bar{x})(y_i-\\bar{y})}{\\sqrt{\\sum(x_i-\\bar{x})^2\\sum(y_i-\\bar{y})^2}} $$ 其中 $x_i,y_i$ 为数据的每个分量,$\\bar{x},\\bar{y}$ 为数据的均值\n该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下:\nCRIM ZN INDUS CHAS NOX RM LSTAT -0.385832 0.360445 -0.483725 0.175260 -0.427321 0.695360 -0.737663 AGE DIS RAD TAX PTRATIO B -0.376955 0.249929 -0.381626 -0.468536 -0.507787 0.333461 观察结果可以发现,在给定的十三个变量中,LSTAT 与 price 的相关程度最高$(|r|\u0026gt;0.7)$,其次是 RM 与PTRATIO $(|r|\u0026gt;0.5)$,再者是 TAX,INDUS,NOX $(|r|\u0026gt;0.4)$,除上述之外的七个变量都与 price 无较强的相关性,因此我们考虑使用六个相关性较强变量和十三个变量分别来对房价进行预测,并对他们进行对比,来寻找最优的回归模型。\n模型的构建 首先我们使用了sklearn中自带的 boston 数据集,并将整体数据集随机划分为了训练集和测试集两部分,所占比例分别为80%和20%。\n然后,我们利用Linear,Ridge,Lasso,ElasticNet,DecisionTree,GradientBoosting,RandomForest,ExtraTrees八种模型通过训练集对其进行训练。\n接下来,我们利用训练集拟合得到的模型,使用测试集对其进行测试,与 Ground Truth 进行对比,并通过 $R^2$ 来评价该预测结果,其中 $R^2$ 计算公式如下,其是衡量回归模型好坏的常见指标,其值一般处于[0,1]之间,$R^2$ 越接近1,说明模型的性能越好。 $$ R^2 = 1-\\frac{\\sum(\\hat{y_i}-y_i)^2}{\\sum(\\bar{y}-y_i)^2} $$\n最后,考虑到模型的训练及预测可能具有偶然性,因此我们对于每一个模型进行20次训练及预测,利用20次的结果对其进行综合评价。利用得到的结果绘制 箱线图 所得结果如下:\n分析最终结果可以发现,无论是使用六个相关性较强变量还是十三个变量来进行预测,GradientBoost(梯度提升决策树)回归模型都是最好的,此外,我们可以发现,利用十三个变量要比利用六个主要变量来进行预测比有着更好的效果。\n前馈神经网络 模型的构建 近年来,神经网络理论不断发展,前馈神经网络(多层感知机、全连接神经网络)越来越多的被利用到数据分析中,因此考虑使用前馈神经网络来解决此问题。\n前馈神经网络(全连接神经网络)的网络结构一般由三部分构成,输入层,隐藏层,以及输出层,输入层与输出层一般只有一层,隐藏层可有多层。中间利用非线性函数作为激活函数可以使得网络具有拟合非线性函数的能力\n根据通用近似定理:\n通用近似定理\n对于具有线性输出层和至少一个使用“挤压”性质的激活函数的隐藏层组成的前馈神经网络,只要其隐藏层神经元的数量足够,它可以以任意精度来近似任何从一个定义在实数空间中的有界闭集函数。\n只要隐藏层网络维度够高,就可以拟合任意的函数。\n考虑到我们的模型有六维or十三维的数据输入,因此我们建立两层前馈神经网络,中间具有一层隐藏层,维度为1000维,激活函数使用Relu,Relu函数有以下优点:\nRelu相比于传统的Sigmoid、Tanh,导数更加好求,反向传播就是不断的更新参数的过程,因为其导数不复杂形式简单,可以使得网络训练更快速。\n此外,当数值过大或者过小,Sigmoid,Tanh的导数接近于0,Relu为非饱和激活函数则不存在这种现象,可以很好的解决梯度消失的问题\nRelu函数及网络结构图如图所示:\n$$ Relu:f(x) = max(0,x) $$\n具体实现 利用流行的深度学习框架 Pytorch 来对模型进行实现。\n首先,将数据集随机划分为训练集和测试集两部分,分别占80%和20%,并将其转化为Pytorch中的张量形式。 然后,利用MinMaxScaler对输入数据进行归一化,利用下列公式将其统一归一化为 $[0,1]$ 之间,以求模型能够更快的收敛。 $$ MinMaxScaler:x^{*} = \\frac{x-min(x)}{max(x)-min(x)} $$\n接下来,构建网络模型,利用 mseloss 作为损失函数,在训练过程中利用反向传播使其最终收敛为0。 $$ MseLoss = \\frac{1}{2n}\\sum||y(x)-a^L(x)||^2 $$\n最后,我们设置网络的学习率为0.01,训练10000个epoch,发现其loss最终降低到0.3%左右,我们利用上文提到的 $R^2$ 对结果进行评估并与回归模型进行对比,通过观察图片可以发现,前馈神经网络相比于传统的回归模型有着更好的拟合效果, 20次预测得到的$R^2$平均值达到了0.95,此外中位数,最大值,最小值也要比回归模型更加优秀,因此我们采用前馈神经网络模型来对最后的房价进行预测。 最终预测 最终我们利用构建的前馈神经网络模型进行预测,利用测试集对其进行对比,绘制预测如下:\n​\n可以看到其中很多点都覆盖的很好,即预测准确。\n通过理论对模型进行量化分析,计算预测的 $R^2$ $$ R^2 = 1-\\frac{\\sum(\\hat{y_i}-y_i)^2}{\\sum(\\bar{y}-y_i)^2} = 1-0.01357 = 0.98643=98.643% $$ 可以发现 $R^2$ 十分接近1,说明回归模型性能良好,符合要求。\n实现代码 代码放在我的Github了,其中写了较详细的README,链接为 BostonPredict 参考链接 很系统的波士顿房价预测研究报告(期中作业)\n作业-机器学习-波士顿房价预测 四种回归算法\n基于Python预测波士顿房价\n波士顿房价预测——回归分析案例(献给初学者)\n","permalink":"https://blog.zzsqwq.cn/posts/182/","summary":"\u003ch3 id=\"前言\"\u003e前言\u003c/h3\u003e\n\u003cp\u003e前一阵学校有五一数模节校赛,和朋友一起参加做B题,波士顿房价预测,算是第一次自己动手实现一个简单的小网络吧,虽然很简单,但还是想记录一下。\u003c/p\u003e\n\u003ch3 id=\"题目介绍\"\u003e题目介绍\u003c/h3\u003e\n\u003cp\u003e波士顿住房数据由哈里森和鲁宾菲尔德于1978年Harrison and Rubinfeld\u003csup\u003e\u003ca href=\"https://blog.zzsqwq.cn/usr/uploads/2021/05/406125417.png\"\u003e1\u003c/a\u003e\u003c/sup\u003e收集。它包括了波士顿大区每个调查行政区的506个观察值。1980年Belsley et al.\u003csup\u003e\u003ca href=\"https://blog.zzsqwq.cn/usr/uploads/2021/05/3238192089.png\"\u003e2\u003c/a\u003e\u003c/sup\u003e曾对此数据做过分析。\u003c/p\u003e\n\u003cp\u003e数据一共14列,每一列的含义分别如下:\u003c/p\u003e\n\u003ctable\u003e\n \u003cthead\u003e\n \u003ctr\u003e\n \u003cth style=\"text-align: left\"\u003e英文简称\u003c/th\u003e\n \u003cth style=\"text-align: left\"\u003e详细含义\u003c/th\u003e\n \u003c/tr\u003e\n \u003c/thead\u003e\n \u003ctbody\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eCRIM\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e城镇的人均犯罪率\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eZN\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e大于25,000平方英尺的地块的住宅用地比例。\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eINDUS\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e每个镇的非零售业务英亩的比例。\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eCHAS\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e查尔斯河虚拟变量(如果环河,则等于1;否则等于0)\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eNOX\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e一氧化氮的浓度(百万分之几)\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eRM\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e每个住宅的平均房间数\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eAGE\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e1940年之前建造的自有住房的比例\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eDIS\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e到五个波士顿就业中心的加权距离\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eRAD\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e径向公路通达性的指标\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eTAX\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e每一万美元的全值财产税率\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003ePTRATIO\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e各镇的师生比率\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eB\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003eLSTAT\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e底层人口的百分比(%)\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003eprice\u003c/strong\u003e\u003c/td\u003e\n \u003ctd style=\"text-align: left\"\u003e自有住房数的中位数,单位(千美元)\u003c/td\u003e\n \u003c/tr\u003e\n \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003e基于上述数据,请完成以下问题:\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e建立波士顿房价预测模型并对预测结果进行评价。\u003c/strong\u003e\u003c/p\u003e\n\u003ch3 id=\"问题分析\"\u003e问题分析\u003c/h3\u003e\n\u003cp\u003e首先这道题目的很明确,数据一共是 $506×14$ 的一个矩阵,有十三维的自变量,通过建立一个模型来拟合回归出最终的因变量 price,即户主拥有住房价值的中位数。这是一个回归问题,综合考虑有以下两个思路\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e通过各种回归算法(GradientBoostingRegressor,RandomForestRegressor,ExtraTreesRegressor,LinearRegressor等)结合全部或部分自变量来回归最终的price\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e建立前馈神经网络模型,根据通用逼近定理,我们可以拟合此回归模型。\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e我们对上述模型来进行实现并确定评估标准来对他们进行比较,选择最优的模型作为预测模型。\u003c/p\u003e\n\u003ch3 id=\"算法流程\"\u003e算法流程\u003c/h3\u003e\n\u003ch4 id=\"传统的回归算法\"\u003e传统的回归算法\u003c/h4\u003e\n\u003ch5 id=\"自变量的选择\"\u003e自变量的选择\u003c/h5\u003e\n\u003cp\u003e首先,考虑到数据集中13列自变量其中某一些可能和最终的房价并无强相关性,如果全部使用进行预测可能会对模型引入噪声,因此我们首先计算了房价price与各个自变量之间的相关系数 $r$ ,其中 $r$ 计算公式如下:\n$$\nr = \\frac{\\sum(x_i-\\bar{x})(y_i-\\bar{y})}{\\sqrt{\\sum(x_i-\\bar{x})^2\\sum(y_i-\\bar{y})^2}}\n$$\n其中 $x_i,y_i$ 为数据的每个分量,$\\bar{x},\\bar{y}$ 为数据的均值\u003c/p\u003e\n\u003cp\u003e该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下:\u003c/p\u003e","title":"利用神经网络进行波士顿房价预测"},{"content":"前言 ​说起来的话今天距离比赛已经过去近一个月了,比赛结束一直想要记录一下and总结一下经验,但是实在是太懒了,临近五一假期,在四月的末尾为这次中国赛画一个句号吧。\n比赛过程 ​如果没记错的话比赛是3.30号(周二)去,4.1号(周四)结束,共三天。但是因为第三天没做什么有意义的事情,就只记录两天了。\n第一天 ​第一天大概中午十点到的吧,去的时候登记完领了牌,就在当地布置场地了。到了场地上才发现,我们好像是拿的东西最多的,包括外接显示屏和集成主机,好像都基本没人带过去····集成主机拿了过去也没怎么用到,本来预想用到的哨岗相机因为 ROS 的通信问题也没能跑成,最后两个机器人还是各跑各的策略了。\n​调试的时候出了一点问题,两个哨岗相机通过20m的USB延长线后,只有一个能连接,后来排查了一下,好像是因为有一条线是光纤USB3.0的线,跟相机的接口不兼容···这个问题还没想好怎么解决,可能会考虑到时候自己带一根USB延长线过去。\n​犹记得调试的时候是和青海大学一起调的,有点可惜的是调试中的我方机器人一直在一个地方鬼畜。那晚上我记得大家熬到了很晚···很可惜的视觉因为用的是学习的框架可调性很差,并没有帮上太大的忙。\n第二天 ​第二天记得一共有三场比赛,分别是打哈工大,哈工大深圳,以及青海大学。\n​在比赛过程中其实对视觉,我没有做太多的调整,主要还是大家在写导航和策略相关的东西吧。\n​跟哈工大打的那一场二车因为没有写好启动判定被罚下了,一车因为点位有问题一直卡在障碍物上。\n​跟哈工深和哈工大两场之间还隔了挺长时间,一个上午是一个下午,中间大家调试了很久,幸好在下午和哈工深打的时候基本没有鬼畜,可以正常的对局,只是因为实力不够强,很明显的一个问题就是视觉做的有问题吧,很多时间在朝着自己的队友打,还有就是会朝着场外的人员打,这是需要改进的点。\n​跟青海大学打的那场,距和哈工深比赛结束只有十几分钟的间隔时间,大家调了一个小bug就又重新赶去检录了,虽然当时已知青海大学的战术是站在原地不动的,但是由于不知道哪里出问题了,比赛中前一分钟两车都没动,后一分钟二车虽然动起来了去吃了加成区,但是因为定位的一些问题,没有看到敌方机器人并且撞墙了··自己撞掉了60血,最后还是败了QAQ。\n​所以就很耻辱的被3:0送走了,这样就结束了比赛日程。\n​值得反思的事情很多吧,赛前虽然基本熬了一个多星期来调车,还是只在最后一天才开始连裁判系统联调,包括暑假效率不高等问题都是值得反思的···打完比赛心中大概已经有了一些改进点,也想把自己的一些调车心得等记录下来,但是因为时间以及学业上的一些事情等一直没去做,本来计划的五月初做好改进的视觉也一直没兑现,希望这个五一假期会有较大的突破吧,不过还要打数模···好累,不想动。\n最后,这一天还拿到了和Charm young的合照,还挺动容的,之前看Robomaster的一个宣传标语就是让工程师们成为明星,给他们一个展示的舞台,看到大家对Charm young的热情,深深的感受到了这一点。\n","permalink":"https://blog.zzsqwq.cn/posts/173/","summary":"\u003ch4 id=\"前言\"\u003e前言\u003c/h4\u003e\n\u003cp\u003e​说起来的话今天距离比赛已经过去近一个月了,比赛结束一直想要记录一下and总结一下经验,但是实在是太懒了,临近五一假期,在四月的末尾为这次中国赛画一个句号吧。\u003c/p\u003e\n\u003ch4 id=\"比赛过程\"\u003e比赛过程\u003c/h4\u003e\n\u003cp\u003e​如果没记错的话比赛是3.30号(周二)去,4.1号(周四)结束,共三天。但是因为第三天没做什么有意义的事情,就只记录两天了。\u003c/p\u003e\n\u003ch5 id=\"第一天\"\u003e第一天\u003c/h5\u003e\n\u003cp\u003e​第一天大概中午十点到的吧,去的时候登记完领了牌,就在当地布置场地了。到了场地上才发现,我们好像是拿的东西最多的,包括外接显示屏和集成主机,好像都基本没人带过去····集成主机拿了过去也没怎么用到,本来预想用到的哨岗相机因为 ROS 的通信问题也没能跑成,最后两个机器人还是各跑各的策略了。\u003c/p\u003e\n\u003cp\u003e​调试的时候出了一点问题,两个哨岗相机通过20m的USB延长线后,只有一个能连接,后来排查了一下,好像是因为有一条线是光纤USB3.0的线,跟相机的接口不兼容···这个问题还没想好怎么解决,可能会考虑到时候自己带一根USB延长线过去。\u003c/p\u003e\n\u003cp\u003e​犹记得调试的时候是和青海大学一起调的,有点可惜的是调试中的我方机器人一直在一个地方鬼畜。那晚上我记得大家熬到了很晚···很可惜的视觉因为用的是学习的框架可调性很差,并没有帮上太大的忙。\u003c/p\u003e\n\u003ch5 id=\"第二天\"\u003e第二天\u003c/h5\u003e\n\u003cp\u003e​第二天记得一共有三场比赛,分别是打哈工大,哈工大深圳,以及青海大学。\u003c/p\u003e\n\u003cp\u003e​在比赛过程中其实对视觉,我没有做太多的调整,主要还是大家在写导航和策略相关的东西吧。\u003c/p\u003e\n\u003cp\u003e​跟哈工大打的那一场二车因为没有写好启动判定被罚下了,一车因为点位有问题一直卡在障碍物上。\u003c/p\u003e\n\u003cp\u003e​跟哈工深和哈工大两场之间还隔了挺长时间,一个上午是一个下午,中间大家调试了很久,幸好在下午和哈工深打的时候基本没有鬼畜,可以正常的对局,只是因为实力不够强,很明显的一个问题就是视觉做的有问题吧,很多时间在朝着自己的队友打,还有就是会朝着场外的人员打,这是需要改进的点。\u003c/p\u003e\n\u003cp\u003e​跟青海大学打的那场,距和哈工深比赛结束只有十几分钟的间隔时间,大家调了一个小bug就又重新赶去检录了,虽然当时已知青海大学的战术是站在原地不动的,但是由于不知道哪里出问题了,比赛中前一分钟两车都没动,后一分钟二车虽然动起来了去吃了加成区,但是因为定位的一些问题,没有看到敌方机器人并且撞墙了··自己撞掉了60血,最后还是败了QAQ。\u003c/p\u003e\n\u003cp\u003e​所以就很耻辱的被3:0送走了,这样就结束了比赛日程。\u003c/p\u003e\n\u003cp\u003e​值得反思的事情很多吧,赛前虽然基本熬了一个多星期来调车,还是只在最后一天才开始连裁判系统联调,包括暑假效率不高等问题都是值得反思的···打完比赛心中大概已经有了一些改进点,也想把自己的一些调车心得等记录下来,但是因为时间以及学业上的一些事情等一直没去做,本来计划的五月初做好改进的视觉也一直没兑现,希望这个五一假期会有较大的突破吧,不过还要打数模···好累,不想动。\u003c/p\u003e\n\u003cp\u003e最后,这一天还拿到了和Charm young的合照,还挺动容的,之前看Robomaster的一个宣传标语就是让工程师们成为明星,给他们一个展示的舞台,看到大家对Charm young的热情,深深的感受到了这一点。\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"https://blog.zzsqwq.cn/usr/uploads/2021/04/2816211838.jpg\" alt=\"与Charmyoung的合影\" /\u003e\n\u003c/p\u003e","title":"2021RoboMaster中国赛比赛记录"},{"content":"前言 最近使用Anaconda的时候遇到了一个很奇怪的问题,如当我新建环境 condatest 后,使用 pip -V 查看pip的路径指向,会发现pip指向的是另一个环境 CenterNet 的路径。搜索了很久得到一个有一些用的解决方法\n解决方案 设有问题的环境为 condatest ,python版本为 3.6\n然后进入 ~/anaconda3/envs/condatest/lib/python3.6\n编辑目录下的 site.py 文件,将其中的 USER_SITE 的值修改为 /home/zs/anaconda3/envs/condatest ,注意这里路径里面的 zs 是你的当前用户名, USER_BASE 的值修改为 /home/zs/anaconda3/envs/condatest/lib/python3.6/site.py,然后问题应该就解决了。\n因为如果环境问题的话,上面两个字符串都为空,猜测的原因是因为有同python版本的环境导致默认指向错误,此方式为修改conda中pip的指向。\n参考链接 更改conda环境中的pip包安装的默认路径 ","permalink":"https://blog.zzsqwq.cn/posts/169/","summary":"\u003ch3 id=\"前言\"\u003e前言\u003c/h3\u003e\n\u003cp\u003e最近使用Anaconda的时候遇到了一个很奇怪的问题,如当我新建环境 \u003cstrong\u003econdatest\u003c/strong\u003e 后,使用 \u003ccode\u003epip -V\u003c/code\u003e 查看pip的路径指向,会发现pip指向的是另一个环境 \u003cstrong\u003eCenterNet\u003c/strong\u003e 的路径。搜索了很久得到一个有一些用的解决方法\u003c/p\u003e\n\u003ch3 id=\"解决方案\"\u003e解决方案\u003c/h3\u003e\n\u003cp\u003e设有问题的环境为 \u003cstrong\u003econdatest\u003c/strong\u003e ,python版本为 \u003cstrong\u003e3.6\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e然后进入 \u003ccode\u003e~/anaconda3/envs/condatest/lib/python3.6\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e编辑目录下的 \u003ccode\u003esite.py\u003c/code\u003e 文件,将其中的 \u003ccode\u003eUSER_SITE\u003c/code\u003e 的值修改为 \u003ccode\u003e/home/zs/anaconda3/envs/condatest\u003c/code\u003e ,注意这里路径里面的 \u003ccode\u003ezs\u003c/code\u003e 是你的当前用户名, \u003ccode\u003eUSER_BASE\u003c/code\u003e 的值修改为 \u003ccode\u003e/home/zs/anaconda3/envs/condatest/lib/python3.6/site.py\u003c/code\u003e,然后问题应该就解决了。\u003c/p\u003e\n\u003cp\u003e因为如果环境问题的话,上面两个字符串都为空,猜测的原因是因为有同python版本的环境导致默认指向错误,此方式为修改conda中pip的指向。\u003c/p\u003e\n\u003ch3 id=\"参考链接\"\u003e参考链接\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://www.pythonf.cn/read/51713\"\u003e更改conda环境中的pip包安装的默认路径\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e","title":"关于Anaconda中pip路径指向问题"},{"content":"CenterNet—Objects as Points介绍 ​CenterNet是一个anchor-free的目标检测网络,与YOLOv3相比,精度有所提升,此外他不仅能够用于2D目标检测,也能够用于人体姿态识别,3D目标检测等···\n安装CenterNet ​其实安装CenterNet的过程就是一个配置环境的问题,直接跟着官方给出的这里Install.md配置一下即可,十分推荐使用Conda来管理环境,这里给出我的环境给大家参考一下:\nUbuntu = 18.04 LTS\npytorch = 1.2.0\npython = 3.6.12\ntorchvision = 0.4.0\ncuda = 10.2\n​需要注意的是:\n官方给出的教程里面使用的是 pytorch 0.4.1,但是我个人在实测过程中遇到了一些问题,遂安装网上的教程更改为 pytorch 1.2.0,并且需要把 ${CenterNet_Root}/src/lib/models/networks/DCNv2 中的这个DCNv2网络更改为官方的最新版。 这里使用的cuda版本最好和你的显卡匹配,之前因为显卡驱动的一些问题导致重装了电脑,根据我们学长学姐的建议,最好直接去cuda官网那边去下载deb包直接安装。 遇到环境配置问题可以先去Google一下,一般作者都在CenterNet\u0026rsquo;s Issues中给出了回复,如果没有,可以发邮件给作者询问,当然也可以发消息/邮箱给我,大家一起探讨一下~ 运行CenterNet的demo ​想要运行demo,首先要去 Model zoo 中下载一下我们需要使用的model,2D目标检测使用的是 ctdet_coco_dla_2x.pth ,人体姿态评估使用的是 multi_pose_dla_3x.pth ,下载后统一将他们放在CenterNet根目录中的model文件夹中。\n​然后使用conda切换到CenterNet的环境,在终端中运行:\npython demo.py ctdet --demo ${CenterNet_Root}/images/17790319373_bd19b24cfc_k.jpg --load_model ../models/ctdet_coco_dla_2x.pth ​这里需要注意的是 --demo 后面的 ${CenterNet_Root}/images/17790319373_bd19b24cfc_k.jpg ,这里我使用的是官方给出的实例图片,它位于CenterNet根目录的images文件夹中,前面的 ${CenterNet_Root} 代表的是 CenterNet根目录,好比我的就位于 /home/zs/CenterNet 。\n​如果不出意外的话效果应该如下图所示:\n运行CenterNet的3D目标检测 配置数据集和模型 ​我们可以直接参考官方的 DATA.md 来配置我们的数据集。\n​然后到 Model zoo 下载3D检测使用的模型 ddd_3dop.pth 。\n​这里说一下遇到的几个坑:\n首先是配置数据集的过程中,我们需要配置的目录结构如图所示(官方给出的结构树有点模糊不清的感觉)\n. ├── ImageSets_3dop │ ├── test.txt │ ├── train.txt │ ├── trainval.txt │ └── val.txt ├── ImageSets_subcnn │ ├── test.txt │ ├── train.txt │ ├── trainval.txt │ └── val.txt └── training ├── calib ├── image_2 └── label_2 然后去到 ${CenterNet_ROOT}/src/tools目录下,运行 python convert_kitti_to_coco.py 将 kitti 数据集转换为 coco 数据集的格式,不出意外应该会报错如下:\n这里的解决方案参考CenterNet中的一个Issue , How to generate the image dir in kitti? ,我们需要回到 data/kitti 目录下手动创建一个 annotations 文件夹,然后再回去运行转换程序。转换后目录结构如下:\n. ├── annotations │ ├── kitti_3dop_train.json │ ├── kitti_3dop_val.json │ ├── kitti_subcnn_train.json │ └── kitti_subcnn_val.json ├── ImageSets_3dop │ ├── test.txt │ ├── train.txt │ ├── trainval.txt │ └── val.txt ├── ImageSets_subcnn │ ├── test.txt │ ├── train.txt │ ├── trainval.txt │ └── val.txt └── training ├── calib ├── image_2 └── label_2 然后根据官方的教程,我们需要创建一个images文件夹,然后将其 training/image_2 链接到 images/trainval,我在实际的测试中,发现此方法并不可行。参考CenterNet中的一个Issue: Evaluate kitti\u0026ndash;AttributeError: \u0026lsquo;NoneType\u0026rsquo; object has no attribute \u0026lsquo;shape\u0026rsquo; ,其中 juanmed给出了解决方案:\nI had the same problem. For some reason the simlinks that are created during the data preparation process described in DATA.md are not working. So instead of creating simlinks I simply copied the actual data into the directories indicated in DATA.md. In other words the folders data/kitti/images/test and data/kitti/images/trainval do contain the actual images.\n意思就是说,我们在 images 中的图片必须都是真实的照片,而不能只是软链接过去。\n解决方案很显然,只需要在 images 文件夹中建立一个 trainval 文件夹,将 training/image_2 中的所有图像都移入其中即可。如果有test的照片,那么也照规在 images 新建一个 test 文件夹,把测试的照片移入其中即可。\n运行测试程序 接下来我们就可以根据官方给出的 GETTING_STARTED.md 来进行我们的检测了。\n即先编译一下评估工具,然后运行测试程序,但其实还是有一点点小问题。\n具体问题可以参考 Issus: kitti test: Couldn\u0026rsquo;t read: 006042.txt of ground truth.\nIssue下 lhyfst 已经给出了解决方案 :\nThe solution is quite simple. cd data/kitti mv label_2 label_val\n​ 更改后,运行成功~\n我们应该可以在 ${CenterNet_ROOT}/exp/ddd/3dop/results 看到我们得到的结果,只不过运行得到的是点的坐标,而不是图像,如果需要图像的话可能还需要自己绘制一下。\n","permalink":"https://blog.zzsqwq.cn/posts/164/","summary":"\u003ch2 id=\"centernetobjects-as-points介绍\"\u003eCenterNet—Objects as Points介绍\u003c/h2\u003e\n\u003cp\u003e​\u003ca href=\"https://github.com/xingyizhou/CenterNet\"\u003eCenterNet\u003c/a\u003e是一个anchor-free的目标检测网络,与YOLOv3相比,精度有所提升,此外他不仅能够用于2D目标检测,也能够用于人体姿态识别,3D目标检测等···\u003c/p\u003e\n\u003ch3 id=\"安装centernet\"\u003e安装CenterNet\u003c/h3\u003e\n\u003cp\u003e​其实安装\u003ca href=\"https://github.com/xingyizhou/CenterNet\"\u003eCenterNet\u003c/a\u003e的过程就是一个配置环境的问题,直接跟着官方给出的这里\u003ca href=\"https://github.com/xingyizhou/CenterNet/blob/master/readme/INSTALL.md\"\u003eInstall.md\u003c/a\u003e配置一下即可,十分推荐使用Conda来管理环境,这里给出我的环境给大家参考一下:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eUbuntu = 18.04 LTS\u003c/p\u003e\n\u003cp\u003epytorch = 1.2.0\u003c/p\u003e\n\u003cp\u003epython = 3.6.12\u003c/p\u003e\n\u003cp\u003etorchvision = 0.4.0\u003c/p\u003e\n\u003cp\u003ecuda = 10.2\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e​需要注意的是:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e官方给出的教程里面使用的是 \u003ccode\u003epytorch 0.4.1\u003c/code\u003e,但是我个人在实测过程中遇到了一些问题,遂安装网上的教程更改为 \u003ccode\u003epytorch 1.2.0\u003c/code\u003e,并且需要把 \u003ccode\u003e${CenterNet_Root}/src/lib/models/networks/DCNv2\u003c/code\u003e 中的这个\u003ca href=\"https://github.com/CharlesShang/DCNv2\"\u003eDCNv2\u003c/a\u003e网络更改为官方的最新版。\u003c/li\u003e\n\u003cli\u003e这里使用的cuda版本最好和你的显卡匹配,之前因为显卡驱动的一些问题导致重装了电脑,根据我们学长学姐的建议,最好直接去cuda官网那边去下载deb包直接安装。\u003c/li\u003e\n\u003cli\u003e遇到环境配置问题可以先去Google一下,一般作者都在CenterNet\u0026rsquo;s Issues中给出了回复,如果没有,可以发邮件给作者询问,当然也可以发消息/邮箱给我,大家一起探讨一下~\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"运行centernet的demo\"\u003e运行CenterNet的demo\u003c/h3\u003e\n\u003cp\u003e​想要运行demo,首先要去 \u003ca href=\"https://github.com/xingyizhou/CenterNet/blob/master/readme/MODEL_ZOO.md\"\u003eModel zoo\u003c/a\u003e 中下载一下我们需要使用的model,2D目标检测使用的是 \u003ca href=\"https://drive.google.com/open?id=1pl_-ael8wERdUREEnaIfqOV_VF2bEVRT\"\u003ectdet_coco_dla_2x.pth\u003c/a\u003e ,人体姿态评估使用的是 \u003ca href=\"https://drive.google.com/open?id=1PO1Ax_GDtjiemEmDVD7oPWwqQkUu28PI\"\u003emulti_pose_dla_3x.pth\u003c/a\u003e ,下载后统一将他们放在CenterNet根目录中的model文件夹中。\u003c/p\u003e\n\u003cp\u003e​然后使用conda切换到CenterNet的环境,在终端中运行:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003epython demo.py ctdet --demo \u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nv\"\u003eCenterNet_Root\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e/images/17790319373_bd19b24cfc_k.jpg --load_model ../models/ctdet_coco_dla_2x.pth \n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e​这里需要注意的是 \u003ccode\u003e--demo\u003c/code\u003e 后面的 \u003ccode\u003e${CenterNet_Root}/images/17790319373_bd19b24cfc_k.jpg\u003c/code\u003e ,这里我使用的是官方给出的实例图片,它位于CenterNet根目录的images文件夹中,前面的 \u003ccode\u003e${CenterNet_Root} \u003c/code\u003e 代表的是 CenterNet根目录,好比我的就位于 \u003ccode\u003e/home/zs/CenterNet\u003c/code\u003e 。\u003c/p\u003e\n\u003cp\u003e​如果不出意外的话效果应该如下图所示:\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"https://blog.zzsqwq.cn/usr/uploads/2021/01/2469782097.jpg\" alt=\"2D目标检测效果\" /\u003e\n\u003c/p\u003e\n\u003ch3 id=\"运行centernet的3d目标检测\"\u003e运行CenterNet的3D目标检测\u003c/h3\u003e\n\u003ch4 id=\"配置数据集和模型\"\u003e配置数据集和模型\u003c/h4\u003e\n\u003cp\u003e​我们可以直接参考官方的 \u003ccode\u003eDATA.md\u003c/code\u003e 来配置我们的数据集。\u003c/p\u003e\n\u003cp\u003e​然后到 \u003ca href=\"https://github.com/xingyizhou/CenterNet/blob/master/readme/MODEL_ZOO.md\"\u003eModel zoo\u003c/a\u003e 下载3D检测使用的模型 \u003ca href=\"https://drive.google.com/open?id=1znsM6E-aVTkATreDuUVxoU0ajL1az8rz\"\u003eddd_3dop.pth\u003c/a\u003e 。\u003c/p\u003e\n\u003cp\u003e​这里说一下遇到的几个坑:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e首先是配置数据集的过程中,我们需要配置的目录结构如图所示(官方给出的结构树有点模糊不清的感觉)\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e.\n├── ImageSets_3dop\n│   ├── test.txt\n│   ├── train.txt\n│   ├── trainval.txt\n│   └── val.txt\n├── ImageSets_subcnn\n│   ├── test.txt\n│   ├── train.txt\n│   ├── trainval.txt\n│   └── val.txt\n└── training\n ├── calib\n ├── image_2\n └── label_2\n\u003c/code\u003e\u003c/pre\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e然后去到 \u003ccode\u003e${CenterNet_ROOT}/src/tools\u003c/code\u003e目录下,运行 \u003ccode\u003epython convert_kitti_to_coco.py \u003c/code\u003e 将 \u003cstrong\u003ekitti\u003c/strong\u003e 数据集转换为 \u003cstrong\u003ecoco\u003c/strong\u003e 数据集的格式,不出意外应该会报错如下:\u003c/p\u003e","title":"如何使用CenterNet做3D目标检测测试"},{"content":"前言 最近在复习Git,因此顺手做个笔记分享出来,方便大家学习和查阅。相信无论是以后的课程作业还是工作,我们都会或多或少的接触/用到Git。\n什么是Git? Git你可能没听说过,但是我相信你应该听说过Github,毕竟是全球最大的同性交友网站。他和Git有着密不可分的联系,我们后续再详细介绍。\nGit的中文全称叫 分布式版本控制系统 ,版本控制系统是什么意思呢?我们举一个简单的例子,你在做一个大作业,很可能要写上千行的代码,但是你可能写完一个功能以后,对他不够满意,但是又害怕改了以后后悔了,又找不回来了,所以你可能就有很多版本,版本1,版本2,版本3等等等。Git就是解决这个问题的,让你文件能够保持最新,但是又能恢复到之前的版本。\n那么既然有分布式版本控制系统,就有 集中式版本控制系统,前者的代表是 Git ,后者的代表有 SVN、CVS 等。\n关于两者的区别,对于集中式版本控制系统,如果你想要对做一个项目的内容做修改,那么你要先从中央服务器把最近的版本拉取(Pull)下来,然后修改完以后,把修改后的版本推送(Push)上去,你本地只有最新的版本,而没有完整的版本库,分布式版本控制系统所作的工作与集中式的相差不大,只是它的本地会有一个完整的版本库,因此它十分的安全。\n这里贴一个他人总结的区别,供大家参考。\nGit的安装 Linux系统\n因为我只用过Ubuntu,所以我只会Ubuntu的QAQ..\nUbuntu中安装Git只需要在终端中输入 sudo apt-get install git 即可。\n如果是其他的linux系统,我猜你在终端中输入git即可获得安装提示,不然的话借助搜索引擎也可以。\nWindows系统\n直接去 Git官网 下载安装程序然后安装即可。关于安装时候的选项,我都是用的默认的。\nMac OS\n太穷了,没用过Mac,但是参考链接中给出了方法,大家有需求可以参考。\nGit的基本使用 Git可以做许多事情,好比版本更新,版本修改,提交到远程仓库等等,这里我们只写一写大概以后用的会比较多的。\n需要注意的是,我们安装以后大概会有一个 Git GUI 还有一个 Git Bash ,开发中多用 Git Bash,下面的教程也是基于Git Bash的。\n表明身份\n在Git所有仓库中我们都要有一个所有者的身份,用于标识是谁的仓库,用如下方式标识\ngit config --global user.name \u0026#34;Your Name\u0026#34; git config --global user.email \u0026#34;Your email\u0026#34; 创建版本库\n我们想要把一个文件夹的内容用git来管理,只需要在文件夹目录运行\ngit init 顾名思义这就是一个初始化的过程,运行以后在当前目录生成一个 .git 文件夹,里面是我们版本控制的数据,一般不要修改。\n把文件添加到Git的暂存区\n这里出现了 暂存区 这个名词,Git内部的逻辑大概把我们工作的过程分为了三部分\n一个是 工作区 ,这个就是我们本地的文件夹。 一个是 暂存区 ,这是我们把文件暂时放到暂存区里,没有决定更新我们的版本。 一个是 最终分支,这就是我们最终的版本存放的位置。 贴一张廖雪峰老师教程中的一张图,我觉得还挺形象的。\n我们清楚了上面的三个分区,那么考虑一下如何把文件夹中的文件从工作区推到暂存区,通过如下命令\ngit add filepath 我们就可以把文件推到暂存区,最后的filepath就是我们需要推送的文件的路径,一般都用相对路径。\n上面是添加单个文件的方法,我们也可以把目录中所有做过更改的文件都加到暂存区中,就用\ngit add . 从暂存区推送到最后分支\n我们可以把暂存区推送到最终分支,以完成我们的版本更新,通过\ngit commit -m \u0026#34;description\u0026#34; 其中description的内容是我们对该次版本更新的一次描述,好比增加什么功能。\n版本回退\n那么既然我们每次有更新版本,我们如何从最新的版本回退到之前的某个版本呢?\n这里我们需要了解到,我们有一个指针 HEAD 来指向我们当前的版本,因此我们只需要指定HEAD指针指向的版本,就可以做到更改版本。\ngit reset --hard 版本号 git reset --hard HEAD^ git reset --hard HEAD~cnt 这里三个命令都可以回退版本,每一个版本有一个版本号,可以指定版本号直接回到对应的版本。此外,通过 git reflog 可以查看每个版本的版本号。\n第二个和第三个有点像,都是往前回退几个版本,有几个^就是回退几个,后面cnt是几就回退几个。\n分支结构\nGit支持分支结构,可以使我们的版本管理变得十分有序,以不至于逻辑混乱。\nGit有一个初始主分支master,我们可以\n创建分支\ngit branch 分支名称 切换分支(两个命令都可以)\ngit switch 分支名称 git checkout 分支名称 创建并切换分支\ngit checkout -b 分支名称 好了,学了这些,其实就已经够让我们在日常生活中管理文件了,下面说一些用于团队合作的。\nGithub的作用 众所周知,一个大项目,想要一个人完成是很难的,大多数优秀的项目都是集思广益,大家一起出力建造出来的。\n我们上面提到的Github就是这样的一个平台,他是一个代码托管仓库,我们可以把新建一个仓库,然后把代码存储到上面,用的时候从上面Pull下来,而且只要经过你的同意,大家都可以为你的仓库贡献代码。由于这种开源的性质,Github有着许许多多优秀的项目,大家闲的没事可以去知乎搜搜Github上好玩的项目去玩一玩,好比 狗屁不通文章生成器 。\nGit与Github的协同 Git和Github密不可分,我们可以使用Git往Github上推送代码,从上面拉取代码等。\n从Github克隆代码\n我们如果想要从一个公有仓库中,把它的代码克隆到自己的本地,然后对他做一些应用。我们可以使用\ngit clone 仓库地址 这样就可以克隆仓库到本地,这里的仓库地址支持 https 或者 ssh 协议。\n推送本地仓库到Github\n首先我们要在Github上有一个自己的仓库,才能将自己的代码推送上去,因此需要在Github上创建自己的公有/私有仓库。\n然后我们在本地仓库做完修改,commit 以后,输入如下命令\ngit remote add origin 仓库地址 git push -u origin master 这两步一个是与远程仓库建立关联,一个是将代码push上去。\n通过这两步就可以把我们当地仓库推送到Github。\nGithub的Pull Request 项目需要团队合作,Pull Request就是为了团队协作而生的。\n你可以把他人的代码clone下来做完修改以后,向仓库所有者提交Pull Request,请求将自己的代码与他的代码合并,如果所有者同意,即可把你的代码合并到他的仓库中,以完成版本的更新,而你,就对这个项目做了一份贡献。\n那么如何提交Pull Request呢?\n对于对仓库有所有权的人来说,只需要把代码clone下来,然后创建并切换到自己的分支,对当前分支进行修改后,push到仓库中,然后创建合并请求即可。\n对于非仓库所有者而言,你需要先把代码 fork 下来,然后clone你 fork 的仓库,关联对方的远程仓库,修改后推上去,然后创建合并请求。\n大家对开源项目的贡献多是用第二种,自己团队内的协作多是第一种。\n一个总结 这篇文章讲的内容不多,QAQ只讲了部分我们可能用的比较多的。\n关于Git的基本使用,还有很多内容,好比 git merge ,git diff 啥的,我们用的可能比较少,我就没提。大家如果有需求可以翻下面的参考链接进行学习。\n之后的内容多是团队协作会用到的,大家可以有需要的时候再看。学会使用Git可以有效地帮助我们管理文件,进行团队协作,提高工作效率。\n关于后续的学习,大家可以选择 廖雪峰老师的Git教程 ,实例丰富、简单易懂,此外还有 Pro Git ,内容丰富,涵盖了基本所有的命令,以及Github上的一个开源项目 learnGitBranching ,有着可视化的界面与闯关机制,趣味十足。\n参考文档 廖雪峰的Git教程\nPro Git\n集中式(SVN)和分布式(Git)版本控制系统的简单比较\ngit学习-Github上如何进行PR(Pull Request)\npcottle/learnGitBranching: An interactive git visualization to challenge and educate! (github.com)\n","permalink":"https://blog.zzsqwq.cn/posts/157/","summary":"\u003ch3 id=\"前言\"\u003e前言\u003c/h3\u003e\n\u003cp\u003e最近在复习Git,因此顺手做个笔记分享出来,方便大家学习和查阅。相信无论是以后的课程作业还是工作,我们都会或多或少的接触/用到Git。\u003c/p\u003e\n\u003ch3 id=\"什么是git\"\u003e什么是Git?\u003c/h3\u003e\n\u003cp\u003eGit你可能没听说过,但是我相信你应该听说过Github,\u003cdel\u003e毕竟是全球最大的同性交友网站\u003c/del\u003e。他和Git有着密不可分的联系,我们后续再详细介绍。\u003c/p\u003e\n\u003cp\u003eGit的中文全称叫 \u003cstrong\u003e分布式版本控制系统\u003c/strong\u003e ,版本控制系统是什么意思呢?我们举一个简单的例子,你在做一个大作业,很可能要写上千行的代码,但是你可能写完一个功能以后,对他不够满意,但是又害怕改了以后后悔了,又找不回来了,所以你可能就有很多版本,版本1,版本2,版本3等等等。Git就是解决这个问题的,让你文件能够保持最新,但是又能恢复到之前的版本。\u003c/p\u003e\n\u003cp\u003e那么既然有分布式版本控制系统,就有 \u003cstrong\u003e集中式版本控制系统\u003c/strong\u003e,前者的代表是 \u003cstrong\u003eGit\u003c/strong\u003e ,后者的代表有 \u003cstrong\u003eSVN、CVS\u003c/strong\u003e 等。\u003c/p\u003e\n\u003cp\u003e关于两者的区别,对于集中式版本控制系统,如果你想要对做一个项目的内容做修改,那么你要先从中央服务器把最近的版本拉取(Pull)下来,然后修改完以后,把修改后的版本推送(Push)上去,你本地只有最新的版本,而没有完整的版本库,分布式版本控制系统所作的工作与集中式的相差不大,只是它的本地会有一个完整的版本库,因此它十分的安全。\u003c/p\u003e\n\u003cp\u003e这里贴一个他人总结的区别,供大家参考。\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"https://blog.zzsqwq.cn/usr/uploads/2020/12/2911747011.png\" alt=\"集中式与分布式版本控制系统的区别\" /\u003e\n\u003c/p\u003e\n\u003ch3 id=\"git的安装\"\u003eGit的安装\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eLinux系统\u003c/p\u003e\n\u003cp\u003e因为我只用过Ubuntu,所以我只会Ubuntu的QAQ..\u003c/p\u003e\n\u003cp\u003eUbuntu中安装Git只需要在终端中输入 \u003ccode\u003esudo apt-get install git\u003c/code\u003e 即可。\u003c/p\u003e\n\u003cp\u003e如果是其他的linux系统,我猜你在终端中输入git即可获得安装提示,不然的话借助搜索引擎也可以。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eWindows系统\u003c/p\u003e\n\u003cp\u003e直接去 \u003ca href=\"https://git-scm.com/downloads\"\u003eGit官网\u003c/a\u003e 下载安装程序然后安装即可。关于安装时候的选项,我都是用的默认的。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eMac OS\u003c/p\u003e\n\u003cp\u003e太穷了,没用过Mac,但是参考链接中给出了方法,大家有需求可以参考。\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"git的基本使用\"\u003eGit的基本使用\u003c/h3\u003e\n\u003cp\u003eGit可以做许多事情,好比版本更新,版本修改,提交到远程仓库等等,这里我们只写一写大概以后用的会比较多的。\u003c/p\u003e\n\u003cp\u003e需要注意的是,我们安装以后大概会有一个 \u003cstrong\u003eGit GUI\u003c/strong\u003e 还有一个 \u003cstrong\u003eGit Bash\u003c/strong\u003e ,开发中多用 \u003cstrong\u003eGit Bash\u003c/strong\u003e,下面的教程也是基于\u003cstrong\u003eGit Bash\u003c/strong\u003e的。\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e表明身份\u003c/p\u003e\n\u003cp\u003e在Git所有仓库中我们都要有一个所有者的身份,用于标识是谁的仓库,用如下方式标识\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit config --global user.name \u003cspan class=\"s2\"\u003e\u0026#34;Your Name\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit config --global user.email \u003cspan class=\"s2\"\u003e\u0026#34;Your email\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e创建版本库\u003c/p\u003e\n\u003cp\u003e我们想要把一个文件夹的内容用git来管理,只需要在文件夹目录运行\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit init\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e顾名思义这就是一个初始化的过程,运行以后在当前目录生成一个 \u003ccode\u003e.git\u003c/code\u003e 文件夹,里面是我们版本控制的数据,一般不要修改。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e把文件添加到Git的暂存区\u003c/p\u003e\n\u003cp\u003e这里出现了 \u003cstrong\u003e暂存区\u003c/strong\u003e 这个名词,Git内部的逻辑大概把我们工作的过程分为了三部分\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e一个是 \u003cstrong\u003e工作区\u003c/strong\u003e ,这个就是我们本地的文件夹。\u003c/li\u003e\n\u003cli\u003e一个是 \u003cstrong\u003e暂存区\u003c/strong\u003e ,这是我们把文件暂时放到暂存区里,没有决定更新我们的版本。\u003c/li\u003e\n\u003cli\u003e一个是 \u003cstrong\u003e最终分支\u003c/strong\u003e,这就是我们最终的版本存放的位置。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e贴一张廖雪峰老师教程中的一张图,我觉得还挺形象的。\u003c/p\u003e","title":"Git的简易教程"},{"content":"前言 因为最近Ubuntu用的比较频繁,所以前一阵把Ubuntu16.04换成Ubuntu18.04了,并且囿于机械硬盘那启动速度,我忍痛割爱把我80G的固态硬盘分给了Ubuntu。\n后来,用着用着就觉得这个Ubuntu的原始界面确实不是特别的好看,配色偏基佬紫的感觉。“工欲善其事,必先利其器“,我们只有将自己的工作环境布置的舒心一些才能有做下去的动力!所以我想给Ubuntu换一个看起来舒服点的界面,然后上网找教程乱七八糟的倒腾了一会,感觉换完以后完全不一样了,这个界面真的好看!!用起来也特别的舒心,感觉自己马上就要告别Windows投奔Linux的怀抱了。后续还有一些其他的优化,例如装QQ、微信、配置终端等,一并写在这里吧。\nUbuntu界面的优化 具体效果 先放几张效果图上来,是我改后的界面。大概就是这样(自我感觉挺好看的),当然也有其他的主题可供选择。\n1.安装GNOME桌面环境主题配置工具 如果要改主题,那么首先要有一个利器,这里我用的Ubuntu18.04,桌面环境为 GNOME 3.28.2 ,因为我目前接触的只有GNOME桌面环境的,Ubuntu18.04本来的桌面环境就是GNOME,但是Ubuntu16.04好像没有自带,但是可以安装,这里大家可以自行百度了解。\n然后我们已经有了GNOME桌面环境后,安装主题配置工具 GNOME Tweaks ,在终端中输入如下内容:\nsudo apt-get update sudo apt-get install gnome-tweak-tool 我们先更新软件源,然后安装后直接打开他就行,在系统软件中中文大概叫 优化 。\n2.拓展上述工具 安装完上述工具后,我们可能发现了一个问题,就是外观那一栏目的Shell有一个感叹号,无法更改,这是因为我们没有安装拓展导致的。我们在终端中运行\nsudo apt-get install gnome-shell-extensions 然后重启一下电脑。再打开软件找到左侧的拓展,把 User themes 那一栏目打开。切换回去就可以发现Shell那边的感叹号无了。\n3.寻找自己喜欢的主题 这里我大家可以去这个网址去找自己喜欢的 GNOME-LOOK.ORG\n这里面包含了图标,主题这些,下面介绍一下如何安装。\n好比我们找到一个自己喜欢的主题,然后我们点击下面的 Files ,可能会有很多文件,但是多是同一个主题的不同风格,好比暗风格和亮风格这样的,还有不同的版本的,我多是安装那个下载量最多的,我们下载那个对应的文件(多是tar.xz安装包)。\n对于主题的安装,我们只需要把解压出来的文件,移动或复制到 /usr/share/themes/ 目录下,如果是光标\\图标的安装,那么就把文件夹移动到 /usr/share/icons 目录下。\n然后我们回到 GNOME Tweaks 软件中就可以发现,我们已经可以在主题\\图标\\光标\\Shell清单中找到我们移动到文件夹中的文件了,然后选择就可以切换了。这里需要注意的,很多主题都是自带Shell的,你下了一个主题,那么你可以在Shell和主题这两个栏目中都找到他们,是一个配套的。\n4.一些后续的调整 我们后续可以改变左边收藏夹的位置,我觉得放在左边有一丢丢的丑,所以我选择把它放在的下面。\n我们去Ubuntu软件中搜索 Dash to dock,然后安装这个拓展,然后打开 GNOME Tweaks 软件在拓展中找到他就可以随心所欲的调我们的收藏夹的位置了。\n5.我自己的配置 theme\u0026amp;shell Canta-light-compact icons 01-McMojave-circle 6.界面修改的参考链接 Ubuntu18.04美化主题(mac主题) Ubuntu18.04美化主题(完整版) GNOME-LOOK.ORG 30个非常不错的Ubuntu主题供你选择 ubuntu18.04更换鼠标游标主题 配置终端 前言 唔,终端本来用起来感觉也还行,感觉终端就是linux的灵魂,啥都能干。\n但是听说有更好用的终端,现在ubuntu普遍用的好像都是bash,但是好像还有zsh,fish这样的,他们可以有一些代码补全,功能更强,可拓展性也高,大家都zsh和fish哪个好用一直争执不停,但是我发现ROS对 zsh 支持的很好,但是对 fish 的支持有点拉胯,考虑到以后可能ros会用的比较多,因此我选择使用zsh。效果图如下\n1.下载zsh 直接在终端执行下列语句\nsudo apt-get update sudo apt-get install zsh 2.安装oh my zsh zsh其实配置起来很麻烦,这一点相比与fish不太行,fish下载下来就已经具备了常用的功能,例如代码补全等。\n但是我们有先人铺路,在Github上有一个开源的项目 oh my zsh,就是专门用来导入这个zsh的配置的,\n我们直接运行如下代码,就可以直接安装了\nwget sh -c \u0026#34;$(wget -O- https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)\u0026#34; 然后我们可以通过在终端中输入zsh来切换到zsh,也可以通过输入bash切换回去\n我们也可以通过如下命令来切换默认的终端系统,首先查找一下zsh的目录,然后切换过去。\nwhereis zsh chsh -s zsh路径 3.配置插件 在zsh里面有许多好用的插件,在这里推荐两个\n自动补全 zsh-autosuggestions 语法高亮 zsh-syntax-highlighting 关于下载的方法,在这两个项目里面都说了,我们只需要把下载的文件放到 ~/.oh-my-zsh/plugins 目录中,然后编辑 ~/.zshrc 在 plugin = (插件1 插件2) 写上你所要启用的插件名称即可。\n然后在终端中 source ~/.zshrc 更新一下配置即可。\n4.配置主题 zsh有许多可用的主题选择,我自己最喜欢的一个叫 pure\n我觉得害挺好看的,效果就跟上图一样吧。\n安装方法就是先把pure下载到一个路径,然后编辑 ~/.zshrc\n在下面加入\nfpath+=安装路径 autoload -U promptinit; promptinit prompt pure 然后我们source一下.zshrc 就可以使用了。\n但是如果是使用zsh本来自带的一些主题,和这个有些差别,只需要下载好主题然后放到 ~/.oh-my-zsh/themes ,然后在 .zshrc 中启用即可。\n5.参考链接 linux终端shell:zsh配置和使用\nzsh和oh-my-zsh的一些好用的主题和插件\nlinux安装oh my zsh终端及简单使用方法\n配置oh-my-zsh主题\nZsh 常用插件\n给Zsh添加主题和插件\n常用的oh-my-zsh插件\n还有一些其他的配置有时间再写吧……咕咕咕\n","permalink":"https://blog.zzsqwq.cn/posts/141/","summary":"\u003ch3 id=\"前言\"\u003e前言\u003c/h3\u003e\n\u003cp\u003e因为最近Ubuntu用的比较频繁,所以前一阵把Ubuntu16.04换成Ubuntu18.04了,并且囿于机械硬盘那启动速度,我忍痛割爱把我80G的固态硬盘分给了Ubuntu。\u003c/p\u003e\n\u003cp\u003e后来,用着用着就觉得这个Ubuntu的原始界面确实不是特别的好看,\u003cdel\u003e配色偏基佬紫的感觉\u003c/del\u003e。“工欲善其事,必先利其器“,我们只有将自己的工作环境布置的舒心一些才能有做下去的动力!所以我想给Ubuntu换一个看起来舒服点的界面,然后上网找教程乱七八糟的倒腾了一会,感觉换完以后完全不一样了,这个界面真的好看!!用起来也特别的舒心,感觉自己马上就要告别Windows投奔Linux的怀抱了。后续还有一些其他的优化,例如装QQ、微信、配置终端等,一并写在这里吧。\u003c/p\u003e\n\u003ch3 id=\"ubuntu界面的优化\"\u003eUbuntu界面的优化\u003c/h3\u003e\n\u003ch4 id=\"具体效果\"\u003e具体效果\u003c/h4\u003e\n\u003cp\u003e先放几张效果图上来,是我改后的界面。大概就是这样(自我感觉挺好看的),当然也有其他的主题可供选择。\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"https://blog.zzsqwq.cn/usr/uploads/2020/12/171170690.png\" alt=\"桌面风格\" /\u003e\n\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"https://blog.zzsqwq.cn/usr/uploads/2020/12/3724154221.png\" alt=\"文件夹风格\" /\u003e\n\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"https://blog.zzsqwq.cn/usr/uploads/2020/12/3559388649.png\" alt=\"效果图\" /\u003e\n\u003c/p\u003e\n\u003ch4 id=\"1安装gnome桌面环境主题配置工具\"\u003e1.安装GNOME桌面环境主题配置工具\u003c/h4\u003e\n\u003cp\u003e如果要改主题,那么首先要有一个利器,这里我用的\u003ccode\u003eUbuntu18.04\u003c/code\u003e,桌面环境为 \u003ccode\u003eGNOME 3.28.2\u003c/code\u003e ,因为我目前接触的只有GNOME桌面环境的,Ubuntu18.04本来的桌面环境就是GNOME,但是Ubuntu16.04好像没有自带,但是可以安装,这里大家可以自行百度了解。\u003c/p\u003e\n\u003cp\u003e然后我们已经有了GNOME桌面环境后,安装主题配置工具 \u003ccode\u003eGNOME Tweaks \u003c/code\u003e ,在终端中输入如下内容:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo apt-get update\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo apt-get install gnome-tweak-tool \n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e我们先更新软件源,然后安装后直接打开他就行,在系统软件中中文大概叫 \u003cstrong\u003e优化\u003c/strong\u003e 。\u003c/p\u003e\n\u003ch4 id=\"2拓展上述工具\"\u003e2.拓展上述工具\u003c/h4\u003e\n\u003cp\u003e安装完上述工具后,我们可能发现了一个问题,就是外观那一栏目的Shell有一个感叹号,无法更改,这是因为我们没有安装拓展导致的。我们在终端中运行\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo apt-get install gnome-shell-extensions\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e然后重启一下电脑。再打开软件找到左侧的拓展,把 \u003ccode\u003eUser themes\u003c/code\u003e 那一栏目打开。切换回去就可以发现Shell那边的感叹号无了。\u003c/p\u003e\n\u003ch4 id=\"3寻找自己喜欢的主题\"\u003e3.寻找自己喜欢的主题\u003c/h4\u003e\n\u003cp\u003e这里我大家可以去这个网址去找自己喜欢的 \u003ca href=\"https://www.gnome-look.org\"\u003eGNOME-LOOK.ORG\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e这里面包含了图标,主题这些,下面介绍一下如何安装。\u003c/p\u003e\n\u003cp\u003e好比我们找到一个自己喜欢的主题,然后我们点击下面的 \u003cstrong\u003eFiles\u003c/strong\u003e ,可能会有很多文件,但是多是同一个主题的不同风格,好比暗风格和亮风格这样的,还有不同的版本的,我多是安装那个下载量最多的,我们下载那个对应的文件(多是tar.xz安装包)。\u003c/p\u003e\n\u003cp\u003e对于主题的安装,我们只需要把解压出来的文件,移动或复制到 \u003ccode\u003e/usr/share/themes/\u003c/code\u003e 目录下,如果是光标\\图标的安装,那么就把文件夹移动到 \u003ccode\u003e/usr/share/icons\u003c/code\u003e 目录下。\u003c/p\u003e\n\u003cp\u003e然后我们回到 \u003ccode\u003eGNOME Tweaks\u003c/code\u003e 软件中就可以发现,我们已经可以在主题\\图标\\光标\\Shell清单中找到我们移动到文件夹中的文件了,然后选择就可以切换了。这里需要注意的,很多主题都是自带Shell的,你下了一个主题,那么你可以在Shell和主题这两个栏目中都找到他们,是一个配套的。\u003c/p\u003e\n\u003ch4 id=\"4一些后续的调整\"\u003e4.一些后续的调整\u003c/h4\u003e\n\u003cp\u003e我们后续可以改变左边收藏夹的位置,我觉得放在左边有一丢丢的丑,所以我选择把它放在的下面。\u003c/p\u003e\n\u003cp\u003e我们去Ubuntu软件中搜索 Dash to dock,然后安装这个拓展,然后打开 \u003ccode\u003eGNOME Tweaks\u003c/code\u003e 软件在拓展中找到他就可以随心所欲的调我们的收藏夹的位置了。\u003c/p\u003e\n\u003ch4 id=\"5我自己的配置\"\u003e5.我自己的配置\u003c/h4\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003etheme\u0026amp;shell Canta-light-compact\nicons 01-McMojave-circle\n\u003c/code\u003e\u003c/pre\u003e\u003ch4 id=\"6界面修改的参考链接\"\u003e6.界面修改的参考链接\u003c/h4\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://blog.csdn.net/lishanleilixin/article/details/80453565\"\u003eUbuntu18.04美化主题(mac主题)\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://blog.csdn.net/qq_42527676/article/details/91356154\"\u003eUbuntu18.04美化主题(完整版)\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.gnome-look.org\"\u003eGNOME-LOOK.ORG\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.jianshu.com/p/4fb5e4657695\"\u003e30个非常不错的Ubuntu主题供你选择\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://blog.csdn.net/maodexuedinge_/article/details/106652323\"\u003eubuntu18.04更换鼠标游标主题\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"配置终端\"\u003e配置终端\u003c/h3\u003e\n\u003ch4 id=\"前言-1\"\u003e前言\u003c/h4\u003e\n\u003cp\u003e唔,终端本来用起来感觉也还行,感觉终端就是linux的灵魂,啥都能干。\u003c/p\u003e","title":"Ubuntu18.04优化教程"},{"content":"“程序星编程之路”第二次作业题解 A. Zs的回文质数 题目描述 读入一个整数 $n$ ,输出 $[1,n]$ 的所有回文质数,我们规定 $1\\sim9$ 也是回文数。\n思路 首先我们需要了解什么是回文数,以及什么是质数。\n简单点说,回文数就是正着读反着读都是一样的,也就是对称的,形如 $abcba $ 或者 $123321$ 这样的。\n质数的话,对于一个数 $n$ ,如果他是质数,那它除了 $1$ 和 $n$ 没有其他因子。例如 $2,3,5,7,11$ 这样的。\n那么接下来我们考虑一下解决这个问题应该怎么做,首先我们看一下数据范围,$[1,100000]$ ,还是挺小的,我们可以考虑直接枚举每一个数来判断它是不是回文数,然后再判断一下是不是质数,如果两个都满足,我们就输出它。\n判断回文数,我们可以考虑到 NOJ05 幸运数 一题的解题思路,也就是说我们把一个数倒置过来,好比一个数 $xyz$ 倒置成 $zyx$ ,然后判断是否 $xyz == zyx$ ,如果相等的话就是回文数,如果不相等就不是。\n判断质数,我们可以在 $[2,\\lfloor\\sqrt{n}\\rfloor]$ 枚举它的因子,这个的完备性我上课的时候证明过,不再赘述。这里需要注意 $1,2$ 需要特判一下。\n代码 #include\u0026lt;stdio.h\u0026gt; #include\u0026lt;math.h\u0026gt; //我们需要用到sqrt函数,因此需要引入数学库 int main() { int n; bool flag = false; // 标记 i 是否满足条件 scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { flag = true; int p=i,j=0; while(p) // 将 p 反转为 j { j=j*10+p%10; p/=10; } if(j==i) { if(j==1) continue; // 特判 1 if(j==2) // 特判 2 { printf(\u0026#34;2\\n\u0026#34;); continue; } int sqrtj = sqrt(j); for(int k=2;k\u0026lt;=sqrtj;k++) // 枚举 [2,sqrt(n)] { if(j%k==0) // 如果能够整除(余数为0),那么是 j 的因子 { flag = false; break; } } if(flag) { printf(\u0026#34;%d\\n\u0026#34;,j); } } } } 其他 因为我们讲到这里的时候,我们没讲函数,但是这道题如果我们把判断是否为回文数,判断是否为质数,都另成一个函数模块,将使得程序变得更加简洁。我在这里也将函数版本的贴出来,有兴趣的可以看一下。\n#include\u0026lt;stdio.h\u0026gt; #include\u0026lt;math.h\u0026gt; bool isprime(int k) //判断是否为质数,如果是质数返回true,如果不是返回false { if(k==1) return false; if(k==2) return true; for(int i=2;i\u0026lt;=sqrt(k);i++) { if(k%i==0) return false; } return true; } bool ishw(int k) //判断是否为回文数,如果是返回true,如果不是返回false { int ans=0; int temp = k; //temp作为一个k的复制版,因为后续需要用到k,新定义一个作为备份 while(k) { ans = ans*10 + k%10; k/=10; } if(temp == ans) { return true; } else return false; } int main() { int n; scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { if(isprime(i) \u0026amp;\u0026amp; ishw(i)) //如果既是质数也是回文数 { printf(\u0026#34;%d\\n\u0026#34;,i); } } } B. Wcx的杨辉三角 题目描述 读入一个整数 $n$ ,输出杨辉三角的前 $n$ 行。\n思路 首先这道题我们需要了解一下杨辉三角 ,大家小学到高中应该都了解过。\n那么如何计算杨辉三角,首先我们可以知道的是杨辉三角的第 $i$ 行就是$C_i^0\\sim C_i^i$ ,但是我们考虑一下如何计算组合数,是用阶乘对吧,但是阶乘就涉及到一个连乘,对于这个题,我数据范围写的是 $1\\le n \\le 40$ ,很明显,阶乘不可行。而且写起来挺麻烦的。\n那么我们考虑一个组合数的性质 $$ C_n^i = C_{n-1}^i + C_{n-1}^{i-1} $$\n看起来很高大上对吧,简单点说就是杨辉三角里面一个数的值等于两肩之和,那么基于这个性质,我们很容易想到,我们可以用一个二维数组,定义 $f[i][j]$ 为第 $i$ 行的第 $j$ 个数,那么可以得到\n当 $j==1$ 或 $j==i$ ,则 $f[i][j] = 1$ ,也就是,当它为这一行的第一个或者最后一个,那么它就是 $1$\n如果不是上述条件,则 $f[i][j] = f[i-1][j] + f[i-1][j-1]$ ,也就是等于两肩之和。\n还有一个需要注意的问题就是,这个题的 $n$ 最大值是 40,这个时候已经超出了 $int$ 的范围,因此我们需要将二维数组定义为 $long: :long$ 。\n代码 #include\u0026lt;stdio.h\u0026gt; int main() { long long a[105][105] = {0}; //全都初始化为 0 int n = 0; scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) //这里我用的是 1~n 而不是 0~n-1 { for(int j=1;j\u0026lt;=i;j++) { if(j==1 || j==i) { printf(\u0026#34;%lld \u0026#34;,a[i][j]=1); } else { printf(\u0026#34;%lld \u0026#34;,a[i][j]=a[i-1][j-1]+a[i-1][j]); } } printf(\u0026#34;\\n\u0026#34;); } } 其他 这道题主要是对二维数组的考察。\n注意我们遇到第五个点过不去的时候,应该试一下最大的值 $40$ ,会发现有负数,显然是溢出问题,我们就能知道问题的解决办法了。\nC. Zh的约瑟夫环问题 题目描述 有 $n$ 个人围成一圈,顺序排号,从第一个开始报数(从 $1$ 到 $m$ 报数),凡报到 $m$ 的人退出圈子,问最后留下的是几号.\n思路 约瑟夫问题是个很经典的问题,可能又叫什么猴子选大王什么的,特多变体。\n这个题其实就是一个纯模拟题,主要是对数组的考察。我们可以考虑开一个布尔数组 vis 用来标记某个人是否出圈,如果出圈了我们给他设置为 true ,如果没有出圈就是 false 。\n然后开一个报数到多少的变量cnt,开一个当前谁报数的变量pot,然后来模拟这个过程。如果 cnt 增长到了 m ,我们将 pot 出圈,也就是 vis[pot] = true ,然后在场的人数减一,当只剩下一人的时候,我们遍历 vis 数组中的每个元素,如果它的 vis 值为 false ,即没有出队,则将他输出。\n还有一个要注意的问题就是这是一个环,那么我们只需要判断一下当 pot 为 $n+1$ 的时候将他置为 $1$ 即可,这就模拟了一个环的性质。\n代码 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; int n,m; int vis[1005]; //vis[i] = true 已经淘汰 vis[i] = false 未被淘汰 int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;m); int cnt = 1; //报数到多少 int pot = 1; //当前是谁报数 int exist = n; //在场的人数 while(exist \u0026gt; 1) { cnt=0; while(1) { if(!vis[pot]) //如果没有出圈 { cnt++; if(cnt==m) { vis[pot] = true; exist--; break; } } pot++; if(pot==n+1) pot=1; //模拟环 } } for(int i=1;i\u0026lt;=n;i++) { if(vis[i] == false) printf(\u0026#34;%d\u0026#34;,i); } return 0; } 其他 上面的想法是比较好理解的形式。\n我们考虑一下模拟环,也就是使得 pot 指针处在一定的范围内,如果超出了将他重新置到头部,那么我们可以联想到取模,在模拟环时使用取模来实现,大家可以下去自己尝试,这有点像魏辰旭第一节课讲的那个字符串的问题。\n因为这道题只关心谁活了下来,所以还有一个比较简单的解法,我看在作业中也有几位同学给出了这个较简单的解法,如果理解了上述思想,看这个代码应该不难理解,大家可以对照代码自行思考。\n#include\u0026lt;stdio.h\u0026gt; int n,m; int pot = 0; int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;m); for(int i=2;i\u0026lt;=n;i++) { pot = (pot+m)%i; } printf(\u0026#34;%d\u0026#34;,pot+1); } 提示:n个人的约瑟夫环杀掉一个人后组成一个新的人数为 n-1 的约瑟夫环\n","permalink":"https://blog.zzsqwq.cn/posts/136/","summary":"\u003ch2 id=\"程序星编程之路第二次作业httpswwwluogucomcncontest36509题解\"\u003e\u003ca href=\"https://www.luogu.com.cn/contest/36509\"\u003e“程序星编程之路”第二次作业\u003c/a\u003e题解\u003c/h2\u003e\n\u003ch3 id=\"a-zs的回文质数httpswwwluogucomcnproblemu138527contestid36509\"\u003eA. \u003ca href=\"https://www.luogu.com.cn/problem/U138527?contestId=36509\"\u003eZs的回文质数\u003c/a\u003e\u003c/h3\u003e\n\u003ch4 id=\"题目描述\"\u003e题目描述\u003c/h4\u003e\n\u003cp\u003e读入一个整数 $n$ ,输出 $[1,n]$ 的所有回文质数,我们规定 $1\\sim9$ 也是回文数。\u003c/p\u003e\n\u003ch4 id=\"思路\"\u003e思路\u003c/h4\u003e\n\u003cp\u003e首先我们需要了解什么是\u003ca href=\"https://baike.baidu.com/item/%E5%9B%9E%E6%96%87%E6%95%B0\"\u003e回文数\u003c/a\u003e,以及什么是\u003ca href=\"https://baike.baidu.com/item/%E8%B4%A8%E6%95%B0\"\u003e质数\u003c/a\u003e。\u003c/p\u003e\n\u003cp\u003e简单点说,回文数就是正着读反着读都是一样的,也就是对称的,形如 $abcba $ 或者 $123321$ 这样的。\u003c/p\u003e\n\u003cp\u003e质数的话,对于一个数 $n$ ,如果他是质数,那它除了 $1$ 和 $n$ 没有其他因子。例如 $2,3,5,7,11$ 这样的。\u003c/p\u003e\n\u003cp\u003e那么接下来我们考虑一下解决这个问题应该怎么做,首先我们看一下数据范围,$[1,100000]$ ,还是挺小的,我们可以考虑直接枚举每一个数来判断它是不是回文数,然后再判断一下是不是质数,如果两个都满足,我们就输出它。\u003c/p\u003e\n\u003cp\u003e判断回文数,我们可以考虑到 NOJ05 幸运数 一题的解题思路,也就是说我们把一个数倒置过来,好比一个数 $xyz$ 倒置成 $zyx$ ,然后判断是否 $xyz == zyx$ ,如果相等的话就是回文数,如果不相等就不是。\u003c/p\u003e\n\u003cp\u003e判断质数,我们可以在 $[2,\\lfloor\\sqrt{n}\\rfloor]$ 枚举它的因子,这个的完备性我上课的时候证明过,不再赘述。这里需要注意 $1,2$ 需要特判一下。\u003c/p\u003e\n\u003ch4 id=\"代码\"\u003e代码\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C++\" data-lang=\"C++\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u0026lt;stdio.h\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u0026lt;math.h\u0026gt; \u003c/span\u003e\u003cspan class=\"c1\"\u003e//我们需要用到sqrt函数,因此需要引入数学库\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003en\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"n\"\u003eflag\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 标记 i 是否满足条件\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003escanf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003en\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;=\u003c/span\u003e\u003cspan class=\"n\"\u003en\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eflag\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 将 p 反转为 j \n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"o\"\u003e+\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"o\"\u003e%\u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"o\"\u003e/=\u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"o\"\u003e==\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"o\"\u003e==\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"k\"\u003econtinue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 特判 1\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"o\"\u003e==\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 特判 2\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;2\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003econtinue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003esqrtj\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003esqrt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ek\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"n\"\u003ek\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;=\u003c/span\u003e\u003cspan class=\"n\"\u003esqrtj\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"n\"\u003ek\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 枚举 [2,sqrt(n)]\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"o\"\u003e%\u003c/span\u003e\u003cspan class=\"n\"\u003ek\u003c/span\u003e\u003cspan class=\"o\"\u003e==\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 如果能够整除(余数为0),那么是 j 的因子\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eflag\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eflag\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;%d\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"其他\"\u003e其他\u003c/h4\u003e\n\u003cp\u003e因为我们讲到这里的时候,我们没讲函数,但是这道题如果我们把判断是否为回文数,判断是否为质数,都另成一个函数模块,将使得程序变得更加简洁。我在这里也将函数版本的贴出来,有兴趣的可以看一下。\u003c/p\u003e","title":"“程序星编程之路”第二次作业题解"},{"content":"Windows 平台 Visual Studio 2019 中 OpenCV 配置教程 前言 我这里配置用的是4.5.0版本,但实际配置过程中需要的大部分时间只是路径,因此和版本基本无关。\n只有一个地方是和版本有关系的,在配置链接器的 opencv_wordxyzd.lib 时,大家一定要注意!!\n1.下载OpenCV 首先我们进入 https://opencv.org/releases/ 在这其中下载OpenCV ,我这里下载的4.5.0 ,选择Windows下载即可。\n下载结束后我们双击安装包,指定解压目录,我这里解压在了我的G盘,具体路径为 G:\\Opencv450\n2.设置OpenCV的环境变量 我们在 此电脑右键 -\u0026gt; 属性 -\u0026gt; 高级系统设置 -\u0026gt; 环境变量 -\u0026gt; 系统变量 -\u0026gt; 双击Path -\u0026gt;添加如下的环境\nG:\\Opencv450\\build\\x64\\vc15\\bin ,这里的路径是根据上面那个路径来看的,如果你上面那个跟我不同,也请看请自己的路径。\n配置Visual Studio 新建一个C++类型的空项目,随便你如何命名,将模式调节为 Debug x64 依次点击 视图 -\u0026gt; 其他窗口 -\u0026gt; 属性管理器\n在打开的 属性管理器 中添加新项目属性表,我是4.5.0的版本,为了好记,新建属性表命名为OpenCV450Debug\n建好以后在其上右键,选择属性 ,然后依次选择 VC++ 目录 -\u0026gt; 包含目录 -\u0026gt; 编辑\n添加下面两个路径,当然,这两个路径也是取决于你安装OpenCV的路径的。\nG:\\Opencv450\\build\\include\nG:\\Opencv450\\build\\include\\opencv2\n接下来选择 VC++ 目录 中的 库目录 -\u0026gt; 编辑 ,然后添加(与你OpenCV路径对应)\nG:\\Opencv450\\build\\x64\\vc15\\lib\n接下来选择 链接器 -\u0026gt; 输入 -\u0026gt; 附加依赖项 -\u0026gt; 编辑\n在其中加入 opencv_world450d.lib ! 大家这里请注意,不同的版本这里的添加名称不同,通常来说如果你的版本是 x.y.z 那么就是 opencv_worldxyzd.lib\n最后我们点击确定,然后退出属性编辑器。\n测试OpenCV的配置 在源文件中添加一个 C++ 源程序,我添加的为 main.cpp\n在其中输入如下测试代码\n#include \u0026lt;iostream\u0026gt; #include \u0026lt;opencv2/core.hpp\u0026gt; #include \u0026lt;opencv2/imgcodecs.hpp\u0026gt; #include \u0026lt;opencv2/highgui.hpp\u0026gt; using namespace std; using namespace cv; int main(int argc, char** argv) { String imageName(\u0026#34;HappyFish.jpg\u0026#34;); // by default if (argc \u0026gt; 1) imageName = argv[1]; Mat image = imread(samples::findFile(imageName), IMREAD_COLOR); // Read the file if (image.empty()) { // Check for invalid input cout \u0026lt;\u0026lt; \u0026#34;Could not open or find the image\u0026#34; \u0026lt;\u0026lt; endl; return -1; } namedWindow(\u0026#34;Display window\u0026#34;, WINDOW_AUTOSIZE); // Create a window for display. imshow(\u0026#34;Display window\u0026#34;, image); // Show our image inside it. waitKey(0); // Wait for a keystroke in the window return 0; } 接下来我们随便找一张 jpg 图片文件,命名为 HappyFish.jpg ,保存在你的工程的根目录下/和 cpp 文件一个路径。这里我放一张 jpg 图片供大家使用~\n然后在我们的 Visual Studio 2019 中按下快捷键 Ctrl + F5 编译运行程序,会发现我们成功打开了这张图片,配置就成功了~\n参考链接 VS2019 上配置 OpenCV4.2.0\n","permalink":"https://blog.zzsqwq.cn/posts/114/","summary":"\u003ch2 id=\"windows-平台-visual-studio-2019-中-opencv-配置教程\"\u003eWindows 平台 Visual Studio 2019 中 OpenCV 配置教程\u003c/h2\u003e\n\u003ch3 id=\"前言\"\u003e前言\u003c/h3\u003e\n\u003cp\u003e我这里配置用的是4.5.0版本,但实际配置过程中需要的大部分时间只是路径,因此和版本基本无关。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e只有一个地方是和版本有关系的,在配置链接器的 \u003ccode\u003eopencv_wordxyzd.lib\u003c/code\u003e 时,大家一定要注意!!\u003c/strong\u003e\u003c/p\u003e","title":"Visual Studio 2019 中 OpenCV 配置教程"},{"content":"了解SQL 一.什么是SQL SQL是结构化查询语言(Structured Query Language)的缩写。是一种专门用来与数据库通信的语言。\n二.什么是数据库? 数据库(Database):保存有组织的数据的容器(通常是一个文件或一组文件)。 ​[scode type = \u0026ldquo;yellow\u0026rdquo;]需要注意的是,有时候我们把数据库软件也简称为数据库,但是数据库软件和数据库有本质区别,数据库软件应称为DBMS(数据库管理系统),我们通过数据库软件对数据库进行删减等操作,他代替你操作和访问数据库。[/scode]\n三.数据库的组成 表\n数据库中通常有多张表,这类似于一个清单。就好像我们管理两个班级就可以用两个表单。\n表单之间用表名区分,在同一个数据库中不能有两个具有相同表名的表单。\n行(又称记录)\n在表中可以有很多行,我们可以把表看成一个二维数组。每一行代表了一个成员。\n列\n每一行有好多列,一列可以代表着成员的一个属性,例如id,班级,姓名等等······\n数据类型\n每一列都有着特定的数据类型,例如字符串和数字就是两种不同的数据类型。\n主键(primary key)\n对于表中的每一行,我们都有一个唯一标识他的记号,这称作他的主键。\n可以发现,主键有以下特征:1.每一行都必须有一个主键,不能为空。2.不同行的主键不同。\n我们可以用多列作为主键,这样只需要确保多列组合起来的标识是唯一的。\n外键(foreign key)\n外键为某个表中的一列,它包含另一个表的主键值,定义了两个表之间的值,通过DBMS的操作可以将两个表联结起来。\n通俗点讲,好比有两张表,分别存储了所有供应商的信息,和所有产品的信息,在前面那张表定义了每个供应商的id,作为其主键。然后我们为每个产品定义外键的id,填上对应供应商的id,然后通过连结,我们就能知道每个产品供应商的详细信息了。\n可伸缩性(scale)\n能够适应不断增加的工作量而不失败。设计良好的数据库或应用程序称之为可伸缩性好(scale well)。\n四.数据库的连结 ​在上面我们讲外键的时候有讲到联结,连结的意思大概就是把多个表,根据一些命令串在一起。\n等值连结(内部连结)\n顾名思义,等值连结就是通过两个表之间元素值的相同来把两个表连结起来。\n自联结\n这个用于查找在同一表中某一特性相同的所有成员。有的时候自联结要比子查询快很多。\n自然联结\n在自然联结中,排除相同的列多次出现,使每个列只返回一次。\n外部联结\n联结包含了那些在相关表中没有关联行的行。这种类型的联结称为外部连结。\n五.数据库设计范式 范式:当一个关系中的所有分类都是不可再分的数据项时,该关系是规范化的。不可再分的数据项,即不存在组合数据项和多项数据项。一个低一级的关系模式,通过模式分解可以转换为若干高一级范式的关系模式的集合,这个过程就叫规范化。\n第一范式:当关系模式R的所有属性都不能在分解为更基本的数据单位时,称R是满足第一范式的,简记为1NF。满足第一范式是关系模式规范化的最低要求,否则,将有很多基本操作在这样的关系模式中实现不了。\n第二范式:如果关系模式R满足第一范式,并且R得所有非主属性都完全依赖于R的每一个候选关键属性,称R满足第二范式,简记为2NF。\n第三范式:设R是一个满足第一范式条件的关系模式,X是R的任意属性集,如果X非传递依赖于R的任意一个候选关键字,称R满足第三范式,简记为3NF。\n用我们学长的一句话,范式不是必须满足的,但是我们尽量按照范式来设计数据库,毕竟这是这么多程序员实战经验总结出来的。\n参考链接 数据库设计三大范式_dosthing 数据库设计三大范式_张龙豪 mysql必知必会 ","permalink":"https://blog.zzsqwq.cn/posts/107/","summary":"\u003ch1 id=\"了解sql\"\u003e了解SQL\u003c/h1\u003e\n\u003ch2 id=\"一什么是sql\"\u003e一.什么是SQL\u003c/h2\u003e\n\u003cblockquote\u003e\n\u003cp\u003e\u003cstrong\u003eSQL\u003c/strong\u003e是结构化查询语言(Structured Query Language)的缩写。是一种专门用来与数据库通信的语言。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch2 id=\"二什么是数据库\"\u003e二.什么是数据库?\u003c/h2\u003e\n\u003cblockquote\u003e\n\u003cp\u003e数据库(Database):保存有组织的数据的容器(通常是一个文件或一组文件)。\n​[scode type = \u0026ldquo;yellow\u0026rdquo;]需要注意的是,有时候我们把数据库软件也简称为数据库,但是数据库软件和数据库有本质区别,数据库软件应称为DBMS(数据库管理系统),我们通过数据库软件对数据库进行删减等操作,他代替你操作和访问数据库。[/scode]\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch2 id=\"三数据库的组成\"\u003e三.数据库的组成\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e表\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e数据库中通常有多张表,这类似于一个清单。就好像我们管理两个班级就可以用两个表单。\u003c/p\u003e\n\u003cp\u003e表单之间用表名区分,在同一个数据库中不能有两个具有相同表名的表单。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e行(又称记录)\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e在表中可以有很多行,我们可以把表看成一个二维数组。每一行代表了一个成员。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e列\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e每一行有好多列,一列可以代表着成员的一个属性,例如id,班级,姓名等等······\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e数据类型\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e每一列都有着特定的数据类型,例如字符串和数字就是两种不同的数据类型。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e主键(primary key)\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e对于表中的每一行,我们都有一个唯一标识他的记号,这称作他的主键。\u003c/p\u003e\n\u003cp\u003e可以发现,主键有以下特征:1.每一行都必须有一个主键,不能为空。2.不同行的主键不同。\u003c/p\u003e\n\u003cp\u003e我们可以用多列作为主键,这样只需要确保多列组合起来的标识是唯一的。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e外键(foreign key)\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e外键为某个表中的一列,它包含另一个表的主键值,定义了两个表之间的值,通过\u003cstrong\u003eDBMS\u003c/strong\u003e的操作可以将两个表联结起来。\u003c/p\u003e\n\u003cp\u003e通俗点讲,好比有两张表,分别存储了所有供应商的信息,和所有产品的信息,在前面那张表定义了每个供应商的id,作为其主键。然后我们为每个产品定义外键的id,填上对应供应商的id,然后通过连结,我们就能知道每个产品供应商的详细信息了。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e可伸缩性(scale)\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e能够适应不断增加的工作量而不失败。设计良好的数据库或应用程序称之为\u003cstrong\u003e可伸缩性好(scale well)\u003c/strong\u003e。\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"四数据库的连结\"\u003e四.数据库的连结\u003c/h2\u003e\n\u003cp\u003e​在上面我们讲外键的时候有讲到联结,连结的意思大概就是把多个表,根据一些命令串在一起。\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e等值连结(内部连结)\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e顾名思义,等值连结就是通过两个表之间元素值的相同来把两个表连结起来。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e自联结\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e这个用于查找在同一表中某一特性相同的所有成员。有的时候自联结要比子查询快很多。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e自然联结\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e在自然联结中,排除相同的列多次出现,使每个列只返回一次。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e外部联结\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e联结包含了那些在相关表中没有关联行的行。这种类型的联结称为外部连结。\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"五数据库设计范式\"\u003e五.数据库设计范式\u003c/h2\u003e\n\u003cblockquote\u003e\n\u003cp\u003e范式:当一个关系中的所有分类都是不可再分的数据项时,该关系是规范化的。不可再分的数据项,即不存在组合数据项和多项数据项。一个低一级的关系模式,通过模式分解可以转换为若干高一级范式的关系模式的集合,这个过程就叫规范化。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e第一范式\u003c/strong\u003e:当关系模式R的所有属性都不能在分解为更基本的数据单位时,称R是满足第一范式的,简记为1NF。满足第一范式是关系模式规范化的最低要求,否则,将有很多基本操作在这样的关系模式中实现不了。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e第二范式\u003c/strong\u003e:如果关系模式R满足第一范式,并且R得所有非主属性都完全依赖于R的每一个候选关键属性,称R满足第二范式,简记为2NF。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e第三范式\u003c/strong\u003e:设R是一个满足第一范式条件的关系模式,X是R的任意属性集,如果X非传递依赖于R的任意一个候选关键字,称R满足第三范式,简记为3NF。\u003c/p\u003e\n\u003cp\u003e用我们学长的一句话,范式不是必须满足的,但是我们尽量按照范式来设计数据库,毕竟这是这么多程序员实战经验总结出来的。\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003chr\u003e\n\u003ch2 id=\"参考链接\"\u003e参考链接\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://blog.csdn.net/dosthing/article/details/87954213\"\u003e数据库设计三大范式_dosthing\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.cnblogs.com/knowledgesea/p/3667395.html\"\u003e数据库设计三大范式_张龙豪\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003emysql必知必会\u003c/li\u003e\n\u003c/ul\u003e","title":"数据库的一些基础知识总结"},{"content":"引言 本来之前是用的 Hexo + Github 搭建的,虽然用的是 Github 的服务器,但是我用家里的移动网访问起来还是没什么压力,就是慢一点,可以接受。\n后来到了学校,我们学校网访问 Github 的速度简直可以用龟速来形容,白天可以说不开代理根本进不去,只有晚上了才能勉强进得去。然后我就寻思,能不能换成国内的服务器,然后就发现了 Gitee ,这个可以算是中国版的 Github ,他具有的服务 Gitee Pages 在国内可以飞速的访问,But如果想要自定义域名/每次推送自动更新需要开 Github Pages Pro ,还挺贵的,一年大概 120¥ 吧。此外,如果想要将域名解析到国内的服务器必须要备案,备案又必须有服务器,那我有服务器了还费那些事了,于是考虑自己买服务器重构一下博客。\n一些博客系统 搭博客,首先我们需要构思一下用什么博客系统,市面上比较广泛的有如下几个。\nWordpress\n这个绝对是重量级的,在全球范围内也是十分出名的,他的作用也不仅仅局限于搭建个人博客,也有很多例如电商等官网也是基于此系统的,据说全球 37% 的网站都是基于 Wordpress 的,这统治地位,可见一斑。\n优点:博客主题多样,十分的大气,插件也是各种各样的应有尽有。里面的设置也是十分的多,特别特别多,这个可以说是既是优点又是缺点,很多东西如果是个人博客的话根本用不到。\n缺点:不是原生支持markdown,并且对LaTeX的支持十分拉胯。需要安装插件,但是显示效果也是不尽人意。此外,Wordpress相比于下面推出的几个十分的臃肿,因为多了很多东西,安装包挺大的(虽然也就几MB的感觉),而且我没有找到我喜欢的主题,于是装载后卸掉了。\nEmlog\nEmlog 博客系统十分的简洁轻巧,安装包只有几百KB。\n优点:比较轻巧方便,主题和插件也还算多。\n缺点:其实主题我觉得,没有太好看的。所以没有考虑,大家可以去翻翻看看有没有钟意的主题再考虑是否安装这一个。\nTypecho\n这个博客系统是我现在正在用的,也是十分的轻巧简洁,是一个国产的博客系统。\n优点:自身对markdown的支持十分的友好,而且有一款插件对LaTeX的支持也是超级棒!因为我比较喜欢之前Hexo里面的NexT主题,而Typecho里面有这个的移植主题,所以最终还是选择的这个系统这个主题。而且他还有好几款例如 Handsome,Aria 这样的我觉得不错的主题。Ps: Handsome主题需要收费,而且现在还在更新,我觉得超值!\n缺点:正式版好久没更新了,上一次更新还是2017年。\n搭建过程 1. 购买服务器 首先我们去阿里云那边买一台学生机,一年也就 120¥ 的样子,很实惠。本来一年大概 1600¥ 的样子。\n买学生机的话就买 轻量应用服务器 ,然后应用镜像选一下 BT-Panel 即可。\n2. 登录服务器 进去之后点击应用详情,看一下 BT-Panel使用步骤。\n根据上面的指示获取登陆服务器的密码。然后点击左侧的 防火墙 ,在那里开启 8888 端口。如下图所示。\n3. 配置服务器 我们登录进入服务器后,点击左侧应用商城。依次安装 Apache、PHP-7.4、Mysql5.6。可能要等挺长时间。\n4. 开启网站 安装完成后,我们去面板设置那边看一下自己的 服务器ip ,记下来。\n点击左侧网站,添加站点。域名那里写自己的 服务器ip ,然后提交即可。\n然后点击左侧数据库,建立一个新的数据库,用于存放我们之后网站的信息。\n我们访问到我们网站的根目录,然后将自己心仪的博客程序拷入,访问 服务器ip/install.php 即可开启安装!\n安装完成后我们就可以通过 服务器ip 来访问我们的网站了!然后可以去网上找一下心仪的主题和插件来安装~\n一些后续工作 如果我们要自定义域名,首先我们可以去阿里云 / 腾讯云那边买一个域名,然后进行域名备案,你服务器是在哪边买的就在哪边备案即可。后续备案结束后在云解析那边添加域名解析(具体操作可以百度),然后在 BT-Panel 这边也添加域名解析,这样即可使用我们的自定义域名访问博客了!\n还有一些后续的优化例如安装 https安全证书(我自己现在还没搞好QAQ) ,加入 SEO优化 ,提交申请让 搜索引擎收录 等等……大家有兴趣的可以自行探索!\n","permalink":"https://blog.zzsqwq.cn/posts/77/","summary":"\u003ch2 id=\"引言\"\u003e引言\u003c/h2\u003e\n\u003cp\u003e本来之前是用的 \u003cstrong\u003eHexo + Github\u003c/strong\u003e 搭建的,虽然用的是 \u003cstrong\u003eGithub\u003c/strong\u003e 的服务器,但是我用家里的移动网访问起来还是没什么压力,就是慢一点,可以接受。\u003c/p\u003e\n\u003cp\u003e后来到了学校,我们学校网访问 \u003cstrong\u003eGithub\u003c/strong\u003e 的速度简直可以用龟速来形容,白天可以说不开代理根本进不去,只有晚上了才能勉强进得去。然后我就寻思,能不能换成国内的服务器,然后就发现了 \u003cstrong\u003eGitee\u003c/strong\u003e ,这个可以算是中国版的 \u003cstrong\u003eGithub\u003c/strong\u003e ,他具有的服务 \u003cstrong\u003eGitee Pages\u003c/strong\u003e 在国内可以飞速的访问,But如果想要自定义域名/每次推送自动更新需要开 \u003cstrong\u003eGithub Pages Pro\u003c/strong\u003e ,还挺贵的,一年大概 \u003cstrong\u003e120¥\u003c/strong\u003e 吧。此外,如果想要将域名解析到国内的服务器必须要备案,\u003cstrong\u003e备案又必须有服务器\u003c/strong\u003e,那我有服务器了还费那些事了,于是考虑自己买服务器重构一下博客。\u003c/p\u003e","title":"自买服务器建站教程"},{"content":"Day 3 A. 黑妹的游戏Ⅰ 题意 给出三个不同的初始数字$a,b,c$,黑妹每次选择两个不同的数字,计算出差的绝对值后如果黑板上没有就写在黑板上。问黑妹最多能添加多少个数字。\n思路 考虑到辗转相除法的那种过程(其实我也是突发奇想,严谨证明不会),最后黑板上所有的数字是 $$ ans = \\frac{max(a,b,c)}{gcd(a,b,c)} $$ 然后就需要减去黑板上原来的三个数就行。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; int t; long long a,b,c; long long gcd(long long a,long long b) { if(b == 0) return a; return gcd(b,a%b); } int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { scanf(\u0026#34;%lld%lld%lld\u0026#34;,\u0026amp;a,\u0026amp;b,\u0026amp;c); long long p = max(max(a,b),c); long long k = gcd(gcd(a,b),c); printf(\u0026#34;%lld\\n\u0026#34;,p/k-3); } return 0; } B. 御坂美琴 题意 有 $n$ 个玩偶堆成一堆。$(1\\le n \\le 10^{18})$\n你可以指定某一有 $x$ 个玩偶的玩偶堆将他分成 $\\lfloor \\frac{x}{2}\\rfloor$ 和 $x-\\lfloor \\frac{x}{2} \\rfloor$ 两堆。\n现给定有 $m$ 个数的序列 $a$ ,问能否通过若干次操作使得第 $i$ 堆玩偶数为 $a_i$ 。如果可以输出 misaka 否则输出 ham 。$(1\\le m\\le 10^5) , (1\\le a_i\\le 10^{18})$\n思路 首先我们可以想到,我们输入序列 $a$ 的时候可以将他累加起来成 $sum$ ,然后考虑最后$sum$ 是否和 $n$ 相同,不同的话肯定是不满足条件的,直接输出ham退出即可。\n否则我们就用 $dfs(n)$ 分割这个 n个玩偶的玩偶堆。因为 $n$ 比较大,考虑开一个map映射 $p$ 记录是否已经有为 $i$ 个玩偶的玩偶堆,如果有的话 $p[i] = 1$。如果没有 $p[i] = 0$ 。\n然后加一个递归结束的条件,就是当 $dfs(k)$ 的时候 $k == 1$ ,那么就不可再分了,直接返回。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; #include\u0026lt;queue\u0026gt; #include\u0026lt;map\u0026gt; using namespace std; #define ll long long const long long maxn = 1e18+5; const int maxm = 1e5+5; ll n,m; ll a[maxm]; ll sum; map\u0026lt;ll,bool\u0026gt; mp; int cmp(ll a,ll b) { return a\u0026gt;b; } void dfs(ll p) { if(mp[p] == 1 || p==1) return ; else { mp[p] = 1; dfs(p\u0026gt;\u0026gt;1); dfs(p-(p\u0026gt;\u0026gt;1)); } } int main() { scanf(\u0026#34;%lld%lld\u0026#34;,\u0026amp;n,\u0026amp;m); for(int i=1;i\u0026lt;=m;i++) { scanf(\u0026#34;%lld\u0026#34;,\u0026amp;a[i]); sum += a[i]; } if(sum != n) { printf(\u0026#34;ham\\n\u0026#34;); return 0; } // sort(a+1,a+1+m,cmp); dfs(n); mp[1] = 1; for(int i=1;i\u0026lt;=m;i++) { if(mp[a[i]] == 0) { printf(\u0026#34;ham\\n\u0026#34;); return 0; } } printf(\u0026#34;misaka\\n\u0026#34;); return 0; } Day 4 A. Distance 题意 给定有 $n$ 个数的序列 $A$ ,第 $i$ 个位置对应的值为 $A_i$ 。$(n\\le 10^5 ,A_i \\le 10^9)$\n定义 $FST$ 距离为 $|i^2 - j^2| + |A_i^2 - A_j^2|$ ,现在 $fst$ 想在序列 $A$ 中找到距离最大的一对元素,他不关心是哪一对,只想要求出最大的距离。\n思路 我们分情况讨论一下\n当 $i \u0026gt; j$ 并且 $A_i \u0026gt; A_j$ ,我们去掉绝对值后 $dis = i^2 + A_i^2 - (j^2 + A_j^2)$ 当 $i \u0026gt; j$ 并且 $A_i \u0026lt; A_j$ ,我们去掉绝对值后 $ dis = i^2 -A_i^2 -(j^2-A_j^2)$ 所以我们只需要在输入的时候维护两个数组,分别为 $p[i] = i^2+A_i^2 ,q[i] = i^2-A_i^2$ ,排序一下,然后在上面两个 $dis$ 中取一个最大值即可。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; #define ll long long const int maxn = 1e5+5; int n; long long a[maxn]; long long f1[maxn]; long long f2[maxn]; int cmp(long long a,long long b) { return a\u0026gt;b; } int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%lld\u0026#34;,\u0026amp;a[i]); f1[i] = (long long)i*i + (long long)a[i]*a[i]; f2[i] = (long long)i*i - (long long)a[i]*a[i]; } sort(f1+1,f1+1+n,cmp); sort(f2+1,f2+1+n,cmp); ll p = f1[1] - f1[n]; ll k = f2[1] - f2[n]; if(p \u0026gt; k) { printf(\u0026#34;%lld\u0026#34;,p); } else printf(\u0026#34;%lld\u0026#34;,k); } B. 字典序最小的中序遍历 题意 给一个有根二叉树,可以无限次的交换任意节点的左右子树,问最少交换多少次使得该树的中序遍历的字典序最小?\n思路 首先这题我上来觉得他就是个贪心题。。不然真的无从下手。\n那么字典序最小,只能是左边小于右边,如果不是的话就直接交换就完事了,然后 $ans++$ 即可。\n然后最后利用 $dfs$ 进行树的中序遍历即可。看代码还是比较好懂的。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; int n,m; const int maxn = 500005; int a[maxn],b[maxn]; int ans = 0; int rev(int p) { int l = p ,r = p; if(a[p]) l = rev(a[p]); if(b[p]) r = rev(b[p]); if(l \u0026gt; r) { swap(a[p],b[p]); ans++; } return l\u0026lt;r?l:r; } void dfs(int p) { if(a[p]==0 \u0026amp;\u0026amp; b[p] ==0) { printf(\u0026#34;%d \u0026#34;,p); return ; } if(a[p]) dfs(a[p]); printf(\u0026#34;%d \u0026#34;,p); if(b[p]) dfs(b[p]); } int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;m); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;a[i],\u0026amp;b[i]); } int k = rev(m); printf(\u0026#34;%d\\n\u0026#34;,ans); dfs(m); return 0; } ","permalink":"https://blog.zzsqwq.cn/posts/68/","summary":"\u003ch1 id=\"day-3\"\u003eDay 3\u003c/h1\u003e\n\u003ch2 id=\"a-黑妹的游戏httpsacnowcodercomacmcontest6956a\"\u003eA. \u003ca href=\"https://ac.nowcoder.com/acm/contest/6956/A\"\u003e黑妹的游戏Ⅰ\u003c/a\u003e\u003c/h2\u003e\n\u003ch3 id=\"题意\"\u003e题意\u003c/h3\u003e\n\u003cp\u003e给出三个不同的初始数字$a,b,c$,黑妹每次选择两个不同的数字,计算出差的绝对值后如果黑板上没有就写在黑板上。问黑妹最多能添加多少个数字。\u003c/p\u003e","title":"排位三和四记录"},{"content":"Day 1 A. 兔子的区间密码 题意 给定一个区间$[L,R]$ ,求从这个区间任意取两个整数(可以相同),两者异或后能得到的最大值是多少?\n思路 首先我们想一下特例,当 $L==R$ 的时候,那么只能是L和他自己异或,就是0了。\n然后可以分两部分来想,设区间端点 $L,R$ 的二进制最高位,从右往左开始数位置分别为 $p_1,p_2$\n如果 $p_1 \\neq p_2 $ ,那么必然是 $p_1 \u0026lt; p_2$ ,我们很容易发现这时候肯定可以取到 $2^{p_2-1}-1 和 2^{p_2-1}$ ,那么两者异或一下就是最大的,答案为 $2^{p_2}$ 如果 $p_1 == p_2$ ,那么我们可以转化为更小规模的问题,就是区间为 $[L-2^{p_1-1},R-2^{p_1-1}]$ 。 代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; #define ll long long ll l,r; int t; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { ll l,r; scanf(\u0026#34;%lld%lld\u0026#34;,\u0026amp;l,\u0026amp;r); if(l == r) { printf(\u0026#34;0\\n\u0026#34;); } else { int p1 = log2(l),p2 = log2(r); while(p1 == p2 \u0026amp;\u0026amp; l != 0) { l^=(1LL\u0026lt;\u0026lt;p1); r^=(1LL\u0026lt;\u0026lt;p1); p1 = log2(l),p2=log2(r); } printf(\u0026#34;%lld\\n\u0026#34;,((1LL\u0026lt;\u0026lt;(p2+1))-1)); } } return 0; } B. 猴子排序的期望 题意 有 $N$ 张卡片,每个上面都写着一个大写字母,问随便扔一次这 $N$ 张的卡片就已经按字典序排好的概率,答案用分字为1的形如 $1/x$ 的形式表示。$( 1\u0026lt;N \u0026lt; 100)$\n思路 这题很显然是道数学排列组合题,我们设每个字母重复出现的次数为 $p[i]$ ,好比字母为$A$的卡片出现了两次,那么就 $p[\u0026lsquo;A\u0026rsquo;]$ 为2。\n那么答案就是如下 $$ ans = \\frac{N!}{\\Pi_{i=\u0026lsquo;A\u0026rsquo;}^{i=\u0026lsquo;Z\u0026rsquo;}(p[i]!)} $$ 这题主要难点大概是在高精,因为可能会涉及到 $100!$ 这种丧心病狂的东西,所以就用笨比的方法写了一发python。其实是高级的算法不会用python写,C++乘法的高精忘掉了。\n代码实现 n = int(input()) s = input() s[0:n:1] ans = 1 for i in range(1,n+1): ans = ans*i for i in range(0,n): count = 0 for j in range(i,n): if s[i] == s[j]: count = count + 1 if count \u0026gt;= 0: ans = ans//count #这里本来//写成了/,连WA3发 print(\u0026#34;1/\u0026#34;,end=\u0026#34;\u0026#34;) print(int(ans)) Day 2 A. 愤怒的巨巨 题意 已知香蕉的次品率为 $p(0\\le p\\le 1)$ ,如果想要买到好香蕉则买香蕉个数的期望值是多少。如果买不到好香蕉,输出”Sorrry,JuJu!”(忽略双引号)。否则输出期望值的最简分数形式:c/d. $p$ 的最多位数为6。\n思路 首先理解一下题意,好比次品率 $p$ 为0.5,则期望的个数为2个。如果次品率 $p$ 为 0.25,则可以说平均买四个有一个次品,那么最少需要的买的个数其实是 $3/4$ 。\n再者特判一下 $p == 0$ 以及 $p==1$ 的情况,分别输出 1/1 和 Sorrry,JuJu! 。\n然后其实可以看一下非次品率 $k = 1-p$ ,然后其实就是一个最大公约数问题了。只需要把 $k$ 转换成分数形式,然后用最大公约数约分一下,再取一个倒数即可。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; char str[100]; int k = 0; int mod = 1; bool flag = false; int gcd(int a,int b) { if(b==0) return a; return gcd(b,a%b); } int main() { scanf(\u0026#34;%s\u0026#34;,str); int len = strlen(str); if(str[0] == \u0026#39;0\u0026#39;) { for(int i=2;i\u0026lt;len;i++) { if(str[i] != \u0026#39;0\u0026#39;) flag = true; } if(flag == false) { printf(\u0026#34;1/1\u0026#34;); return 0; } } if(str[0] == \u0026#39;1\u0026#39;) { printf(\u0026#34;Sorrry,JuJu!\u0026#34;); return 0; } for(int i=2;i\u0026lt;len;i++) { k = k*10+str[i]-\u0026#39;0\u0026#39;; mod *= 10; } int m = mod - k; int p = gcd(m,mod); printf(\u0026#34;%d/%d\u0026#34;,mod/p,m/p); return 0; } B. 兔子的逆序对 题意 给定一个区间 $[L,R]$ ,然后给出 $m$ 次翻转操作,通过给出子区间左右端点,反转该区间。每翻转一次,要求给出区间 $[L,R]$ 逆序对的奇偶性,如果是奇数,输出 dislike ,如果是偶数,输出 like 。\n思路 首先用归并 / 树状数组的方法,求出来区间 $[L,R]$ 的逆序对 $ans$。\n然后我们考虑每一次翻转带来的影响。我们考虑一个子区间 $[l,r]$ ,设该区间逆序对为 $x$ ,那么反转后该区间的逆序对为 $C_n^2 -x$ 。翻转区间 $[l,r]$ 导致答案 $ans = ans + C_n^2 -x - x = ans + C_n^2-2x$\n因为只需要奇偶性,那么 $2x$ 需要考虑,那么就每次看看 $C_n^2$ 的奇偶性即可。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; #define lowbit(x) (x)\u0026amp;(-x) typedef struct Node { int val; // value int pos; //postion }node; int cmp(node a,node b) { return a.val\u0026lt;b.val; } const int maxn = 1e5+5; const int maxm = 2e6+5; node num[maxn]; int tree[maxm]; int n,m; int l,r; void add(int x) { for(int i=x;i\u0026lt;=n;i+=lowbit(i)) { tree[i]++; } } int find(int x) { int sum=0; for(int i=x;i\u0026gt;0;i-=lowbit(i)) { sum+=tree[i]; } return sum; } int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;num[i].val); num[i].pos=i; } sort(num+1,num+n+1,cmp); int ans = 0; for(int i=1;i\u0026lt;=n;i++) { ans+=find(num[i].pos); add(num[i].pos); } scanf(\u0026#34;%d\u0026#34;,\u0026amp;m); for(int i=1;i\u0026lt;=m;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;l,\u0026amp;r); int k = ((r-l+1)*(r-l))\u0026gt;\u0026gt;1; if(k\u0026amp;1) { if(ans%2 == 0) { printf(\u0026#34;dislike\\n\u0026#34;); ans++; } else { printf(\u0026#34;like\\n\u0026#34;); ans++; } } else { if(ans%2 == 0) { printf(\u0026#34;like\\n\u0026#34;); } else { printf(\u0026#34;dislike\\n\u0026#34;); } } } } C. Butterfly 题意 这题描述起来有点难,还是直接点链接去看比较好。\n大概就是给定一个 由 X 和 O 构成的$n\\times m$ 的矩阵,让你找出里面由 X 构成的蝴蝶的最大对角线长度。\n思路 这题第一时间让我想到了我 2020/2/12 写的dp练习中的创意吃鱼法。\n一开始想要考虑从中心开始考虑,但是需要维护的东西有点多,而且周围的判别不好判。因此可以考虑从右上/右下/左上/左下 这四个位置考虑,我这里是从左下考虑的。设我们要求的答案为 $ans$ 。\n考虑维护三个数组,看 X 向上延伸,左上延伸,右上延伸的长度。所以我们依次遍历矩阵中的每一个元素,判定他是否可以作为蝴蝶的左下角,首先取一个向上延伸和右上延伸的最小值 $p$,然后从 $p$ 到 $ans$ 遍历,每次判定一下该答案是否合法,判定的话无非是从右下角判定一下就行,比较简单。如果答案合法,那么更新 $ans$。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn = 2005; int lr[maxn][maxn],rr[maxn][maxn],str[maxn][maxn]; //分别为按左上、右上,向上延伸 char x; int n,m; int ans; int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;m); for(int i=1;i\u0026lt;=n;i++) { for(int j=1;j\u0026lt;=m;j++) { cin\u0026gt;\u0026gt;x; if(x == \u0026#39;X\u0026#39;) { lr[i][j] = lr[i-1][j-1] + 1; rr[i][j] = rr[i-1][j+1] + 1; str[i][j] = str[i-1][j] + 1; ans = 1; } } } for(int i=1;i\u0026lt;=n;i++) { for(int j=1;j\u0026lt;=m;j++) { int p = min(str[i][j],rr[i][j]); for(int k = p;k\u0026gt;ans;k--) { if(k\u0026amp;1) { if(str[i][j+k-1]\u0026gt;=k \u0026amp;\u0026amp; lr[i][j+k-1]\u0026gt;=k) ans = max(ans,k); } } } } printf(\u0026#34;%d\u0026#34;,ans); } ","permalink":"https://blog.zzsqwq.cn/posts/5/","summary":"\u003ch1 id=\"day-1\"\u003eDay 1\u003c/h1\u003e\n\u003ch2 id=\"a-兔子的区间密码httpsacnowcodercomacmcontest6954a\"\u003eA. \u003ca href=\"https://ac.nowcoder.com/acm/contest/6954/A\"\u003e兔子的区间密码\u003c/a\u003e\u003c/h2\u003e\n\u003ch3 id=\"题意\"\u003e题意\u003c/h3\u003e\n\u003cp\u003e给定一个区间$[L,R]$ ,求从这个区间任意取两个整数(可以相同),两者异或后能得到的最大值是多少?\u003c/p\u003e","title":"排位一和二记录"},{"content":"高精度计算PI值 题目描述 使用双向链表作为存储结构,请根据用户输入的一个整数(该整数表示精确到小数点后的位数,可能要求精确到小数点后 500 位),高精度计算PI值。提示:可以利用反三角函数幂级展开式来进行计算。\n解题思路 求PI的算法 首先这道题是要求必须使用双向链表作为存储结构的,这个需要注意,而且也不能用数组计算完了之后挨个赋值给链表的每个节点,这是耍赖 。\n那么我们开始再想,用什么公式来求 PI 呢?这是一个问题。先没管题目的提示,我去百度了一通,发现了一个很神奇的算法,用三行就可以计算到圆周率小数点后800+位。\n#include\u0026lt;cstdio\u0026gt; using namespace std; long a=1000,b,c=2800,d,e,f[2801],g; int main(){ for(;b-c;) f[b++]=a/5; for(;d=0,g=c*2;c-=14,printf(\u0026#34;%.3d\u0026#34;,e+d/a),e=d%a) for(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b); } ​实验了一下发现居然真的是,而且效率还挺高的?看了一会实现的原理一直没看懂,作罢。\n​最后发现是找不到什么除了幂级展开还有啥高效率的算法了好像,还是考虑题目提示的 三角函数幂级展开。然后继续在网上搜索了一下,在学长的一个博客里发现了公式。 $$ f_{i} = \\begin{cases} 1 \u0026amp; {i=1}\\\\ f_{i-1}\\times \\frac{i-1}{2\\times i-1} \u0026amp; {i\u0026gt;1} \\end{cases} $$\n那么拿到了这个式子,我们就可以分析一下,怎么和链表结合起来做了。\n链表的设计 双向链表,也就是每个节点有一个数据域,有前和后两个指针。我考虑到我们做加法和乘法是需要从后往前做,除法是需要从前往后做。因此需要双向遍历,我又添加了一个尾指针,记录当前链表的尾节点的地址,方便从后往前遍历,头节点可以保证从前往后遍历。设计如下:\ntypedef struct node { int data; struct node *nxt; struct node *pre; struct node *tail; node() //构造函数,用于初始化 { nxt = NULL; pre = NULL; tail = this; data = 0; } } 数据域就用来存储每一位数字,好比 3.1415926 就从第一个节点到第八个节点依次存 31415926 。\n乘法的实现 另出一个函数,函数声明类似于 void Multi(List L,int k)\n乘法我们模拟竖式的乘法运算,考虑到这是一个 高精度大数 * 低精度整数 ,因此我们只需要从尾部到头部依次对每一位做乘法即可,考虑到进位问题,可以有两种办法\n可以是先做完乘法,然后再回到尾部,再从尾到头依次处理进位,这样的好处是这两种操作分隔开了,操作起来难度不大,也比较好想。 可以是边做乘法边进位,我们定义一个 temp 用来存储低位到高一位的进位,这里要注意的是,对于某一位的操作不是先加上进位再做乘法,是先做乘法,再加低位的进位。 但是有一个问题我们需要注意,就是好比 52 * 3 ,这时候原来的两位数变成三位数了,因此需要我们在头节点和第一个节点之间增加新的节点,并且可能增加的不只是一个,只要 temp 这个进位大于等于10就需要一直创建新的节点来保证进位。\n除法的实现 另出一个函数,函数声明类似于 void Division(List L,int k)\n除法也是模拟竖式运算,这个是从头到尾进行处理,这一位的数据做完除法,余数作为下一位的**“进位”** ,这里可以边做边 “进位” 。这里这个进位不是乘法的那种进位,注意区分。\n需要注意的是最后可能有除不尽的情况,这样我们就可以一直在尾部插入节点,然后处理一直处理数据到最大位数 或者 到 “进位” 为0为止 。最后不要忘记重置一下尾指针,指向新的尾节点。\n加法的实现 函数声明类似于 void Sum(List L,List p) 。\n加法的实现也是需要从后往前遍历,然后依次对每一位做加法。先取两个链表的尾节点出来,然后依次向前遍历相加,我们可以把相加的答案放在前面那个链表里面,注意这样是不需要返回值的,因为链表内部是通过地址索引的,我们改变的就是传入链表的值。\n最后的整合 最后我们总共需要一个和链表,一个 $f_{i}$。 和链表用于计算所有式子的累加和,而 $f_{i-1}$ 其实就是 $f_i$ 的上个阶段 。我们每次把 $f_i$ 和 和链表进行累加即可。\n最后再对和链表乘2 即可。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; #include\u0026lt;algorithm\u0026gt; using namespace std; const int maxsize = 600; // 设定求小数点后多少位 typedef struct node // 双向链表的结构体 { int data; struct node *nxt; struct node *pre; struct node *tail; node() //构造函数,用于初始化 { data = 0; tail = this; nxt = NULL; pre = NULL; } }Node,*List; void Mult(List Head,int k); // 对链表每一位 *k void Divi(List Head,int k); // 对链表每一位 ÷k void Sum(List a,List b); // 对两个链表的数求和,所得数放在前面链表中 void InitList(List \u0026amp;L); // 初始化链表,并把第一个节点值设为 1 void InitSum(List \u0026amp;L); // 初始化最后存和的链表,并把第一个节点置为1 void Output(List L,int k); // 输出一个链表,保留 k 位小数 int main() { int n = 0; scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); List Head,S; InitList(Head); InitSum(S); for(int i=2;i\u0026lt;=3000;i++) //计算pi值 { Mult(Head,i-1); Divi(Head,2*i-1); Sum(S,Head); } Mult(S,2); Output(S,n); return 0; } void Mult(List Head,int k) // 对以Head为头节点的链表中的每一位做乘法 { List p = Head-\u0026gt;tail; // 先把指针指向链表的末尾,方便从后往前做乘法 while(p != Head) // 从前往后开始算乘法 { p-\u0026gt;data *= k; p = p-\u0026gt;pre; // printf(\u0026#34;I have done Multi.\\n\u0026#34;); } p = Head-\u0026gt;tail; while(p != Head-\u0026gt;nxt) //开始处理进位 { p-\u0026gt;pre-\u0026gt;data += p-\u0026gt;data /10; p-\u0026gt;data %= 10; p = p-\u0026gt;pre; } while( p-\u0026gt;data \u0026gt; 10) //一直处理最高位的进位 { List s = (List)malloc(sizeof(Node)); s-\u0026gt;data = p-\u0026gt;data/10; p-\u0026gt;data %= 10; s-\u0026gt;pre = Head; s-\u0026gt;nxt = p; p-\u0026gt;pre = s; Head-\u0026gt;nxt = s; p = s; } } void Divi(List Head,int k) // 对链表每一位除k { int temp = 0,depth = 0; //temp用于进位计算 ,depth 用于计算链表长度 List p = Head-\u0026gt;nxt; List t; // 存尾部节点 while(p != NULL) //模拟做除法 { depth++; p-\u0026gt;data += temp*10; temp = p-\u0026gt;data % k; p-\u0026gt;data /= k; t = p; p = p-\u0026gt;nxt; } p = t; while(temp!=0 \u0026amp;\u0026amp; depth \u0026lt;= maxsize) // 如果除不尽,就一直往后拓展节点,但注意不要超过最大位数 { // printf(\u0026#34;I have done Division!\\n\u0026#34;); depth++; List s = (List)malloc(sizeof(Node)); s-\u0026gt;data = temp*10; s-\u0026gt;nxt = NULL; s-\u0026gt;pre = p; temp = s-\u0026gt;data % k; s-\u0026gt;data /= k; p-\u0026gt;nxt = s; p = s; } Head-\u0026gt;tail = p; } void Sum(List a,List b) // 对两个链表的数求和,所得数放在前面链表中 { List p = a-\u0026gt;tail,k = b-\u0026gt;tail; // 先指向各自的尾部,开始从前往后加 while(p!=a \u0026amp;\u0026amp; k!=b) // 遍历到有一个到头节点为止 { p-\u0026gt;data += k-\u0026gt;data; p-\u0026gt;pre-\u0026gt;data += p-\u0026gt;data / 10; p-\u0026gt;data %= 10; p = p-\u0026gt;pre; k = k-\u0026gt;pre; } } void InitList(List \u0026amp;L) // 初始化链表,并把第一个节点值设为 1 { L = (List)malloc(sizeof(Node)); L-\u0026gt;data = 0; List s = (List)malloc(sizeof(Node)); s-\u0026gt;data = 1; s-\u0026gt;pre = L; L-\u0026gt;nxt = s; L-\u0026gt;pre = NULL; L-\u0026gt;tail = s; s-\u0026gt;nxt = NULL; } void InitSum(List \u0026amp;L) // 初始化最后存和的链表,并把第一个节点置为1 { L = (List)malloc(sizeof(Node)); L-\u0026gt;nxt = NULL; L-\u0026gt;pre = NULL; L-\u0026gt;data = 0; List p = L; int depth = 0; while(depth \u0026lt;= maxsize) { List s = (List)malloc(sizeof(Node)); s-\u0026gt;data = 0; s-\u0026gt;pre = p; p-\u0026gt;nxt = s; s-\u0026gt;nxt = NULL; p = s; depth++; } L-\u0026gt;nxt-\u0026gt;data = 1; L-\u0026gt;tail = p; } void Output(List L,int k) //输出一个列表,保留 k 位小数 { List p = L-\u0026gt;nxt; printf(\u0026#34;%d.\u0026#34;,p-\u0026gt;data); p = p-\u0026gt;nxt; int t = 0; while(p != NULL \u0026amp;\u0026amp; t\u0026lt;k) { t++; printf(\u0026#34;%d\u0026#34;,p-\u0026gt;data); p = p-\u0026gt;nxt; } printf(\u0026#34;\\n\u0026#34;); } 参考链接 数据结构实验:高精度计算圆周率 圆周率高精度算法 ","permalink":"https://blog.zzsqwq.cn/posts/67/","summary":"\u003ch2 id=\"高精度计算pi值\"\u003e高精度计算PI值\u003c/h2\u003e\n\u003ch3 id=\"题目描述\"\u003e题目描述\u003c/h3\u003e\n\u003cp\u003e使用双向链表作为存储结构,请根据用户输入的一个整数(该整数表示精确到小数点后的位数,可能要求精确到小数点后 \u003cstrong\u003e500\u003c/strong\u003e 位),高精度计算PI值。\u003cstrong\u003e提示:可以利用反三角函数幂级展开式来进行计算。\u003c/strong\u003e\u003c/p\u003e","title":"高精度计算pi"},{"content":"Python学习笔记 Python的不同解释器 CPython\n这是自带的用C语言开发的解释器,因此叫CPython。它也是使用最广的Python解释器。\nIPython\n这是基于CPython之上的一个交互式解释器,只是相比于CPython多了交互上的优化。\nPyPy\n它的目标是执行速度。PyPy采用JIT技术,对Python代码进行动态编译(注意不是解释),所以可以显著提高Python代码的执行速度。他与CPython略有不同。\nJython\n这是运行在Java平台上的Python解释器,可以直接把Python代码编译成Java字节码执行。\nIronPython\n这是运行在微软.Net平台上的Python解释器,可以直接把Python代码编译成.Net的字节码。\nPython基础 简单的输入和输出(I/O) 输入 python提供了一个 input() 函数供我们输入使用,这读入的是字符串数据,并返回,可以将返回值存放在一个变量中。input函数中可以带字符串,这段字符串在输入前会打印在屏幕上,这使得我们具有很好的交互性,好比我们写:\nname = input(\u0026#34;hello,friend! please input your name\u0026#34;) print(\u0026#34;The input name is \u0026#34;,name) 那么这时候我们运行上述程序,就会提示 hello , friend! please input your name ,这就提示我们应该输入名字。\n这里需要注意的是,input() 函数读入的是一个字符串 str ,就算我们输入了整数他也是一个字符串,如果我们要用真正的整数,那么就需要用 int() 进行类型强制转换。如果其中不是合法的整数,那么会报错。\n输出 python中的输出函数是 print() ,这和 C++ 的printf 差了一个f。我们在函数的参数中传入什么,他就会打印什么。好比我们写 print(\u0026quot;heelo,world\u0026quot;) ,那么运行就会打印 hello,world 在屏幕上。print 支持我们传入多个参数,好比 printf(\u0026quot;my name is\u0026quot;,\u0026quot;zs\u0026quot;) ,两两之间用逗号隔开,这在输出时会被解析成空格,也就是说两段字符串之间有一个空格。当然此函数也可以打印整数等。\n一些规则 缩进 Python中对代码块的区分,不是用C++的大括号,而是用缩进。处于连续同一缩进的是一个代码块,这也是为什么Python又被戏称为游标卡尺语言的原因。当语句以冒号:结尾时,缩进的语句视为代码块。我们通常用一个Tab / 四个空格 的缩进。\n注释 Python的注释用的是 # ,而 C++ 中的注释用的是 \\\\ 。\nCase Sensitive Python中是大小写敏感的,也就是 a 和 A 不是同一个东西。\n数据类型 1. 整数 Python一个很大的好处就是可以处理任意大小的整数,包括负整数。这也是为什么很多大数题大家都喜欢用Python,hhhh。多数地方都用十进制,但是也是支持其他进制的哈~好比 0x 前缀就是16进制。\n2. 浮点数 浮点数是小数,之所以称为浮点数,是因为小数点位置在科学计数法中是可变的。这里需要注意,整数和浮点数在计算机内部存储方式不同,浮点数应该都是 IEEE754 标准吧?整数之间的运算永远都是精确的,包括除法。而浮点数的运算则会有一定的误差。Python的浮点数也没有大小限制,但是超出一定范围就直接表示为inf(无限大)。\n3. 字符串 字符串是以单引号 '' 或者双引号 \u0026quot;\u0026quot; 括起来的任意文本。我们注意到Python中没有单个字符的概念,就算是单个字符也是一个字符串。如果'' 括起来的字符串内部出现 '' 需要使用\\转义,相同的,如果 \u0026quot;\u0026quot; 括起来的字符串内部出现 \u0026quot;\u0026quot; 需要转义。好比下面的程序\nprint(\u0026#34;My name is \u0026#39;zs\u0026#39;\u0026#34;) #合法 My name is \u0026#39;zs\u0026#39; print(\u0026#34;My name is \u0026#34;zs\u0026#34;\u0026#34;) #不合法 invalid syntax print(\u0026#34;My name is \\\u0026#34;zs\\\u0026#34;\u0026#34;) #合法 My name is \u0026#34;zs\u0026#34; print(\u0026#39;My name is \u0026#34;zs\u0026#34;\u0026#39;) #合法 My name is \u0026#34;zs\u0026#34; print(\u0026#39;My name is \u0026#39;zs\u0026#39;\u0026#39;) #不合法 invalid syntax print(\u0026#39;My name is \\\u0026#39;zs\\\u0026#39;\u0026#39;) #合法 My name is \u0026#39;zs\u0026#39; Python中也有很多转义字符,跟C++的很类似。\\n,\\t,\\\\ 分别代表换行,横向制表,字符\\ 。在python中还支持用 r' ' 表示 '' 内部的字符默认不转义。\nPython在输出多行语句时,可以用 print('''content''') 其中content中的内容,支持用直觉上的换行。\nprint(\u0026#39;\u0026#39;\u0026#39;python name zs\u0026#39;\u0026#39;\u0026#39;) # The output python name zs 4. 布尔值 含有 Ture 和 False 两种类型,代表真和假。支持 and , or ,not 三种运算。\n5. 空值 空值是Python中的一个特殊值,用 None 表示。 None不能理解为0,因为0是有意义的,而None是一个特殊的空值。\n变量 变量在程序中就是用一个变量名表示了,变量名必须是大小写英文、数字和_的组合,且不能用数字开头。\n变量命名时最好能做到顾名思义,当然也有很多规范的命名规则,可以自行百度。\n在 Python 中我们不需要指定一个变量是特定的类型,它可以在不同的类型之间变来变去,这确实很方便,不过感觉也是很占内存和时间的。\n这种变量本身类型不固定的语言称之为动态语言,与之对应的是静态语言。静态语言在定义变量时必须指定变量类型,如果赋值的时候类型不匹配,就会报错\n常量 Python中没有C++中的const来限制常量,但是通常用变量名全大写来代表这个变量为一个常量,但是这玩意是个约定俗成的,并不是说你这么写他就真是个常量了。\n字符串和编码 字符编码 字符编码有很多种,不同的语言也对应着不同的字符编码。常见的几个是 ASCII ,Unicode ,UTF-8,GB2313 他们分别是英文和特殊字符的编码,统一的一套编码,可变长的统一编码,常用的中文编码。\nPython的字符串存储 Python 3的的字符串是 Unicode 编码的,也就是说Python的字符串支持多语言,因为这是一套统一的编码。\n对于单个字符的编码,Python提供了 Ord() 函数获取字符的整数表示,chr() 函数通过整数获取对应字符。\nPython中的字符串类型为 str ,一个字符对应若干字节。**如果要在网络上传输,或者保存到磁盘上,就需要把str变为以字节为单位的bytes。**Python对bytes类型的数据用带b前缀的单引号或双引号表示。\n我们可以通过encode('编码方式') 将 str 转变成 bytes 。我们也可以通过 decode('编码方式') 将 bytes 转变为 str 。\nPython为我们提供了一个 len() 函数,如果字符串是 str ,那么计算出的是字符数,如果是 bytes ,那么计算的是字节数。我们为了防止乱码问题,在两者相互转换时推荐用 utf-8 编码。\n由于Python源代码也是一个文本文件,所以,当你的源代码中包含中文的时候,在保存源代码时,就需要务必指定保存为UTF-8编码。当Python解释器读取源代码时,为了让它按UTF-8编码读取,我们通常在文件开头写上这两行:\n#!/usr/bin/env python3 # -*- coding: utf-8 -*- 第一行注释是为了告诉Linux/OS X系统,这是一个Python可执行程序,Windows系统会忽略这个注释;\n第二行注释是为了告诉Python解释器,按照UTF-8编码读取源代码,否则,你在源代码中写的中文输出可能会有乱码。而且需要你的编辑器支持 UTF-8编码。\n字符串的格式化输出 第一种方式 Python的 print() 格式化输出和C语言的很像,也是 %d 代表整数,%f 代表浮点数, %s 代表字符串,%s代表十六进制整数。关于格式的指定,好比补0什么的也和C的很像。具体格式如下:\nprint(\u0026#39;%2d-%02d\u0026#39; % (3,1)) # 输出 3-01 print(\u0026#39;my name is %s\u0026#39; % \u0026#34;zs\u0026#34;) # 输出 my name is zs 如果我们要在字符串里面输出 % ,那么就需要用 %% 来转义表示 % 。\nprint(\u0026#34;This is a common %% %s \u0026#34; % \u0026#34;字符\u0026#34;) # 输出 This is a common % 字符 第二种方式 除了上面的方法,print 还可以用 .format 的方法进行格式化输出。例如下例子\nprint(\u0026#39;{0} name is {1}\u0026#39;.format(\u0026#34;who\u0026#34;,\u0026#34;zs\u0026#34;)) #输出 who name is zs List \u0026amp; tuple (列表和元组) List(列表) List像是一个大杂烩,里面可以有各种类型的东西,是一个有序的集合,也就是说可以通过下标索引。\n我们创建一个列表可以用中括号, Mylist = [\u0026quot;zs\u0026quot;,\u0026quot;wx\u0026quot;] ,这就创建了具有两个元素的列表,第一个元素是字符串 zs 第二个元素是字符串 wx 。这个列表的名字就是 Mylist 。\n我们可以通过 len() 来获取列表中元素的个数,也可以通过下表索引列表的元素,但是要注意下标是从0开始计数的,如果索引出界会报 IndexError 。有趣的是,我们可以通过负的下表来访问元素,是倒着访问的,好比上述列表中 Mylist[-1] 就代表元素 \u0026ldquo;wx\u0026rdquo; 。\n我们可以通过 listk = [] ,来创建一个空列表 listk ,如果用 len() 查看长度那么长度为0.\n此外列表中的元素也可以是列表,可以通过类似于二维数组的形式索引。\n列表中,有许多的方法。就像是相对于这个类型内置的一些函数,用法如下:\nMylist = [\u0026#34;zs\u0026#34;,\u0026#34;wx\u0026#34;] print(Mylist) # 输出 [\u0026#39;zs\u0026#39;, \u0026#39;wx\u0026#39;] Mylist.append(\u0026#39;Better\u0026#39;) # 用于在列表后面追加一个元素 print(Mylist) # 输出 [\u0026#39;zs\u0026#39;, \u0026#39;wx\u0026#39;, \u0026#39;Better\u0026#39;] Mylist.insert(1,\u0026#39;Good\u0026#39;) # 用于在下标为1的位置,插入一个元素 print(Mylist) # 输出 [\u0026#39;zs\u0026#39;, \u0026#39;Good\u0026#39;, \u0026#39;wx\u0026#39;, \u0026#39;Better\u0026#39;] popx = Mylist.pop() # 用于删除列表中最后一个元素,并返回元素的值 print(Mylist,popx) # 输出 [\u0026#39;zs\u0026#39;, \u0026#39;Good\u0026#39;, \u0026#39;wx\u0026#39;] Better popx = Mylist.pop(1) # 用于删除列表中下标为1的元素,并返回元素的值 print(Mylist,popx) # 输出 [\u0026#39;zs\u0026#39;, \u0026#39;wx\u0026#39;] Good L = [] # 创建了一个空列表 L print(len(L)) #输出0 Tuple(元组) 元组跟上面的链表差不多,只不过是不可变的,一旦初始化就不能修改,也是可以通过下标访问元素。\n不同的的是,我们定义一个元组是用 () ,好比我们定义 Mytuple = (\u0026quot;zs\u0026quot;,\u0026quot;wx\u0026quot;) ,这是含有两个字符串元素的元组,我们可以通过 Mytuple = () 来定义一个空的元组。\n需要注意的是,当我们定义一个只有一个元素的元组,如果我们写成 Mytuple = (\u0026quot;zs\u0026quot;) ,那么Python会默认解析为这是一个字符串,把括号当初普通的括号,不解释成元组。 那么我们如何定义只有一个元素的元组呢,我们应该写 Mytuple = (\u0026quot;zs\u0026quot;,) 这样就是只有一个元素的元组。\n元组中的不可变,是指它的指向不变,那么如果好比元组的元素中有一个列表,那么其实这个元组中的列表的元素还是可以改变的。\n条件判断 条件判断是一个经典的语句。用于分支结构。\n用法跟C很像,不过 else if 可以缩写为 elif ,并且因为 if ,else , elif 后面接的都是语句块,因此要加 : 。\nweight = 120 if weight\u0026gt;=200: print(\u0026#34;too fat\u0026#34;) elif weight\u0026lt;=100: print(\u0026#34;too thin\u0026#34;) else: print(\u0026#34;Good\u0026#34;) 循环语句 循环结构也是三大结构之一。\nfor for语句是我C++中最喜欢循环语句。在Python中,他的写法变成了 for x in something: ,下面接相应的循环语句块。这个 x 是变量的名字,something 是某一个容器,可以是列表可以是元组啥的,这个写法的意思就是 遍历 something 中的每个元素,带入变量 x 中,执行循环操作。\n我们通常配合 range() 函数来执行循环操作,通过 range(n) 可以生成从 [0,n) 的整数。\nfor x in list(range(11)): print(x) #输出 0~10 while while语句也是和C语言差不多,当型循环,当满足条件时就执行循环,也记住不要忘记加 : 。\nbreak \u0026amp; continue break 的作用是结束整个循环。\ncontinue 的作用是跳过这一次循环。\nDict \u0026amp; Set (字典和集合) Dict 这个字典其实就是C语言中的 map ,人家 Python 直接内置了,属实业界良心。其实就是利用键值对匹配,一个键对应一个值。实现方式为哈希 (Hash) 。\n创建就是 Mydict = {\u0026quot;zs\u0026quot;:250 , \u0026quot;wx\u0026quot;:666} 这样第一个元素的键为 \u0026ldquo;zs\u0026rdquo; ,对应值为 250 。第二个值与这个的解读类似。我们也可以通过类似于数组的形式往字典里面加元素. Mydict[\u0026quot;jjh\u0026quot;] = 100 ,那么这时候就往里面加入了一个键值对。\n字典中每个键值是唯一的,但是值可以相同,类似于函数。我们也可以通过类似于数组的形式,下标为键来访问值。当我们下标在字典中不存在,利用下标访问就会直接报错。Python 为我们提供了另一种方法来满足我们的需求,利用 Mydict.get(键) 可以获得对应的值,当不存在这个键,会返回 None 。此外,我们也可以指定其返回值,Mydict.get(键,something) ,这样当不存在的时候就会返回这个 something 。\n最后,字典中的 Key 只能是不可变对象。\nSet set 就是数学中的集合,具有无序性和唯一性。里面元素不重复,并且无序导致没法通过下标访问。可以用来给一组数据去重。通过 add(key) remove(key) 等函数去除对应值的元素。\n可以通过 \u0026amp; 求交集, | 求并集, - 求差集等。\nset 中的元素也只能是不可变对象。\n函数 调用函数 调用函数的时候要保证参数个数、参数顺序、参数类型满足函数的定义。然后正确的处理好返回值。\n定义函数 函数的定义 普通函数的定义通过 def 来进行,好比我们要写一个求绝对值的函数,那么就可以如下定义\ndef myabs(x): if x\u0026gt;=0: return x else: return -x 这样我们就可以类似调用 myabs(-5) 来获得 -5 的绝对值。\n如果我们想要定义一个空的函数,也就是什么都不做,那么函数内部的语句可以写 pass 。这类似于C++中的分号的作用?大概是。\n通过 函数.__name__ 可以获得函数的真实名字。\n多个返回值的函数 我们可以在 return 后面写多个参数,这样在返回的时候会返回一个元组。我们接受返回值的时候,也可以并拍写多个变量,这样就会把返回值的元组中的各个值依次赋给每个变量。\n函数的参数 Python的函数定义非常简单,但灵活度却非常大。除了正常定义的必选参数外,还可以使用默认参数,可变参数,关键字参数,这使得函数定义出来的接口,不但能处理复杂的参数,还可以简化调用者的代码。\n默认参数 当我们调用一个函数,有几个参数大多数情况下是一个默认的值,少数时候是变的,那么我们可以用到默认参数,默认参数的使用我们可以在那个参数的后面加上 =something ,这意思说是,这个参数默认为 something\ndef poww(x,n=2): k = 1 while n\u0026gt;0: n = n-1 k = k*x return k 例如上面这个例子,我们要求 $2^5$ ,那么可以调用 poww(2,5) 。那么我们如果要求 $2^2$ ,那么就可以直接调用poww(2) ,另一个参数可以不写,那么就是默认的2。\n需要注意的是,必选参数在前,默认参数要在后。否则话会产生歧义,因为解释器不知道你到底传入的参数是默认参数还是必选参数。\n此外,当我们有多个默认参数的时候,我们要在前面几个默认参数使用默认值,而后面那个用传入参数的时候,我们需要加上参数名,也就是 参数名 = value 这样传入。例子如下:\ndef poww(x,n=2,z=3): k = 1 f = n+z while n\u0026gt;0: f = f-1 k = k*x return k 这时候,我们如果要调用 poww(5,4) ,代表求的是 $5^{4+3}$ ,如果我们要求 $5^{2+7}$ ,可以按照如下方法调用,使用 poww(5,z=7) 。\n最后还有一点很重要,默认参数要指向 不变对象 。否则当我们重复调用会发生错误。\n可变参数 我们很多时候可能需要一个函数内传入不定量个数的参数,这就要用到可变参数,可变参数就是数量可变。\n我们很容易想到,可以往里面传列表或者元组 ,不过这样当我们传之前还有要把所有的参数归到一个列表和元素中,这样太麻烦。Python给出了一个简便写法,我们只需要在参数面前加一个 * ,这样我们就可以传入可变个参数。而且调用的时候,按普通的调用方法来即可,不需要传入元组。\ndef test(*numbers): sum = 0 for i in numbers: sum = sum + i*i return sum print(test(1,2,3)) # 输出 14 那么当这时候我们想往里面传一个元组,或者列表。当然可以挨个用数组访问然后写,不过Python也给了我们一个简便做法,只需要在列表或者元组前面加一个 * ,就可以把它结构解开,然后挨个元素传入函数中。\ndef test(*numbers): sum = 0 for i in numbers: sum = sum + i*i return sum Mylist = list(range(5)) print(test(*Mylist)) #输出30 关键词参数 可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。\ndef myfun(**kw): print(kw) myfun(city = \u0026#34;jz\u0026#34;,name = \u0026#34;zs\u0026#34;) # 输出 {\u0026#39;city\u0026#39;: \u0026#39;jz\u0026#39;, \u0026#39;name\u0026#39;: \u0026#39;zs\u0026#39;} Mydict = {\u0026#34;city\u0026#34;:\u0026#34;jz\u0026#34;,\u0026#34;name\u0026#34;:\u0026#34;zs\u0026#34;} myfun(**Mydict) # 输出 {\u0026#39;city\u0026#39;: \u0026#39;jz\u0026#39;, \u0026#39;name\u0026#39;: \u0026#39;zs\u0026#39;} 参数前面加 ** 即是关键词参数。当然我们也可以传入参数时,用dict,然后加 ** 解开结构传入。\n命名关键词参数 我们可以在上述的基础上,传入特定的参数,给相应的参数命名。这需要我们在定义各个参数之前,在参数之前加上 * ,好比 def person(name,age,*,city,job) 规定了,我们传入的两个关键词参数名字只能是 city 和和 job 。不过,当我们前面有一个参数是可变参数,那么就可以不用加那个 * 。好比像如下方法定义上面那个函数, def person(name,age,*city,job) 。在这里 city 是一个可变参数,后面的 job 就是一个命名关键词参数。\n参数调用顺序 在函数的参数中,上述各类参数可以组合使用。但是要注意顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。\n函数的递归调用 函数的递归调用就是自己调用自己,QAQ,C++里面搞得也挺多的,就不赘述了。\n高级特性 切片 切片操作感觉真的是Python很方便的一个特性了。\n字符串,列表,元组支持切片。\n好比我们有一个列表,里面有数,0~100,我们要取其中的奇数,那么我们就需要每隔一个数取一个数,我们可以通过for循环来实现这个操作,但是呢,Python有一种更便利的方法来实现,那就是切片。他的用法类似于matlab中的冒号表达式,begin:end:step 这三个变量分别代表起始,终止和步长,也就是每个多少取一个,这三个参数都可以省略,省略时默认为序列起始点,序列终止点,1。这里要注意,序列范围为 [begin,end) ,前闭后开,例子:\nL = list(range(101)) print(L[1:100:2]) # 输出0~100所有的奇数 print(L[-10::2]) # 从倒数第十个数开始输出奇数,输出 [91, 93, 95, 97, 99] print(L[-50:0:-2]) # 从倒数第50个数,往前开始输出奇数,为 51~0中所有奇数 迭代 迭代就是类似于遍历吧,通过 for 可以迭代遍历一个容器内的所有元素。\n字符串和列表,元组,集合,字典这些都是可以用for遍历的,这也叫做可迭代对象。需要注意的是,我们在遍历字典和集合时,因为是无序的,所以两次遍历顺序可能不太一样。\n当我们遍历字典时,默认遍历的是键值。例如下面这样\nL = {\u0026#34;zs\u0026#34;:\u0026#34;rj\u0026#34;,\u0026#34;jjh\u0026#34;:\u0026#34;nb\u0026#34;} for key in L: print(key) # 输出 zs jjh for value in L.values(): print(value) # 输出 rj nb for k,v in L.items(): print(k,v) # 输出 zs rj jjh nb 可以注意到,可以同时迭代两个数,或者多个数。\n列表生成器 列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。\n好比我们生成 [1*1,2*2,3*3,···,n*n] 这样的列表,可以用循环实现,也可以用列表生成式。\n列表生成式格式大概是 [元素 规则] 就是前面是要往里面加的元素的表达式,后面是生成的规则。\nL = [x*x for x in range(1,11)] print(L) # 输出[1, 4, 9, 16, 25, 36, 49, 64, 81, 100] D = [x*x for x in range(1,11) if x % 2 == 0] print(D) # 输出[4, 16, 36, 64, 100] 生成器 我们将上述列表生成式外面的 [] 改成 () ,就变成了一个列表生成器。列表生成器里面每个元素不是原来就存在的,而是你要用的时候他按照规则去生成,可以节省空间。他也是一个可迭代对象,可以通过for循环来访问,此外也可以用 next(迭代器) 来获取下一个元素。\n除了上述方法,我们也可以用函数的方法来定义生成器,当一个函数中有了关键字 : yield 他就不是一个普通的函数了,就变成了一个生成器,按照函数的规则来生成相应数据。规则如下:当我们进入函数的时候,开始从头开始执行,执行到 yield ,函数结束,返回 yield 后面接的内容。然后下次进入函数的时候,从上次结束的地方继续开始,然后这样一直循环,直到再不能取数为止。\n迭代器 凡是可作用于for循环的对象都是Iterable类型,就是可迭代对象;\n凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列,这感觉就像是一个指针呀其实(自我认为),可以通过指针访问可迭代对象中的元素;\n集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。\nPython的for循环本质上就是通过不断调用next()函数实现的,例如:\nfor x in [1, 2, 3, 4, 5]: pass 实际上完全等价于:\n# 首先获得Iterator对象: it = iter([1, 2, 3, 4, 5]) # 循环: while True: try: # 获得下一个值: x = next(it) except StopIteration: # 遇到StopIteration就退出循环 break 函数式编程 高阶函数 map/reduce map() 函数包括两个参数,第一个参数是一个函数,第二个参数是一个序列。map 的作用就是将序列中的每个元素代入到函数中并且求出每个元素对应的值,然后会返回一个相应的 Iterator ,我们可以通过对应的语句,好比 list() ,tuple() 啥的转成对应的序列。\nreduce() 函数也是包括两个参数,一个是函数,一个是序列。reduce 的作用是类似于一个递归的感觉吧大概,好比序列是 L = [1,2,3,4,5] ,有一个函数是 f ,我们暂且不管这个函数的作用是什么,那么如果我们现在调用 reduce(f,L) ,他返回一个 f 函数的返回值,值为 f(f(f(1,2),3),4) 。就是类似于这种嵌套的结构。\nfilter filter() 函数也包括两个参数,一个是函数,一个是序列。他是通过那个函数的返回值是 True or False 来判断是否保留那个序列中的每个元素。返回值也是 Iterator 。\nsorted sorted() 顾名思义,这是一个排序函数,我们往里面传入一个序列,那么他就会默认的对序列按升序排序,并且返回一个这个排序后序列。但是我们传入的序列不会有变动。\n此外,sorted() 里面还可以加关键词 key 键值来确定规则,好比我们可以加 key=abs 这样就可以将序列中所有的元素按照绝对值从小到大的顺序。我们也可以加 reverse=True 来变成降序排序。\n返回函数 我们知道,函数名只是一个指向函数的变量,我们也可以用另一个变量指向这个函数来引用函数,相当于起了一个别名。因此,我们也可以在函数的返回值中返回一个函数,然后将返回值赋值给一个变量,这样就可以通过这个变量来调用返回的函数。\n我们在一个函数中又定义了一个函数,并且,内部函数可以引用外部函数的参数和局部变量,当外部函数返回内部函数时,相关参数和变量都保存在返回的函数中,这种称为“闭包**(Closure)**”的程序结构拥有极大的威力。\n返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。因为这个变量相当于一个静态变量,现在变了,前面相应的结果也会变。\n返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。\n通过 函数.__name__ 可以获得函数的真实名字。\n匿名函数 通过 lambda 可以创建匿名函数,这个就类似于matlab里面的那个 @ 创建的匿名函数。\n格式为: lambda 变量: 返回值\nprint(list(map(lambda x: x*x,range(1,11)))) # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] 我们也可以把匿名函数当作函数的返回值返回。\n装饰器 我们可能想在调用函数之前在前面打印一下函数的运行日志,或者其他的一些内容,其他的操作。\n这样我们就可以通过装饰器来实现,装饰器是为了给函数加一些其他的修饰,但是不需要在原本函数的基础上做改变。\n本质上,装饰器(decorator) 是一个返回函数的高阶函数,一个能打印日志的 decorator 可以如下定义:\ndef log(func): def wrapper(*args,**kw): print(\u0026#34;call %s()\u0026#34; % func.__name__) return func(*args,**kw) return wrapper 调用如下:\n@log def now(): print(\u0026#39;2020-4-18\u0026#39;) print(now()) # 输出 call now() 2020-4-18 在这里, @log 可以等效为 now = log(now) ,那么我们应该怎么理解呢,首先,在我们调用之前,我们就把这个函数传入这个log函数,然后进入 wrapper 函数,先输出了日志,然后返回了一个 func() 函数,然后结束这个函数的定义,又返回了 wrapper 函数,这样就是将日志和原函数组合在一起了。所以最后一起输出\n偏函数 偏函数可以看做一个函数其中某一个参数固定,然后另成一个新函数,这样到时候我们重复调用的时候就会比较方便了。\n当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单。\n当用 functools.partial 之前我们需要引入 functools 模块。\nimport functools int2 = functools.partial(int,base=2) print(int(\u0026#39;10110\u0026#39;,base=2)) # 以二进制来转化这个字符串,得到22 print(int2(\u0026#39;10110\u0026#39;)) # 和上述等价 模块 这个就是类似于头文件的感觉,模块里面包含了很多别人已经写好了的函数,你引入之后可以直接拿来用,能够大大提高自己的编程效率。\n模块是放在包里的,这样可以避免不同模块之间的冲突,包中可以有很多的模块,并且所有包里都有一个相同名字的模块 , __init__.py ,这个文件说明这个目录是一个包,里面的其他的内容是模块。\n模块命名为 包名.模块名 ,这样就有效避免了模块与模块之间的冲突\n模块是一组Python代码的集合,可以使用其他模块,也可以被其他模块使用。\n创建自己的模块时,要注意:\n模块名要遵循Python变量命名规范,不要使用中文、特殊字符; 模块名不要和系统模块名冲突,最好先查看系统是否已存在该模块,检查方法是在Python交互环境执行import abc,若成功则说明系统存在此模块。 使用模块 在使用模块之前只需要 import 模块名 ,就可以通过 模块名.方法 的方式来调用这个模块里面的方法。\n当我们在命令行运行模块文件时,Python解释器把一个特殊变量__name__置为__main__,而如果在其他地方导入模块时,if判断将失败,因此,这种if测试可以让一个模块通过命令行运行时执行一些额外的代码,最常见的就是运行测试。\n封装 在一个模块中,我们可能会定义很多函数和变量,但有的函数和变量我们希望给别人使用,有的函数和变量我们希望仅仅在模块内部使用。在Python中,是通过_前缀来实现的。\n正常的函数和变量名是公开的(public)。但是外部不需要引用的函数全部定义成private,只有外部需要引用的函数才定义为public。\n安装第三方模块 我们用包管理工具 pip 来安装第三方模块。\n安装一个模块只需要 pip install 库名 ,这样就成功安装了一个包了。\n此外,我们也可以直接安装 Anaconda ,这是一个基于Python的数据处理和科学计算平台,它已经内置了许多非常有用的第三方库,我们装上Anaconda,就相当于把数十个第三方模块自动安装好了,非常简单易用。\n下载地址为 : Anaconda官网\n模块搜索路径 当我们加载一个模块时,Python会在指定路径搜索对应的模块文件,如果找不到就会返回错误。\n默认情况下,Python解释器会搜索当前目录,所有已安装的内置模块和第三方模块,搜索路径存放在 sys 模块的 path 变量中。我们可以通过 sys.path 来查看。\n我们要改动这个目录,往里面添加我们需要的,有两个方法。\n直接通过 sys.path.append() 添加对应的路径,但是运行结束后会失效。 设置环境变量PYTHONPATH,该环境变量的内容会被自动添加到模块搜索路径中。设置方式与设置Path环境变量类似。注意只需要添加你自己的搜索路径,Python自己本身的搜索路径不受影响。 资料补充 廖雪峰的Python教程 Anaconda介绍、安装及使用教程 ","permalink":"https://blog.zzsqwq.cn/posts/66/","summary":"\u003ch1 id=\"python学习笔记\"\u003ePython学习笔记\u003c/h1\u003e\n\u003ch2 id=\"python的不同解释器\"\u003ePython的不同解释器\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eCPython\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e这是自带的用C语言开发的解释器,因此叫CPython。它也是使用最广的Python解释器。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eIPython\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e这是基于CPython之上的一个交互式解释器,只是相比于CPython多了交互上的优化。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003ePyPy\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e它的目标是执行速度。PyPy采用\u003ca href=\"http://en.wikipedia.org/wiki/Just-in-time_compilation\"\u003eJIT技术\u003c/a\u003e,对Python代码进行动态编译(注意不是解释),所以可以显著提高Python代码的执行速度。他与CPython略有不同。\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e","title":"Python初步学习"},{"content":"C++大数类设计思路 洛谷大数类的评测结果(开了氧气优化) 这个第四个点真的优化不过去了QAQ,24W的数据,丧心病狂\n整体构思 构造大数类名为 BigNumber ,首先想法是用字符串读入大数,然后将其转化为vector数组倒序分位存储的整数,然后通过一个 len 来记录数字的位数,便于做运算。还设计了一个标记变量,用于标记这数为正数还是负数。\n构造函数 我用了两种构造函数,一个是无参构造函数,一个是拷贝构造函数,当然还有一个有参构造函数,但是实际过程中我没有用到。无参构造函数用于上述类成员的初始化,拷贝构造函数用于复制一个相同的大数类进行运算。有参构造函数可以用于对类成员的复制。\n重载运算符 重载 \u0026ldquo;+\u0026rdquo; 首先在类中进行了声明, BigNumber operator + (const BigNumber \u0026amp;b); ,用当前类 *this 来和引入的类 b 进行加法运算,返回值为一个 BigNumber 类。 在类的外部进行重载的定义,先将用拷贝构造函数将当前的类 *this 拷贝为 a ,然后对 a 和 b 进行加法运算,模拟竖式,对应位相加,大于10则进位,最后去掉尾部的 0 即可。 BigNumber BigNumber::operator + (const BigNumber \u0026amp;b) //重载 \u0026#34;+\u0026#34; 定义 { BigNumber Result; BigNumber a(*this); Result.len = max(a.len,b.len)+1; int add=0; for(int i=0;i\u0026lt;Result.len||add!=0;i++) { int p=add; if(i\u0026lt;a.len) p+=a.v[i]; if(i\u0026lt;b.len) p+=b.v[i]; add=p/10; Result.v.push_back(p%10); } while(Result.v[Result.v.size()-1]==0 \u0026amp;\u0026amp; Result.v.size() \u0026gt; 1) { Result.v.pop_back(); } Result.len=Result.v.size(); return Result; } 重载 \u0026ldquo;\u0026lt;\u0026rdquo; 因为进行减法前需要比较两个大数类的大小,我就先重载了 \u0026lt; 。思路就是先比较a、b两个大数的长度,长的那个肯定比较大,如果两个长度相等。从尾部开始依次向前比较,如果不相等的话,就看两个数的相对大小,大的那个肯定整体比较大。如果总是相等,到了最后,就返回相应的值表示他们相等。这里我的返回值为int类型,用的标记是:如果两个相等,返回-1,如果前者小于后者,返回1,如果前者大于后者,返回0.\nint BigNumber::operator \u0026lt; (const BigNumber \u0026amp;b) // 重载 \u0026#34;\u0026lt;\u0026#34; 定义 { BigNumber a(*this); if(a.len \u0026lt; b.len) return 1; if(a.len \u0026gt; b.len) return 0; for(int i=a.len-1;i\u0026gt;=0;i--) { if(a.v[i]!=b.v[i]) { return a.v[i] \u0026lt; b.v[i]; } } return -1; } 重载 \u0026ldquo;-\u0026rdquo; 首先在类中进行了声明, BigNumber operator - (BigNumber \u0026amp;b); ,用当前类 *this 来和引入的类 b 进行减法运算,返回值为一个 BigNumber 类。 在类的外部进行重载的定义,先将用拷贝构造函数将当前的类 *this 拷贝为 a ,然后对 a 和 b 进行减法运算。如果 a\u0026lt;b ,那么我们就把 flag 设为 true ,标志得数为一个负数,然后用 swap 交换两个类,保证总是大数减小数。减法的话就是从前往后扫,对应位相减,如果不够减的就进行借位。如果借完位当前位置小于0了,那么就再向前借位。最后要去掉结尾多于的0. BigNumber BigNumber::operator - (BigNumber \u0026amp;b) // 重载 \u0026#34;-\u0026#34; 定义 { BigNumber Result; BigNumber a(*this); if(a\u0026lt;b==1) { swap(a,b); Result.flag=true; } Result.len=a.len; for(int i=0;i\u0026lt;a.len;i++) { if(a.v[i]\u0026lt;0) { a.v[i]+=10; a.v[i+1]--; } if(a.v[i] \u0026lt; b.v[i]\u0026amp;\u0026amp;i\u0026lt;b.len) { a.v[i]+=10; a.v[i+1]--; } if(i\u0026lt;b.len) Result.v.push_back(a.v[i]-b.v[i]); else Result.v.push_back(a.v[i]); } while(Result.v[Result.len-1]==0 \u0026amp;\u0026amp; Result.len \u0026gt; 1) { Result.v.pop_back(); Result.len--; } return Result; } 重载 \u0026ldquo;*\u0026rdquo; 首先在类中进行了声明, BigNumber operator * (BigNumber \u0026amp;b);,用当前类 *this 来和引入的类 b 进行乘法运算,返回值为一个 BigNumber 类。 在类的外部进行重载的定义,先将用拷贝构造函数将当前的类 *this 拷贝为 a ,然后对 a 和 b 进行乘法运算。乘法也是模拟竖式运算,两个位数相乘对应的得数中的哪一位不难发现,因此只需要边乘边进位即可,一开始想的是所有乘完之后再进位,后来想了想运算的次序不会影响除和模的运算,所以就可以边乘边取商和模,可以少掉两层循环。算是一个小小的优化。最后要去掉结尾多于的0. BigNumber BigNumber::operator * (BigNumber \u0026amp;b) // 重载 \u0026#34;*\u0026#34; 定义 { BigNumber Result; BigNumber a(*this); Result.len=a.len+b.len; for(int i=0;i\u0026lt;Result.len;i++) Result.v.push_back(0); for(int i=0;i\u0026lt;a.len;i++) { for(int j=0;j\u0026lt;b.len;j++) { Result.v[i+j]+=a.v[i]*b.v[j]; Result.v[i+j+1]+=Result.v[i+j]/10; Result.v[i+j]%=10; } } while(Result.v[Result.v.size()-1]==0 \u0026amp;\u0026amp; Result.v.size() \u0026gt; 1) { Result.v.pop_back(); } Result.len=Result.v.size(); return Result; } 重载 \u0026ldquo;/\u0026rdquo; 首先在类中进行了声明,BigNumber operator / (BigNumber \u0026amp;b);,用当前类 *this 来和引入的类 b 进行除法运算,返回值为一个 BigNumber 类。\n在类的外部进行重载的定义,先将用拷贝构造函数将当前的类 *this 拷贝为 a ,然后对 a 和 b 进行除法法运算。我选择了做除法的时候大数类中同时存储商和余数,这样可以加快效率,因为我自己的想法是把除法和取模一起处理,求得商的同时,模也能求出来。因此他们的框架肯定是相差无几的,所以我选择了一次性算出来两个,在大数类中用两个vector数组分别存商和余数,求商和余数我用的是减法的策略,分下面三种情况来讨论\na\u0026lt;b :很显然商为0,余数为a。 a==b :很显然商为1,余数为0。 a\u0026gt;b :这个是最难处理的,我们想想一下模拟除法的竖式运算,先在b的后面填0,让a和b的位数相同,然后再一直对a进行减法运算,将得到的数排列起来即可。里面细节还是挺多的,具体的看代码。最后要去掉结尾多于的0. BigNumber BigNumber::operator / (BigNumber \u0026amp;b) // 重载 \u0026#34;/\u0026#34; 定义 { BigNumber Result; BigNumber a(*this); if(a\u0026lt;b==1) { Result.v.push_back(0); for(int i=0;i\u0026lt;a.v.size();i++) { Result.m.push_back(a.v[i]); } return Result; } if(a\u0026lt;b==-1) { Result.v.push_back(1); Result.m.push_back(0); Result.len=1; } if(a\u0026lt;b==0) { int size = a.len-b.len; for(int i=size;i\u0026gt;=0;i--) { BigNumber p(b); int cnt=0; for(int j=1;j\u0026lt;=i;j++) { p.v.insert(p.v.begin(),0); } p.len = p.v.size(); while((a-p).flag==false) { a=a-p; cnt++; } if(i==size) { for(int j=1;j\u0026lt;=size;j++) { Result.v.push_back(0); } Result.v.push_back(cnt); } else { Result.v[i] = cnt; } } while(Result.v[Result.v.size()-1]==0 \u0026amp;\u0026amp; Result.v.size() \u0026gt; 1) { Result.v.pop_back(); } Result.len=Result.v.size(); for(int i=0;i\u0026lt;a.v.size();i++) { Result.m.push_back(a.v[i]); } } return Result; } 重载 \u0026ldquo;%\u0026rdquo; 这个和除法的类似,我们除法的其实已经求出来模了,这个只是象征性的搞一搞。QAQ。\nBigNumber BigNumber::operator % (BigNumber \u0026amp;b) //重载 \u0026#34;%\u0026#34; 定义 { BigNumber Result; BigNumber a(*this); if(a\u0026lt;b) { Result.v.push_back(0); return Result; } else { int size = a.len-b.len; for(int i=size;i\u0026gt;=0;i--) { BigNumber p(b); for(int j=1;j\u0026lt;=i;j++) { p.v.insert(p.v.begin(),0); } p.len = p.v.size(); while((a-p).flag==false) { a=a-p; } } for(int i=0;i\u0026lt;a.v.size();i++) { Result.v.push_back(a.v[i]); } } return Result; } 其中遇到的问题 在做减法的时候,会出现莫名奇怪的数据,后来发现是由于访问b数组的时候越界,而且vector数组的clear只是将数组的size置为了0,而不是将所有数据都莫抹除,而且vector通过下标访问越界还不会报错,我整个人都傻了,调了巨长时间。 在做除法的时候,一度自闭。本来是只是一直减,这样效率真的巨tm慢。后来想到了用这个办法好像可以优化到 log 级别的,但是好难调试啊。。从昨天下午一直搞到现在。 因为swap这个东西,好像会影响到类的源数据,所以我就多定义了几个数,分别对他们进行操作,这样就不会相互影响,虽然看起来挺丑的。 整体的代码实现 /* Name: BigNumber Class Copyright: Zs Author: Zs Date: 04/04/20 09:08 Description: A BigNumber Class */ #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; #include\u0026lt;vector\u0026gt; using namespace std; class BigNumber { private: vector\u0026lt;int\u0026gt; v; // 和,差,积,商 vector\u0026lt;int\u0026gt; m; // 余数,当无余数的时候 size 为0 int len; // 数字的长度 = v.size() bool flag; //是否为负数的标志 public: BigNumber();//无参构造函数 BigNumber(string s) //带参数的构造函数 { *this=s; } BigNumber(const BigNumber \u0026amp;); // 拷贝构造函数 BigNumber operator = (const string s); // 重载 \u0026#34;=\u0026#34; 声明 BigNumber operator = (int k); // 重载输入的数为整型的时候的 \u0026#34;=\u0026#34; 声明 int operator \u0026lt; (const BigNumber \u0026amp;b); // 重载 \u0026#34;\u0026lt;\u0026#34; 声明 BigNumber operator + (const BigNumber \u0026amp;b); // 重载 \u0026#34;+\u0026#34; 声明 BigNumber operator - (BigNumber \u0026amp;b); // 重载 \u0026#34;-\u0026#34; 声明 BigNumber operator * (BigNumber \u0026amp;b); // 重载 \u0026#34;*\u0026#34; 声明 BigNumber operator / (BigNumber \u0026amp;b); //重载 \u0026#34;/\u0026#34; 声明 BigNumber operator % (BigNumber \u0026amp;b); //重载 \u0026#34;%\u0026#34; 声明 void print() //输出函数 { if(flag) { printf(\u0026#34;-\u0026#34;); flag=false; } for(int i=v.size()-1;i\u0026gt;=0;i--) printf(\u0026#34;%d\u0026#34;,v[i]); printf(\u0026#34;\\n\u0026#34;); for(int i=m.size()-1;i\u0026gt;=0;i--) printf(\u0026#34;%d\u0026#34;,m[i]); } }; BigNumber::BigNumber() //无参构造函数 { v.clear(); m.clear(); len = 0; flag=false; } BigNumber::BigNumber(const BigNumber \u0026amp;T) // 拷贝构造函数 { v.assign(T.v.begin(),T.v.end()); len = T.len; flag = T.flag; } BigNumber BigNumber::operator = (const string s) // 重载 \u0026#34;=\u0026#34; 定义 { len = s.length(); for(int i=0;i\u0026lt;len;i++) { v.push_back(s[len-1-i]-\u0026#39;0\u0026#39;); } return *this; } BigNumber BigNumber::operator = (int k) // 重载输入的数为整型的时候的 \u0026#34;=\u0026#34; 定义 { while(k) { v.push_back(k%10); k/=10; len++; } len--; return *this; } int BigNumber::operator \u0026lt; (const BigNumber \u0026amp;b) // 重载 \u0026#34;\u0026lt;\u0026#34; 定义 { BigNumber a(*this); if(a.len \u0026lt; b.len) return 1; if(a.len \u0026gt; b.len) return 0; for(int i=a.len-1;i\u0026gt;=0;i--) { if(a.v[i]!=b.v[i]) { return a.v[i] \u0026lt; b.v[i]; } } return -1; } BigNumber BigNumber::operator + (const BigNumber \u0026amp;b) //重载 \u0026#34;+\u0026#34; 定义 { BigNumber Result; BigNumber a(*this); Result.len = max(a.len,b.len)+1; int add=0; for(int i=0;i\u0026lt;Result.len||add!=0;i++) { int p=add; if(i\u0026lt;a.len) p+=a.v[i]; if(i\u0026lt;b.len) p+=b.v[i]; add=p/10; Result.v.push_back(p%10); } while(Result.v[Result.v.size()-1]==0 \u0026amp;\u0026amp; Result.v.size() \u0026gt; 1) { Result.v.pop_back(); } Result.len=Result.v.size(); return Result; } BigNumber BigNumber::operator - (BigNumber \u0026amp;b) // 重载 \u0026#34;-\u0026#34; 定义 { BigNumber Result; BigNumber a(*this); if(a\u0026lt;b==1) { swap(a,b); Result.flag=true; } Result.len=a.len; for(int i=0;i\u0026lt;a.len;i++) { if(a.v[i]\u0026lt;0) { a.v[i]+=10; a.v[i+1]--; } if(a.v[i] \u0026lt; b.v[i]\u0026amp;\u0026amp;i\u0026lt;b.len) { a.v[i]+=10; a.v[i+1]--; } if(i\u0026lt;b.len) Result.v.push_back(a.v[i]-b.v[i]); else Result.v.push_back(a.v[i]); } while(Result.v[Result.len-1]==0 \u0026amp;\u0026amp; Result.len \u0026gt; 1) { Result.v.pop_back(); Result.len--; } return Result; } BigNumber BigNumber::operator * (BigNumber \u0026amp;b) // 重载 \u0026#34;*\u0026#34; 定义 { BigNumber Result; BigNumber a(*this); Result.len=a.len+b.len; for(int i=0;i\u0026lt;Result.len;i++) Result.v.push_back(0); for(int i=0;i\u0026lt;a.len;i++) { for(int j=0;j\u0026lt;b.len;j++) { Result.v[i+j]+=a.v[i]*b.v[j]; Result.v[i+j+1]+=Result.v[i+j]/10; Result.v[i+j]%=10; } } while(Result.v[Result.v.size()-1]==0 \u0026amp;\u0026amp; Result.v.size() \u0026gt; 1) { Result.v.pop_back(); } Result.len=Result.v.size(); return Result; } BigNumber BigNumber::operator / (BigNumber \u0026amp;b) // 重载 \u0026#34;/\u0026#34; 定义 { BigNumber Result; BigNumber a(*this); if(a\u0026lt;b==1) { Result.v.push_back(0); for(int i=0;i\u0026lt;a.v.size();i++) { Result.m.push_back(a.v[i]); } return Result; } if(a\u0026lt;b==-1) { Result.v.push_back(1); Result.m.push_back(0); Result.len=1; } if(a\u0026lt;b==0) { int size = a.len-b.len; for(int i=size;i\u0026gt;=0;i--) { BigNumber p(b); int cnt=0; for(int j=1;j\u0026lt;=i;j++) { p.v.insert(p.v.begin(),0); } p.len = p.v.size(); while((a-p).flag==false) { a=a-p; cnt++; } if(i==size) { for(int j=1;j\u0026lt;=size;j++) { Result.v.push_back(0); } Result.v.push_back(cnt); } else { Result.v[i] = cnt; } } while(Result.v[Result.v.size()-1]==0 \u0026amp;\u0026amp; Result.v.size() \u0026gt; 1) { Result.v.pop_back(); } Result.len=Result.v.size(); for(int i=0;i\u0026lt;a.v.size();i++) { Result.m.push_back(a.v[i]); } } return Result; } BigNumber BigNumber::operator % (BigNumber \u0026amp;b) //重载 \u0026#34;%\u0026#34; 定义 { BigNumber Result; BigNumber a(*this); if(a\u0026lt;b) { Result.v.push_back(0); return Result; } else { int size = a.len-b.len; for(int i=size;i\u0026gt;=0;i--) { BigNumber p(b); for(int j=1;j\u0026lt;=i;j++) { p.v.insert(p.v.begin(),0); } p.len = p.v.size(); while((a-p).flag==false) { a=a-p; } } for(int i=0;i\u0026lt;a.v.size();i++) { Result.v.push_back(a.v[i]); } } return Result; } int main() { //\tfreopen(\u0026#34;test.in\u0026#34;,\u0026#34;r\u0026#34;,stdin); //\tfreopen(\u0026#34;test.out\u0026#34;,\u0026#34;w\u0026#34;,stdout); string s1,s2; cin\u0026gt;\u0026gt;s1\u0026gt;\u0026gt;s2; BigNumber a,b,c,e,f,k,j; a=s1,b=s2; e=s1,f=s2; k=s1,j=s2; c=a+b; c.print(); c=a-b; c.print(); c=k*j; c.print(); c=e%f; c.print(); return 0; } ","permalink":"https://blog.zzsqwq.cn/posts/64/","summary":"\u003ch1 id=\"c大数类设计思路\"\u003eC++大数类设计思路\u003c/h1\u003e\n\u003ch3 id=\"洛谷大数类httpswwwluogucomcnproblemu111551的评测结果开了氧气优化\"\u003e\u003ca href=\"https://www.luogu.com.cn/problem/U111551\"\u003e洛谷大数类\u003c/a\u003e的评测结果(开了氧气优化)\u003c/h3\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"https://blog.zzsqwq.cn/usr/uploads/2020/08/4200651250.png\" alt=\"BigNumber.png\" /\u003e\n\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e这个第四个点真的优化不过去了QAQ,24W的数据,\u003cdel\u003e丧心病狂\u003c/del\u003e\u003c/strong\u003e\u003c/p\u003e","title":"C++大数类的实现"},{"content":"Linux系统常见命令 基本操作 **cd (Change Directory)**命令:跳转目录\ncd path : path为路径,进入相应目录 cd # 或 cd ~ :回到主目录 cd - : 回到上次所在目录 cd !$ :将上个命令的参数做为输入 cd .. :回到上层目录 ls (List) 命令:列出当前目录文件\nls : 显示当前目录文件\nls -a:显示全部的文件及文件夹,包括隐藏的文件和文件夹。\nls -l : 显示较全的文件信息,包括权限,用户,用户组。\nTab 键:通过按Tab可以进行自动补全。如果当前目录有前缀相同的文件,则按两下Tab可以显示出所有以具有该前缀的文件。\nmv (Move) 命令:移动(剪切)文件,也可以用作一个等效给文件或目录的重命名。\n通过 mv 文件x 目录a 可以将当前目录下的文件x移入目录k。\ncp (Copy) 命令:拷贝,将一个文件或目录拷贝到另一个文件或目录。\n通过 cp [options] 文件x 目录a 可以将当前目录下的文件x复制到目录a。\n-a:此选项通常在复制目录时使用,它保留链接、文件属性,并复制目录下的所有内容。其作用等于dpR参数组合。 -d:复制时保留链接。这里所说的链接相当于Windows系统中的快捷方式。\n-f:覆盖已经存在的目标文件而不给出提示。 -i:与-f选项相反,在覆盖目标文件之前给出提示,要求用户确认是否覆盖,回答\u0026quot;y\u0026quot;时目标文件将被覆盖。\n-p:除复制文件的内容外,还把修改时间和访问权限也复制到新文件中。 -r:若给出的源文件是一个目录文件,此时将复制该目录下所有的子目录和文件。\n-l:不复制文件,只是生成链接文件。 pwd(Print Working Directory) 命令:打印出当前工作目录\nmkdir 命令 : mkdir name创建一个名为name的文件夹\nrm (Remove) 命令 :删除文件,删除文件后不可恢复。特殊的 ,**rmdir ** 为删除文件夹命令,rm -r是先删除目录内的内容,再删除目录。 rm -i 为交互式进行删除,一个个确定。rm -f 为强制删除(慎用)。\ngedit 命令:gedit path 打开编辑某个文件。path为绝对路径或相对路径。\ntouch 命令:touch name 创建一个文件,name包含拓展名。\ncat 命令:打开指定文件, 并显示其中内容在终端,并且可以将其复制到一个另文件中。如果cat后面加多个文件名,那么就会打开多个文件。\ntar 命令:压缩或解压命令。tar [参数] 打包文件名 要打包的各个文件 。\n参数表:\n参数 含义 -c 生成档案文件,创建打包文件 -v 列出归档解档的详细过程,显示进度 -f 指定档案文件名称,f后面一定是.tar文件,所以放选项最后 -t 列出档案中包含的文件 -x 解开档案文件 打包实例: tar -cvf 文件名 要打包的文件 解压实例:tar -xvf 压缩包名\n不同的查找方式 find :使用方法为find \u0026lt;指定目录\u0026gt;\u0026lt;指定条件\u0026gt;\u0026lt;指定动作\u0026gt; ,如何find后面不加任何参数,那么就默认搜索当前目录及其子目录,并显示在屏幕上。\n\u0026lt;指定目录\u0026gt;:用于指定要搜索的目录,默认为当前所在目录。\n\u0026lt;指定条件\u0026gt;:指定所要搜索文件的特征。\n-name :按文件名查找 -perm:按文件权限查找 -depth:查找时先在当前目录查找,然后查找其他子目录。 -prune:不在当前指定路径查找。如果同时指定-depth,则此选项被忽略。 -user/-nouser:按照文件属主查找/查找无效属主文件 -group/-nogroup:按照文件属组查找/查找无效属组文件 -newer file1 !file2:查找更改时间比file1新比file2旧的文件。 -type:查找某一类型文件,b:块设备文件,d:目录,c:字符设备文件,P:管道文件,l:符号链接文件,f:普通文件。 locate :等价于 find -name ,但是速度要快,因为locate在一个本地数据库中存放了所有本地文件信息,每天自动更新,我们查找之前需要通过 updatedb 手动更新其中内容,不然可能会导致新改动的文件查找不到。\nwhereis :whereis可以用于程序名的搜索,可以通过参数 -s,-m,-s 分别搜索二进制文件,man说明文件,和源代码文件。如果省略参数,则返回所有信息。不过这个也是从本地数据库里面进行搜索。\nwhich :只能用于寻找可执行文件,并通过path变量寻找。\n关于查找方式的总结,find命令非常强大,搜索全盘,而且可以配合多种参数进行各种各样的搜索。 而locate能做到搜索的更快,因为一种特殊的搜索位置,但是功能要略逊于find。whereis和which都是对于指定类型的搜索,专精某一方面。\n软链接和硬链接 首先我了解到,linux文件系统中,每一个文件都会有一个编号,称为索引节点号inode。也就是i节点。\n链接呢,我的感觉就是,建立一个源文件和链接文件的映射,两个之间会有一定的关系存在。\n创建链接的方式为 ln 源文件 目标文件 ,默认为硬链接,软链接为 ln -s 源文件 目标文件 。\n对于软链接,很像快捷方式,可以跨文件系统(也就是说可以存在于不同的文件系统中),而且他有一个单独的inode,然后通过软连接可以打开源文件。\n对于硬链接,就像是整了一个毛一样的东西出来,很像备份吧,而且两者名字可不同,他们的inode是同一个,只是把inode link count 域增加了1,也就是多了加了一个索引项,因为他们是一毛一样的东西,那么就肯定不能跨文件系统了,因为你这个东西在这个文件系统里面是代表这个东西,在另一个里面就不一定是了,会产生错误。\n关于他们的几点其他区别如下\n软链接可以对一个不存在的文件名进行链接,如果用编辑器打开这个目标文件,那么会默认创建一个名为filename的文件,而硬链接肯定不行了,因为你文件不存在,他也就没有inode,无从创建链接。\n软链接可以跨文件系统,硬链接不行。\n软链接可以链接目录,硬链接不行。百度了解到,因为硬链接和源文件用的一个inode,用硬链接链接可以会形成循环依赖,导致系统死机。\n硬链接在源文件删除后依然可以访问,因为它具有源文件的inode,而软链接在源文件删除后无法对源文件进行访问,因为inode没有了,索引不到了。\n我们对硬链接文件中的内容进行修改也会影响到源文件,因为他们是同一个文件。当然软链接也可以,因为他就是相当于打开了源文件。\n其他常见操作\n新建一个用户:通过sudo useradd -m name 会创建一个名为name的用户,看/home文件下会显示名为name的用户,可以通过 sudo passwd name 来为用户设置密码,通过su name来切换用户,如果想要删除则通过sudo userdel [-r] name 来删除,加上-r代表删除对应文件夹。我们可以通过命令来查看etc中的passwd文件,就能够看到是否创建成功。\n权限的修改:我们可以通过sudo gedit /etc/sudoers 打开sudoers文件修改 # User privilege specification 下的目录,添加\u0026lt;用户名\u0026gt; ALL=(ALL:ALL) ALL 来为用户添加sudo权限。\n连接网络\n无线网 nmcli dev wifi 查看可连接的无线网络 nmcli dev wifi connect name password password name为对应的wifi名称,而后面的password则是对应的密码。 有线网拨号上网 sudo ifconfig eth0 down/up 为关闭或者开启网卡驱动。 sudo pppoeconf 建立拨号连接,对于有线网卡输入 sudo pppoeconf eth0 然后输入拨号的用户名以及密码即可连接到网络。 sudo和su一些区别\nsu(substitute user):切换用户。 sudo:sudo是通过另一个用户来执行命令,也就是说一个命令需要root权限,你并不需要直接跑到root用户下执行,只需要通过sudo然后输入root的密码即可执行相应的命令。 apt-get\napt-get,是一条linux命令,适用于deb包管理式的操作系统,主要用于自动从互联网的软件仓库中搜索、安装、升级、卸载软件或操作系统。通常搭配sudo命令使用。 Vim的常用操作 首先通过 sudo apt-get install vim 来安装Vim 通过 vim name 来编辑name这个文件,如果不存在那么就会创建一个。\nVim的使用\nVim分为了三种模式,分别是命令模式(Command mode),输入模式(Insert mode),底线命令模式(Last line mode)。\n命令模式\n我们刚进入vim就是进入了命令模式,可以通过输入 i或a或o 来切换到输入模式,也可以通过输入x来删除当前光标后的字符,还有一系列操作可以进行,也可以输入 : 来进入底线命令模式。\n一些常用命令\n/word 或 ?word :向光标之下 / 光标之上搜索word这个字符串。 n / N :继续上一个搜索操作 / 进行与上一个搜索操作相反的搜索 ZZ :按两下大写的Z,那么就是直接保存后离开。 输入模式\n输入模式也就是对文本进行编辑,和普通的类似。里面好像有挺多快捷键的,可以通过Page Up/Page Down 来上下翻页,可以通过 HOME/END 来将光标移到行首/行尾。通过 Insert 可以将光标切换为输入/替换模式,光标相应的变为竖线/下划线。通过 Esc 可以退出输入模式,切换到命令模式。\n底线命令模式\n输入 :命令 可以执行非常多的操作,一些常用命令如下。\n:set nu / :set nonu : 设置行号,取消行号。 :n1,n2s/word1/word2/g :将n1~n2行中所有的word1替换为word2,g后加c则每次替换前需要用户手动确认,如果加上i则忽略大小写。 :1,$s/word1/word2/g 或 $s/word1/word2/g :将第一行到最后一行中的word1替换为word2,g后加 c 则每次替换前需要用户确认,如果加上 i (ignore) 则忽略大小写。 :w / :w! :分别为保存,强制保存。 :q / :q! :分别为离开vim,强制离开vim,后者是不需要保存的时候可以选择直接退出。 :wq / :wq! : 分别为存储后离开,强制存储后离开,我们发现加个叹号!一般就是强制的意思。 :w [filename] :将文本保存成一个叫filename的文件,类似于另存为。 :r [filename] :将文本文件filename读入写在光标之后。 :n1,n2 w filename :将文本n1~n2行保存在的filename中(新建一个文件保存)。 :! command :暂时离开vim到终端中 ","permalink":"https://blog.zzsqwq.cn/posts/63/","summary":"\u003ch2 id=\"linux系统常见命令\"\u003eLinux系统常见命令\u003c/h2\u003e\n\u003ch3 id=\"基本操作\"\u003e基本操作\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e**cd (Change Directory)**命令:跳转目录\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003ecd path\u003c/strong\u003e : path为路径,进入相应目录\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003ecd #\u003c/strong\u003e 或 \u003cstrong\u003ecd ~\u003c/strong\u003e :回到主目录\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003ecd -\u003c/strong\u003e : 回到上次所在目录\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003ecd !$\u003c/strong\u003e :将上个命令的参数做为输入\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003ecd ..\u003c/strong\u003e :回到上层目录\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"https://blog.zzsqwq.cn/usr/uploads/2020/08/1228769729.png\" alt=\"image-20200330164354765.png\" /\u003e\n\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e","title":"Linux和Vim入门"},{"content":"4.1 二维曲线 plot函数 基本用法:plot(x,y) ,x和y分别代表横纵坐标,plot函数会将各个点连接起来,形成线,x和y一般为长度相等的向量。 最简单的调用格式:plot(x) 当x为实向量时,则以该元素下表为横坐标,元素的值为纵坐标绘制曲线。 当x为复向量时,则以实部和虚部分别为横纵坐标绘制曲线。 plot(x,y)函数参数的变化形式 当x为向量,y为矩阵:这时x的长度和y的列数(或行数)必须相等。这时候绘制多条曲线,分别是x为横坐标,取与x长度相等的那一个参数作为纵坐标,另一个参数为曲线的条数。如果y的行、列两个参数相等,那么用y的每一列作为纵坐标,曲线条数等于矩阵列数。 当x和y为同型矩阵:这时以x,y对应列元素为横、纵坐标绘制曲线,曲线条数等于矩阵列数。 含多个输入参数:形如 plot(x1,y1,x2,y2,···,xn,yn) ,那么就是以每一个向量对组成一个点,绘制曲线。 含选项的plot函数,plot(x,y,选项) 线型 :通过\u0026quot;-\u0026quot;,\u0026quot;:\u0026quot;,\u0026quot;-.\u0026quot;,\u0026quot;--\u0026quot; 等参数来实现实线,虚线,点画线,双画线。 颜色 :通过 \u0026quot;r\u0026quot;,\u0026quot;g\u0026quot; 等实现曲线颜色的切换。当颜色选项省略,绘图自动循环使用。 数据点标记 :通过 \u0026quot;*\u0026quot;,\u0026quot;o\u0026quot;,\u0026quot;s\u0026quot; 等来实现将数据点用星号,圆圈,方块标记。 fplot函数 可根据参数函数的变化特性自适应地设置采样间隔,当函数值变化缓慢,采样间隔大,当变化快的时候,采样间隔小。\n基本用法:fplot(f,lims,选项) ,参数分别函数(一般采用函数句柄表示),lims为x轴的取值范围,采用二元向量 [xmin,xmax] 来表示,默认值为 [-5,5] 。选项参数与plot函数相同。\n双输入参数函数的用法:fplot(funx,funy,tlims,选项) ,前两个分别为x,y的参数表示,通常以函数句柄的形式给出。tlims为前方函数参数 t 的取值范围,用二元向量 [tmin,tmax] 表示,默认的值为 [-5,5] ,选项参数与上述相同。\n例程 利用不同的线型和颜色在同一坐标内绘制曲线 $y=2e^{-0.5x}sin(2\\pi x)$ 以及其包络线。(包络线:在几何学,某个曲线族的包络线(Envelope),是跟该曲线族的每条线都有至少一点相切的一条曲线。) x=(0:pi/50:2*pi)\u0026#39;; y1=2*exp(-0.5*x)*[1,-1]; %这里绘制的是上下两条包络线,是有两行的矩阵。 y2=2*exp(-0.5*x).*sin(2*pi*x); %这里绘制的是曲线本身 x1=0:0.5:6; y3=2*exp(-0.5*x1).*sin(2*pi*x1); %这里标记的是正弦函数和x轴的交点。 plot(x, y1, \u0026#39;k:\u0026#39;, x, y2, \u0026#39;b--\u0026#39;, x1, y3, \u0026#39;rp\u0026#39;) 利用fplot函数绘制 $y=sin{\\frac{1}{x}}$ 在区间 $[0,0.2]$ 的图像。 fplot(@x sin(1./x),[0,0.2]) 4.2 绘制图形的辅助操作 添加图形标注 title函数:用于给图形添加标题说明\n基本用法:title('图形标题') ,如果是有多行,就用逗号分隔,大括号{}括起来。 LaTeX排版:可在在图形标题中使用LaTeX格式控制符,要用LaTeX时将其控制字符用大括号{}括起来。 控制字体:用 \u0026quot;\\bf\u0026quot; ,\u0026quot;\\it\u0026quot;,\u0026quot;\\rm\u0026quot; 分别控制字体加粗,斜体以及正体。 设置title函数属性 : title(图形标题,属性名,属性值) 其中属性名和属性值对应成对出现。 Color属性:用于设置图形标题文本的颜色,缺省时为黑色。 FontSize属性 :用于设置标题文字字号,缺省时为11。 xlable和ylable函数:给x轴和y轴添加说明\n基本用法: xlable(x轴说明) ,ylable(y轴说明) ,同样还有 zlable等。 text函数和gtext函数:给特定位置说明\n基本用法: text(x,y,说明),x、y参数用来指明说明的位置,后面的说明和title函数类似。 gtext(说明) 这里没有坐标指定位置,通过鼠标的点击来指定位置。 legend函数:用于给图形添加图例\n基本用法:legend(图例1,图例2,···) 其中图例顺序要与plot函数中参数顺序相对应,图例的说明方式与tiele函数标题说明类似。 坐标控制 axis函数:用于设置坐标轴的范围\n基本用法:axis([xmin,xmax,ymin,ymax,zmin,zmax]) ,分别代表了x,y,z轴范围。\n其他用法:通过在axis函数下面加语句来实现控制其他格式。\naxis equal:横纵坐标刻度等长。 axis square:采用正方形坐标系(默认为矩形)。 axis auto:使用默认设置。 axis off/on:不显示/显示坐标轴。 给坐标系加网格和边框\n添加网格:通过 grid on/off 控制显示和不显示网格线,而直接用 grid 用于切换两种形式,如果是带网格则切换为不带,反之亦然。如果不添加语句,则默认不带。 添加边框:通过 box on/off 控制显示不显示边框,用法与 grid 类似,如果不添加语句,则默认带网格。 图形保持 一般情况下绘图命令每执行一次,图形界面就刷新一次,去掉原有图形,绘制新图形,如果要保留原有图形,可使用图形保持命令。通过hold on\\off 来控制是否保留,通过 hold 切换保留和不保留两种选择。\n图形窗口分割 子图:同一图形窗口中的不同坐标系下的图形称为子图。 subplot函数 :subplot(m,n,p) 意思是将图形窗口分成 $m\\times n$ 个子图区域,当前绘制的是第p个子图,区号按行编号。我们在一个图形窗口内,绘制不同的图可以采用不同的分割。 例程 绘制 $sinx$ 、$sin2x$ 、$sin(\\frac{x}{2})$ 的图像,并添加相应的图形标注。 x=linspace(0,6*pi,100); y=[sin(x);sin(2*x);sin(x./2)]; plot(x,y); axis([0,6*pi,-1.1,1.1]); title(\u0026#39;不同频率正弦函数曲线\u0026#39;); xlabel(\u0026#39;X-axis\u0026#39;); ylabel(\u0026#39;Y-axis\u0026#39;); text(2.5,sin(2.5),\u0026#39;sin(x)\u0026#39;); text(1.5,sin(3),\u0026#39;sin(2*x)\u0026#39;); text(5.5,sin(0.5*5.5),\u0026#39;sin(x/2)\u0026#39;); legend(\u0026#39;sin(x)\u0026#39;,\u0026#39;sin(2x)\u0026#39;,\u0026#39;sin(x/2)\u0026#39;); grid on 利用子图函数在不同区域绘出不同图形。 x=linspace(0,2*pi,100); subplot(2,2,1); plot(x,sin(x)); title(\u0026#39;sin(x)\u0026#39;); axis([0,2*pi,-1,1]); subplot(2,1,2); plot(x,cos(x)); title(\u0026#39;cos(x)\u0026#39;); axis([0,2*pi,-1,1]); subplot(4,4,3); plot(x,tan(x)); title(\u0026#39;tan(x)\u0026#39;); subplot(4,4,8); plot(x,cot(x)); title(\u0026#39;cot(x)\u0026#39;); axis([0,2*pi,-35,35]); 4.3 其他形式的二维曲线 其他坐标系下的二维曲线图 对数坐标图\nsemilogx 函数:调用形式与plot函数类似,semilogx(x,y,选项)为其中一种调用格式,其他的可参考plot函数,此函数绘图采用半对数坐标,x轴采用常用对数刻度,y轴为线性刻度。 semilogy 函数:调用形式与plot函数类似,semilogy(x,y,选项)为其中一种调用格式,其他的可参考plot函数,此函数绘图采用半对数坐标,y轴采用常用对数刻度,x轴为线性刻度。 loglog 函数:调用函数与上述类似,x和y都为常用对数刻度。 极坐标图\n基本调用格式:polar(theta,rho,选项) theta为极角,rho 为极径,选项与plot函数类似。 统计图 条形类图形\n条形图\nbar 函数:绘制二维垂直条形图\n调用格式为bar(y,style) :y如果为向量,则以每个元素值作为每一个柱的高度,元素下标代表横坐标。如果y为矩阵,则以每一行作为一组,以行号作为组号绘图。后方的 style 有 \u0026quot;grouped\u0026quot; 和\u0026quot;stacked\u0026quot; 两种模式,分别为簇状分组和堆积分组。默认为簇状分组。 调用格式为bar(x,y,style) :其中x存储横坐标,y为矩阵,存储每一个横坐标对应的数据,y的行数必须与x的长度相对应。 barh 函数:绘制二维水平条形图。调用格式与bar函数相同。\n直方图\nhist 函数:绘制直角坐标系下的直方图。\n调用格式为 hist(y) ,y为向量,绘图时将 $[miny,maxy]$ 区间等分成十组,并求出每个区间内对应元素的个数,然后绘出直方图。 调用格式为hist(y,x),如果x为标量,则将y区间分成x个区间,如果x为向量,则向量中的每一个数指定分组的中心值,元素的个数为指定分成的组数,x缺省默认均分十组。 rose 函数:用于绘制极坐标系下的直方图。\n调用格式为 rose(theta,x) 其中参数 theta 用于确定每一数据与圆点的角度,如果x为标量,则x代表均分组数,缺省默认为20。 面积类图形\n扇形图/饼图 pie 函数:调用格式为 pie(x,explode) 其中参数x为待统计的数据,通常为向量,其中每一个数据在整体中占用的比例在扇形图中表示出来,后续的 explode 为每个x对应的分离参数,如果非0,则将其分离出来。explode 缺省则饼图为一个整体。 面积图 area 函数:与plot函数类似,下方与坐标轴围成的区域进行填充。 散点类图形\n散点图 scatter 函数:scatter(x,y,选项,'filled') ,其中x和y通常为同等大小向量,代表了一定数量的点。选项与plot函数类似,用于限制颜色,线型,以及数据点标记,如果采用数据点标记,则可以用 \u0026lsquo;filled\u0026rsquo; 参数来填充数据点,如果缺省,则标记数据点为空心。 阶梯图 stairs 函数:使用方法与上述 scatter 函数类似。 杆图 stem 函数: 使用方法与上述 scatter 函数类似。 矢量类图形\n箭头图\nquiver 函数:常用此绘制磁力线,矢量。调用格式为quiver(x,y,u,v) , 其中 (x,y) 为矢量起点,(u,v) 为矢量终点,如果x,y省略,则均匀取若干个点作为起点。 罗盘图\ncompasser函数:与 plot 函数类似。 羽毛图\nfeather 函数:与 plot 函数类似。 例程 某次考试成绩优秀,良好,中等,及格,不及格人数分别为:7、13,23,9,4,用扇形统计图作成绩统计。 score = [7,13,23,9,4]; tag = [0,0,0,0,1]; pie(score,tag); legend(\u0026#34;Excellent\u0026#34;,\u0026#34;Good\u0026#34;,\u0026#34;Middle\u0026#34;,\u0026#34;Qualified\u0026#34;,\u0026#34;Bad\u0026#34;,\u0026#39;Location\u0026#39;,\u0026#39;eastoutside\u0026#39;); %上方legend中的location是用于指定图例出现位置的,如果不指定,会与统计图重合 不加location参数\n加入location参数\n4.4 三维曲线 plot3函数:绘制三维曲线最常用的函数。 基本用法:plot3(x,y,z) 其中三个参数分别为坐标对,一般为等长向量,plot3函数用直线将所有点连起来。\n变化形式:\n当plot(x,y,z) 当x,y,z为同型矩阵,则绘制多条曲线,曲线条数等于矩阵列数。\n当x,y,z中有向量也有矩阵的时候,向量的长度应与矩阵相符,如果是行向量,那么行向量的长度应与矩阵列数相同,如果是列向量,那么列向量的长度应与矩阵行数相同。\n也可以用多组向量对来绘制多组曲线,plot(x1,y1,z1,x2,y2,z2···,xn,yn,zn) ;\n含选项的plot3函数:plot(x,y,z,选项) 选项与功能与plot函数类似。\nfplot3函数 基本用法:与fplot函数类似 4.5 三维曲面 生成平面网格数据 meshgrid 函数:调用格式 [X,Y]=meshgrid(x,y) ,其中x,y为向量,X,Y为存储网格坐标系横纵坐标的矩阵。如果只填一个 x ,那么就相当于 x=y 。 绘制三维曲面的函数 mesh 函数 \u0026amp; surf 函数\n基本调用格式:mesh(x,y,z,c) \u0026amp; surf(x,y,z,c),两者可以用来绘制三维曲面,其中x,y为网格坐标矩阵,z 是网格点上的高度矩阵,c 用于指定在不同高度下的曲面颜色。如果 c 缺省,则默认 c=z ,也就是说颜色正比于高度。\n其他调用格式: mesh(z,c) \u0026amp; surf(z,c) 这样的话就用z矩阵的列,行坐标代表x,y的值,z的值代表高度,c的意义与上面相同。\n其他花里胡哨的 :\n带等高线的三维网格曲面函数 meshc 和 带底座的三维网格曲面函数meshz ,用法与 mesh 函数相同。前者带等高线,后者带底座(就是说下面是实体的)。 带等高线的曲面函数 surfc 和具有光照效果的曲面函数 surfl 。 标准三维曲面 sphere 函数:生成三维球面对应坐标。格式[x,y,z]=sphere(n) ,这将产生x,y,z三个(n+1)阶的方阵,通过这三个方针结合绘制三维曲面的函数 (surf或者mesh),可以绘制出圆心在圆点,半径为一的单位球面。如果不加输出参数x,y,z,则直接绘制球面。n的值代表圆滑程度,默认为20. cylinder 函数:生成三维柱面对应坐标。格式为 [x,y,z]=cylinder(R,n) R为一个向量,存放柱面各个等间隔高度上的半径,n表示圆柱圆周上的间隔点个数,默认为20。如果R为标量,则生成一个柱面。 fsurf和fmesh函数 用于绘制参数方程表示的函数,并且有两个变参。调用格式为 fsurf(funx,funy,funz,uvlims),其中前三个通常为函数句柄形式给出的函数,uvlims 表示前三个函数自变量取值范围,用四元向量组来进行描述,形如[umin,umax,vmin,vmax],默认值为[-5,5,-5,5] 。\n例程 绘制螺旋曲面。 funx = @(u,v) u.*sin(v); funy = @(u,v) -u.*cos(v); funz = @(u,v) v; fsurf(funx,funy,funz,[-5 5 -5 -2]) hold on fmesh(funx,funy,funz,[-5 5 -2 2]) hold off 绘制函数$z=(x-1)^2+(y-2)^2-1$ 的曲面图,分别用带等高线的mesh函数,带底座的mesh函数,带等高线的surf函数,带光照效果的surf函数绘制。$x\\in[0,2],y\\in[1,3]$ [x,y]=meshgrid(0:0.1:2,1:0.1:3); z=(x-1).^2+(y-2).^2-1; subplot(2,2,1); meshc(x,y,z);title(\u0026#39;meshc(x,y,z)\u0026#39;) subplot(2,2,2); meshz(x,y,z);title(\u0026#39;meshz(x,y,z)\u0026#39;) subplot(2,2,3); surfc(x,y,z);title(\u0026#39;surfc(x,y,z)\u0026#39;) subplot(2,2,4); surfl(x,y,z); title(\u0026#39;surfl(x,y,z)\u0026#39;) ","permalink":"https://blog.zzsqwq.cn/posts/51/","summary":"\u003ch2 id=\"41-二维曲线\"\u003e4.1 二维曲线\u003c/h2\u003e\n\u003ch3 id=\"span-idjumpplot函数span\"\u003e\u003cspan id=\"jump\"\u003eplot函数\u003c/span\u003e\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e基本用法\u003c/strong\u003e:\u003ccode\u003eplot(x,y)\u003c/code\u003e ,x和y分别代表横纵坐标,plot函数会将各个点连接起来,形成线,x和y一般为长度相等的向量。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e最简单的调用格式\u003c/strong\u003e:\u003ccode\u003eplot(x)\u003c/code\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e当x为实向量时\u003c/strong\u003e,则以该元素下表为横坐标,元素的值为纵坐标绘制曲线。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e当x为复向量时\u003c/strong\u003e,则以\u003cstrong\u003e实部\u003c/strong\u003e和\u003cstrong\u003e虚部\u003c/strong\u003e分别为横纵坐标绘制曲线。\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e","title":"专题四:MATLAB绘图"},{"content":"3.1 顺序结构程序 程序设计的基本步骤 程序 在matlab中程序文件扩展名为**.m** ,因此程序文件又叫 M文件。 程序文件分两种 脚本文件:是可以在命令行窗口直接执行的文件,也叫命令文件。 函数文件:定义一个函数,以函数调用方式来调用,不能单独执行。 文件的建立 可以在主页点击新建脚本,即可创建脚本文件,并且打开MATLAB编辑器。 在命令行窗口写 edit test 即可在当前文件下创建 test 脚本文件。 %利用脚本文件求两矩阵乘积 %脚本文件f1.m A=[1:3;4:6]; B=[1,2;3,4;5,6]; C=A*B; %在命令行窗口运行脚本文件 \u0026gt;\u0026gt; f1 C = 22 28 49 64 %利用函数文件求两矩阵乘积 %函数文件f1.m function C=f2(A,B) C=A*B; end \u0026gt;\u0026gt; C=f1(A,B) C = 22 28 49 64 顺序结构 数据的输入 : A=input(提示信息,参数选项) ,输入时会将提示信息打印出来,后面的参数选项用于限定输入数据的类型等。 数据的输出: disp(输出项) 程序的暂停: pause(延迟秒数) ,如果延迟秒数省略,那么就会一直暂停直到用户下次动作。如果程序运行中要强行暂停可以通过 Ctrl+C 实现。 例程 通过脚本文件和函数文件求一个向量的四舍五入向量。 脚本 A=[1.2,3.4,4.7,0.5]; B=round(A); disp(B) 函数 function B=f2(A) B=round(A); end 求两点之间距离以及黄金分割点坐标(其中点坐标通过复数形式输入)。 a=input(\u0026#39;a=\u0026#39;); b=input(\u0026#39;b=\u0026#39;); c=a+0.618*(b-a); s=abs(b-a); disp(s) disp(c) 3.2 用if语句实现选择结构 单分支if语句 如果成立执行语句组,如果不成立则跳出if,语句格式如下:\nif 条件(关系运算或逻辑运算) 语句组 end 双分支if语句 如果成立执行语句组1,不成立执行语句组2,然后跳出if,语句格式如下:\nif 条件(关系运算或逻辑运算) 语句组1 else 语句组2 end 多分支if语句 根据上述双分支的类推,依次判断条件1~n,成立则执行对应语句组,然后跳出if,不成立则往下寻找,语句格式如下:\nif 条件1 语句组1 elseif 条件2 语句组2 elseif 条件3 语句组3 ··· elseif 条件n-1 语句组n-1 else 语句组n end 条件成立的判断 当条件结果为标量,非零表示真,零表示假。 当条件为矩阵,如果矩阵非空且不包含零元素,则条件成立,否则不成立。 3.3 用switch语句实现选择结构 switch语句的基本格式 表示在C++里面就不喜欢用switch,感觉太麻烦了。这个和多分支if有点像吧,只是他的区别在于首先给出一个表达式,在下方每一个语句组对应着一个结果表,如果结果表对应着表达式的值,就执行当前语句组,执行完之后跳出switch语句,这个和C++的有所区别。此外,如果都不满足的话,我们还可以加入一个条件otherwise,顾名思义,如果上述结果都不满足,就执行这个otherwise下对应的语句,switch的语句格式如下:\nswitch 表达式 case 结果表1 语句组1 case 结果表2 语句组2 ··· case 结果表n 语句组n otherwise 语句组k end switch的使用规则 case结果表为switch表达式的取值,当取值有多个时,我们可以用单元数据表示。将这多个结果用大括号{}括起来,如果表达式值满足其中一个,就执行相应语句组。 用for语句实现循环结构 常用的for语句 % for语句格式: for 循环变量=表达式1:表达式2:表达式3 循环体语句 end 我们可以发现循环变量后面对应的是一个冒号表达式,分别是起始,步长,终止。 循环执行时,先求出冒号表达式对应的行向量,然后依次遍历行向量中的每一个元素,执行循环体语句。 for语句针对向量每一个元素执行一次循环体,有几个元素执行几次,当冒号表达式对应的向量为空向量,则一次也不执行。 当退出循环后,循环变量值为行向量组中的最后一个元素。 更一般的for语句 for 循环变量=矩阵表达式 循环体语句 end 更一般的for语句循环遍历后对应的是矩阵表达式,执行过程中将矩阵的各列元素,赋值给循环变量,这时候,循环变量为一个列向量,而不是上述常用for语句中的标量,可以发现,常用的for语句是一般格式下的特例。循环的次数为矩阵的列数。 例程 计算圆周率 $\\pi$\n利用循环求无穷级数展开求 $\\pi$ $$ 1-\\frac{1}{3}+\\frac{1}{5}-\\frac{1}{7}+\\cdots+(-1)^{n+1}\\frac{1}{2n-1} =\\frac{\\pi}{4} $$\ny=0; g=-1; n=input(\u0026#39;n=\u0026#39;); for i=1:n g=-g; y=y+g*1/(2*i-1); end disp(4*y) 利用矩阵求和求无穷级数展开求 $\\pi$ n=input(\u0026#39;n=\u0026#39;); x=1:2:(2*n-1); y=(-1).^(2:n+1)./x; disp(sum(y)*4) 3.5 用while语句实现循环结构 while语句 通过一个条件来判定是否执行循环体语句,当条件成立时,成立。不像是for循环先去设定循环多少次,循环变量依次取什么值,这个是根据条件限定,又叫条件循环语句。\nwhile 条件 循环体语句 end break语句和continue语句 break语句:当循环执行到break语句会跳出当前循环,进行循环外的语句。 continue语句:当循环执行到continue语句,会结束本次循环,进行下一次判断是否继续循环体。 循环嵌套 如果一个循环结构循环体又包括循环结构,那么就称为循环嵌套or多重循环结构。通过嵌套的层数不同来不同的命名,例如二重循环,三重循环等等。\n例程 从键盘输入若干数,当输入0时结束输入,求这些数的和和他们的平均值\nmsum=0; cnt=0; x=input(\u0026#39;Enter your numbers: \u0026#39;); while x~=0 msum=msum+x; cnt=cnt+1; x=input(\u0026#39;Enter your numbers: \u0026#39;); end if cnt\u0026gt;0 disp(msum); disp(msum/cnt); end 用筛法求 1~m 范围内的素数。\nm=input(\u0026#39;m=\u0026#39;); p=1:m; p(1)=0; for i=2:sqrt(m) for j=2*i:i:m p(j)=0; end end n=find(p~=0); p(n) 3.6 函数文件的定义与调用 函数文件的基本结构 function 输出参数表=函数名(输入形参表) 注释说明部分 函数体语句 end 当有多个形参时,形参之间用 , 逗号分隔,组成形参表。当输出形参多于一个,用方括号 [] 括起来,形成输出矩阵。 函数使用中的一些规定 函数文件名通常由 函数名再加上拓展名.m 组成,函数文件名与函数名也可以不同,当两者不同时,MATLAB默认忽视函数名,调用时使用函数文件名。但一般我们将函数名和函数文件名进行统一\n如果函数文件中有 return 语句,就结束函数的执行,返回栈底。\n函数调用 [输出实参表]=函数名(输入实参表) 匿名函数 MATLAB提供了一种特殊的函数,函数句柄变量相当于这个函数的别名,通过函数句柄可以间接的调用函数,多个参数之间用逗号分隔。\n函数定义的基本格式如下:\n函数句柄变量 = @(匿名函数输入参数) 匿名函数表达式 函数调用的基本格式如下:\n函数句柄变量(匿名函数输入实参) 特殊的,我们可以将一个已知的内部函数或者自定义函数,赋值给一个函数句柄变量,这样我们就可以通过函数句柄变量变量来简洁的调用函数。(类似于改个名字)\n例程 通过函数文件和匿名函数两个形式,求出 $x^2+y^2$ 的值。\n函数文件 function z=f2(x,y) z=x^2+y^2; end 匿名函数 f=@(x,y) x^2+y^2 3.7 函数的递归调用 函数的递归调用 如果一个函数在函数体内部调用自己本身称为递归调用(如果是其他函数称为嵌套调用)。递归是把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。\n直接递归调用:在一个函数体内部直接调用自己本身。 简介递归调用:在一个函数体内不嵌套调用其他函数,其他函数又调用自己。 例程 求 $n!=1\\times2\\times3\\cdots \\times n$ function f=fact(n) if n\u0026lt;=1 f=1; else f=fact(n-1)*n; end 3.8 函数参数与变量的作用域 函数参数的可调性 可调性顾名思义,就是可以调节的。MATLAB函数在调用过程中函数传递参数的数目是可以调节的。在调用时,函数有两个预定义变量,nargin 和 nargout ,前者记录调用函数时输入实参的个数,后者记录调用函数时输出实参的个数。通过这两个变量,可以针对不同的变量个数进行不同的处理。\n全局变量和局部变量 函数中定义的变量是局部变量,不能被其他函数引用 我们可以通过 global 变量名 来定义一个全局变量,如果不加 global ,默认是局部变量。 全局变量的作用域是整个MATLAB工作空间,全程有效,所有函数都可以对他进行存取和修改。 但是要注意的是,这里的全局变量使用方式和C++的有所区别,如果你要在函数中调用工作区中的全局变量,那么你需要在函数体内部定义相同的全局变量,这样才可以对其进行引用,函数体内部和工作区中的变量值是共享的。 例程 求 $x1\\times x+y1\\times y$ ,其中x1 和 y1 是全局工作区中全局变量的值。 %函数文件 function f=solve(x,y) global x1 y1 f=x1*x+y1*y %工作区 global x1 y1; x1=1; y1=2; s=solve(1,2) ","permalink":"https://blog.zzsqwq.cn/posts/36/","summary":"\u003ch2 id=\"31-顺序结构程序\"\u003e3.1 顺序结构程序\u003c/h2\u003e\n\u003ch3 id=\"程序设计的基本步骤\"\u003e程序设计的基本步骤\u003c/h3\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"https://blog.zzsqwq.cn/usr/uploads/2020/08/2521586228.png\" alt=\"step.png\" /\u003e\n\u003c/p\u003e","title":"专题三:MATLAB程序流程控制"},{"content":"2.1 特殊矩阵 通用的特殊矩阵 zeros函数: 产生全0矩阵,即零矩阵。\nones函数: 产生全1函数,即幺矩阵。\neye函数: 产生对角线为1的矩阵,当矩阵为方针时,为单位矩阵。\nrand函数: 产生 (0,1) 区间均匀分布的随机矩阵。\n通过 fix(a+(b-a+1)*rand(x)) 可产生[a,b]区间上均匀分布的随机整数。\nrandn函数: n为normal的意思,产生均值为0,方差为1的标准正态分布随机矩阵。\n通过 $\\mu+\\sigma x$ 来得到均值为 $\\mu$ ,方差为 $\\sigma{^2}$ 的随机数据。(高中数学知识,证明可百度) 对于上述函数的调用格式,我们都有如下规定,zeros(m)为产生 $m\\times m$ 的零矩阵,zeros(m,n)为产生类型为 $m\\times n$ 的零矩阵, zeros(size(A)) 为产生和 A 同类型的零矩阵,其余函数和此类似。 用于专门学科的特殊矩阵 魔方/幻方矩阵 (Magic Square)\nn阶幻方矩阵每行,每列,主副对角线的和相等。 n阶幻方矩阵每行每列的元素之和为 $(1+2+3+\\cdots+n^2)/n=(n+n^3)/2$ 范德蒙矩阵 (Vandermonde)\n利用 Vander(V) 生成以向量 V 为基础的**范德蒙(Vandermonde)**矩阵。 A=vander(1:5) A = 1 1 1 1 1 16 8 4 2 1 81 27 9 3 1 256 64 16 4 1 625 125 25 5 1 希尔伯特矩阵 (Hilbert)\n利用 hilb(n) 可以生成n阶希尔伯特矩阵。 伴随矩阵\n通过 compan(p) 可以生成向量p对应的多项式的伴随矩阵。p向量中高次系数在前,低次系数在后。(我感觉我学过伴随矩阵,但看了之后又感觉没学过QAQ) 帕斯卡矩阵\n通过 pascal(n) 生成一个n阶帕斯卡矩阵。 2.2 矩阵变换 对角阵 对角矩阵:只有对角线上有非0元素的矩阵是对角矩阵。如果对角线上元素相等,则称为数量矩阵。当对角线上元素相等且为1,称为单位矩阵。 提取矩阵的对角线元素 diag(A): 提取矩阵A主对角线元素,产生一个列向量。 diag(A,k): 提取矩阵A第k条对角线元素,产生一个列向量。主对角线为第0条,往上依次为1,2···n,往下依次为-1,-2 ··· -n。 构造对角矩阵 diag(V): 以向量V为主对角线元素,产生对角矩阵。 diag(V,k): 以向量V为第k条对角线元素,产生对角矩阵。 三角阵 矩阵对角线以上元素全为0为上三角矩阵,以下全为0为下三角矩阵。 上,下三角矩阵 (上 up,下 low),关于下三角的只需要把 triu 换为 tril triu(A): 提取矩阵A的主对角线及以上的元素。 triu(A,k): 提取矩阵A的第k条对角线及以上的元素。 矩阵的转置 普通转置运算符为 .' ,共轭转置为 ' ,它在转置的基础上还会求每个数的复共轭。 矩阵的旋转 rot90(A,k): 将矩阵A逆时针方向旋转 $90^{\\circ}$ 的k倍,当k为1时可以省略。 矩阵的翻转 fliplr(A): 对矩阵A实施左右翻转。 flipud(A): 对矩阵A进行上下反转。 矩阵的求逆 inv(A): 求A的逆阵。 矩阵的阶梯状 rref(A): 将矩阵A化为阶梯状(具体不再解释,不懂可百度) 2.3 矩阵求值 方阵的行列式 通过 det(A) 可以求A矩阵的行列式值。 矩阵的秩 通过 rank(A) 可以求A矩阵的秩。 矩阵的迹 矩阵的迹等于对角线元素之和,也等于特征值之和。通过 trace(A) 可以求A矩阵的迹。 向量和矩阵的范数 范数用来度量矩阵或向量在某种意义下的长度。\n向量的范数\n向量 1-范数 : 为向量元素的绝对值之和。通过 norm(V,1)计算V的1-范数 $$ ||V||{_1}=\\sum\\limits^n_{i=1}|v_i| $$\n向量 2-范数 : 为向量元素绝对值的平方和的平方根。通过norm(V)或者norm(V,2)计算向量V的2-范数 $$ ||V||_2=\\sqrt{\\sum\\limits^n_{i=1}|v_i|^2} $$\n向量 ∞-范数 : 所有向量元素绝对值中的最大值。通过norm(V,inf)计算向量V的∞-范数 $$ ||V||_{\\infty}=\\mathop{max}\\limits_{0\u0026lt;=i\u0026lt;=n}{|v_i|} $$\n矩阵的范数**(对不起我实在不想写latex了,直接截图了)**\n矩阵的范数求法和向量的一样一样滴 矩阵的条件数 用于描述矩阵性能的数,等于矩阵的范数乘逆阵的范数,条件数约接近一,矩阵性能越好。 通过 cond(A,1) ,cond(A)或cond(A,2) ,cond(A,inf) 分别求矩阵A三种范数下的条件数。 2.4 矩阵的特征值与特征向量 求矩阵的特征值 E=eig(A) :求矩阵A的全部特征值,构成向量E。 [X,D]=eig(A) :求矩阵A的全部特征值,构成对角阵D,并产生矩阵X,X各列为相应特征值对应的特征向量。 特征值的几何意义 这里没太听懂,回头来补,咕咕咕QAQ。\n2.5 稀疏矩阵 稀疏矩阵就是零元素个数远远大于非0元素个数的矩阵。\n矩阵的存储方式 完全存储方式:把所以元素按列依次存储 稀疏存储方式:只存储非0元素的行列下标和数值,不改变存储顺序,依次按列存储。 稀疏存储方式的产生 完全存储方式与稀疏存储方式的转化\n通过 A=sparse(S) 可以将矩阵S转化为稀疏存储方式的矩阵A 通过 S=full(A) 可以将矩阵A转化为完全存储方式的矩阵S。 直接建立稀疏存储矩阵\nsparse(m,n) 可以建立一个 $m\\times n$ 的所有元素都为0的稀疏矩阵。\nsparse(u,v,S) 其中u,v,S为3个等长向量,分别表示行下标,列下标,非零元素。\nB=spconvert(A) ,A是一个 $m\\times 3$ 或 $m\\times4$ 的矩阵,每一行元素依次表示一个稀疏矩阵的非零元素,从1~4列分别为,行下标,列下标,元素实部,元素虚部,若元素为实数,则第四列省略。\n单位矩阵的稀疏存储\nspeye(m,n) 可返回一个 $m\\times n$ 的稀疏存储单位矩阵。 ","permalink":"https://blog.zzsqwq.cn/posts/34/","summary":"\u003ch2 id=\"21-特殊矩阵\"\u003e2.1 特殊矩阵\u003c/h2\u003e\n\u003ch3 id=\"通用的特殊矩阵\"\u003e通用的特殊矩阵\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003ezeros函数\u003c/strong\u003e: 产生全0矩阵,即零矩阵。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eones函数\u003c/strong\u003e: 产生全1函数,即幺矩阵。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eeye函数\u003c/strong\u003e: 产生对角线为1的矩阵,当矩阵为方针时,为单位矩阵。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003erand函数\u003c/strong\u003e: 产生 \u003cstrong\u003e(0,1)\u003c/strong\u003e 区间均匀分布的随机矩阵。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e通过 \u003ccode\u003efix(a+(b-a+1)*rand(x))\u003c/code\u003e 可产生[a,b]区间上均匀分布的随机整数。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003erandn函数\u003c/strong\u003e: n为normal的意思,产生均值为0,方差为1的标准正态分布随机矩阵。\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e通过 $\\mu+\\sigma x$ 来得到均值为 $\\mu$ ,方差为 $\\sigma{^2}$ 的随机数据。\u003cstrong\u003e(高中数学知识,证明可百度)\u003c/strong\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e","title":"专题二:MATLAB矩阵处理"},{"content":"1.1 MATLAB系统环境 MATLAB操作界面的组成 MATLAB主窗口 命令行窗口 命令行窗口含有 \u0026gt;\u0026gt; 命令提示符,表示MATLAB处于准备状态,可以接受并执行命令,按下回车键后MATLAB会执行输入命令,并在后面显示执行结果 如果指令过长可以分行输入,在一行末尾写 ... 并按下回车键,在下个命令行继续输入,...称为续行符。 当前文件夹窗口 在MATLAB编程过程中生成的文件自动存放在当前文件夹,我们可以通过cd命令(例如我们要进入E盘下的work文件夹,可以cd e:\\work)或者选择文件工具栏中的文件夹来设置当前文件夹。 工作区窗口 可用于变量的显示和操作,可显示你当前创建的变量。并且可对其保存,修改,删除。 MATLAB的搜索路径 检索命令对象的顺序如下 设置文件搜索路径 用path命令设置文件搜索路径。例如: path{path,`e:\\work`} 用对话框设置文件搜索路径。在MATLAB主窗口的主页中设置。 1.2 MATLAB数值数据 数值数据类型的分类 整型\n无符号整数:含有8,16,32,64四种 带符号整数:含有8,16,32,64四种 范围和C语言一样,通过类型(数据) 来进行强转。\n浮点型\n单精度:占四字节 双精度:占八字节,数值数据默认为双精度 通过single和double函数进行强转。\n复型\n复型数据包括实部和虚部两部分,都默认为浮点型,虚数单位用i或j来表示。\n通过read和imag函数来求复型数据的实部和虚部。\n字符型\n字符在内部作为数字存储,而不会采用浮点格式存储。 数值数据的输出格式 format命令的格式,使用方法 format 格式符,不带格式符的format会恢复默认格式。ps:format只影响数据的输出,不影响数据的存储和计算。 常用数学函数 函数的调用格式为: 函数名(函数自变量的值)\n函数自变量规定为矩阵变量,也可以为标量(为矩阵的特例)。 函数在运算时将函数逐项作用在每个元素上,最后运算出来是一个与自变量同类型矩阵。 常用函数的应用\n三角函数有两类,例如sin和sind两种,前面是弧度制,后面是角度制,其余cos等类似。 abs函数可以求实数的绝对值、复数的模、字符串的ASCII码值。 用于取整的函数有fix,floor,ceil,round。分别为靠0取整,向下取整,向上取整,四舍五入取整。 判断是否为素数的函数isprime,是素数返回1,不是返回0。 \u0026gt;\u0026gt; x=[1:100]; \u0026gt;\u0026gt; k=isprime(x); \u0026gt;\u0026gt; k1=find(k); \u0026gt;\u0026gt; p=x(k1) p = 1 至 16 列 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 17 至 25 列 59 61 67 71 73 79 83 89 97 1.3 变量及其操作 变量与赋值语句 变量本质是一个内存单元的抽象,变量名以字母开头,后接数字、字母或下划线,最多63个字符。 变量名区分字母大小写(case sensitive),标准函数名以及命令名必须用小写字母。 赋值语句有两种格式 变量 = 表达式 表达式的值赋值MATLAB预定义变量ans 如果赋值后不加分号,会显示变量的结果,如果加了分号,则不显示。 预定义变量 预定义变量是系统自身定义的变量\nans 是默认赋值变量,命令行表达式值默认赋值给 ans i 和 j 代表虚数单位 pi 表示圆周率 NaN 代表非数 变量的管理 变量的删除和修改 在工作区进行变量的删除和修改 通过 who 和 whose 命令来查看变量清单,前者只显示名称,后者显示各种信息 内存变量文件 用于保存MATLAB工作区变量的文件交内存变量文件,扩展名为.mat,也叫MAT文件,是一种二进制文件。 save命令:创建内存变量文件,load命令:载入内存变量文件 1.4 MATLAB矩阵的表示 矩阵的建立 直接输入法建立矩阵\n将矩阵的元素用中括号[] 括起来,按行输入元素,同一行元素用逗号或者空格分隔,用分号换行。\n利用已有矩阵建立更大矩阵\n个人感觉类似于分块矩阵,例子如下:\n\u0026gt;\u0026gt; A=[1,2,3;4,5,6;7,8,9]; \u0026gt;\u0026gt; B=[-1,-2,-3;-4,-5,-6;-7,-8,-9]; \u0026gt;\u0026gt; C=[A,B;B,A] C = 1 2 3 -1 -2 -3 4 5 6 -4 -5 -6 7 8 9 -7 -8 -9 -1 -2 -3 1 2 3 -4 -5 -6 4 5 6 -7 -8 -9 7 8 9 用两个实矩阵矩阵通过矩阵的运算可以建立复数矩阵,要确保两个矩阵同类型\n\u0026gt;\u0026gt; B=[1,2,3;4,5,6]; \u0026gt;\u0026gt; C=[7,8,9;1,2,3]; \u0026gt;\u0026gt; D=B+i*C D = 1.0000 + 7.0000i 2.0000 + 8.0000i 3.0000 + 9.0000i 4.0000 + 1.0000i 5.0000 + 2.0000i 6.0000 + 3.0000i 冒号表达式 通过冒号表达式可以产生行向量\n一般格式为e1:e2:e3 分别是初始值,步长,终止值。可以省略e2,省略时步长为默认为1。\n\u0026gt;\u0026gt; t=0:1:5 t= 0\t1\t2\t3\t4\t5 \u0026gt;\u0026gt; s=0:5 s 0\t1\t2\t3\t4\t5 通过linspace函数产生行向量\nlinspace(a,b,n) 代表首元素为a,末尾元素为b,产生n个元素,相应的,步长为(b-a)/(n-1)。当n可以省略,省略时默认n为100。\n\u0026gt;\u0026gt; x=linspace(0,pi,5) x= 0 0.7854 1.5708 2.3562 3.1416 结构矩阵和单元矩阵 结构矩阵\n类似于C语言的结构体,把很多个数据写成一个结构体,矩阵里的每个元素个元素都是结构体变量。给对应元素赋值格式为 结构体元素.成员名=表达式 。我们应该注意到,当一个结构体内没有我们赋值的成员,那么他会自动扩充矩阵来满足你的要求。\n我们可以通过 s=struct('name',{'next','what'},'sex',{'male','unknow'}) 来创建一个包含 name 和 sex 两个成员的结构体。\n单元矩阵\n矩阵里的每个元素的类型可以不同,通过直接输入法建立,所有元素用大括号{}而不是中括号[]\n1.5 矩阵元素的引用 矩阵元素的引用方式 通过下标来引用矩阵,例如A(3,2)表示A矩阵第三列第二个元素。如果我们引用的元素超出矩阵范围,那么会默认扩充矩阵至满足要求,拓展元素默认为0。 \u0026gt;\u0026gt; A=[1,2,3;4,5,6]; \u0026gt;\u0026gt; A(4,5)=10 A= 1\t2\t3\t0\t0 4\t5\t6\t0\t0 0\t0\t0\t0\t0 0\t0\t0\t0\t10 通过序号来引用,注意矩阵元素按列存储,依次存放第一列,第二列···最后一列。\n矩阵元素的序号和下标可以通过 sub2ind 和 ind2sub 两个函数完成相互转化\nsub2ind 函数:将矩阵中指定元素的行列下标转换成存储的序号,格式为D=sub2ind(S,I,J),三个参数依次为行数和列数组成的二维向量(可以通过size函数获取),转换矩阵元素的行下标,转换矩阵元素的列下标。如果I,J为矩阵的话,那么就说明要将对应的一个下标矩阵求对应序号。注意结合下例来进行理解,我们注意到A(1,1)的序号为1,A(2,1)的序号为2,那么就是给定下标矩阵的顺序来生产的这个序号矩阵,类型相同。 \u0026gt;\u0026gt; A=[1:3;4:6] A= 1\t2\t3 4\t5\t6 \u0026gt;\u0026gt; D=sub2ind(size(A),[1,2;2,2],[1,1;3,2]) D= 1\t2 6\t4 ind2sub 函数:将矩阵元素的序号转换成下标,格式为 [I,J]=ind2sub(S,D) ,S,D分别为行数和列数组成的二维向量(可以通过size函数获取),要获取下标的元素的序号(可以是一个向量,标志要获取多个元素的下标) ,那么前方的 I和J就是对应的行下标和列下标,类似于一个 sub2ind 函数的逆用。 \u0026gt;\u0026gt; [I,J]=ind2sub([3,3],[1,3,5]) I= 1\t3\t2 J= 1\t1\t2 利用冒号表达式获得子矩阵 我们可以用冒号表达式作为矩阵的行或列下标,也可以用单个:来当行或列下标,这代表取遍全部行或列。end运算符: 表示某一维的末尾元素下标。 A(i,:)\t表示第i行的全部元素 A(:,j)\t表示第j行的全部元素 A(i:i+m,j:j+m)\t表示第i~i+m行和j~j+m列全部元素 A(i:i+m,:)\t表示第i~i+m行全部元素 A(1:3;1:end) 这代表取1~3行和1~最后一列元素 利用空矩阵删除矩阵元素 空矩阵就是不含任何元素的矩阵,例如x=[] 就建立了一个空矩阵x。 \u0026gt;\u0026gt; C=[4,5,6;1,2,3] C = 4 5 6 1 2 3 \u0026gt;\u0026gt; C(:,1:2)=[] C = 6 3 改变矩阵的形状 通过reshape函数可以在矩阵元素个数不变的情况下改变矩阵形状,例如 reshape(A,m,n) 就是将A矩阵变成m行n列的矩阵,不改变矩阵元素的存储顺序,也就是依次按列存储,对应序号相同。 特殊的约定 通过指令A(:) 可以将所有元素堆叠成一个列向量,不改变存储顺序。 1.6 MATLAB基本运算 算数运算 基本算术运算:+(加),-(减),*(乘),/(右除),\\(左除),^(乘方)\nMATLAB的算数运算在矩阵意义下进行,单个数据运算是矩阵的特例。 加减运算 两矩阵同型,对应元素相加减。不同型,发生错误。 一个标量可以和矩阵进行运算,这时把标量对全体矩阵元素进行操作。 乘法运算 很明显必须满足矩阵乘的条件,也就是当A*B时必须满足A的行数等于B的列数,此时称A,B矩阵是可乘的,或称两矩阵维数和大小相容。不相容就会发生错误 除法运算 如果A是**非奇异矩阵(A的行列式不为0) **,则B/A等效于B*inv(A),A\\B等效为inv(A)*B。inv(A)是指A的逆阵 。 乘法运算 A矩阵的x次方可以表示成A^x ,要求A为方阵,x为标量。 点运算\n点运算符:在相应算术运算符前面加.,有点乘,点右除,点左除,点乘方。 点运算:两个同型矩阵对应元素进行相关运算。 \u0026gt;\u0026gt; A=[1,2;3,4]; \u0026gt;\u0026gt; A^2 ans = 7 10 15 22 \u0026gt;\u0026gt; A.^2 ans = 1 4 9 16 关系运算 关系运算符: \u0026lt; ,\u0026lt;=,\u0026gt;,\u0026gt;=,==(等于),~=(不等于) 两个比较量为标量,直接比较两个数大小,如果成立表达式值为1,否则为0。 如果两个矩阵是同型矩阵,对每两个对应元素进行比较,形成一个由0,1构成的同型矩阵。 如果一个是标量一个是矩阵,则用标量和每个矩阵元素比较,形成一个同型矩阵。 逻辑运算 逻辑运算符: \u0026amp;(与),|(或),~(非)。各自对应的运算法则和C语言类似,不再赘述。 标量,矩阵之间进行运算,对应规则和关系运算类似,不再赘述。 运算符的优先级 算术运算优先级最高,逻辑运算优先级最低,但是逻辑非运算是单目运算符,优先级比双目运算符高。\n1.7 字符串处理 字符串的表达 用单引号括起来的字符序列就是字符串,MATLAB把他当成一个行向量。若字符串中含有单引号,则单引号字符要用两个单引号表示。 可以建立多行字符串,建立字符矩阵**(注意每一行的字符串长度要相等)**。和数值矩阵无异。 字符串的操作 字符串的执行\n通过eval(s) 函数可以执行字符串 s 对应的命令行命令。 字串与数值之间的转换\nabs 和 double 函数都可以获取字符串矩阵对应的ASCII码矩阵。 char 函数可以把ASCII码矩阵转换成字符串矩阵。 字符串的比较\n关系运算符比较:两个等长字符串比较,两两对应字符比较,成立为1,不成立为0,得到是一个含0,1的行向量。 字符串比较函数比较 strcmp(s1,s2):比较s1和s2是否相等,返回值为一个标量,相等为0,不等为1。后缀加i表示比较时忽略大小写。 strncmp(s1,s2,n):比较s1和s2前n个字符是否相等,返回值为一个标量。相等为0,不等为1。后缀加i表示比较时忽略大小写。 字符串的查找和替换\nfindstr(s1,s2):返回短字符串在长字符串中的开始位置。如果出现多次,则返回一个行向量。 strrep(s1,s2,s3):将s1中所有子字符串s2替换为s3。 数值转换为字符\n通过 num2str 或 int2str 等函数可以将数字转换为字符 ","permalink":"https://blog.zzsqwq.cn/posts/33/","summary":"\u003ch2 id=\"11-matlab系统环境\"\u003e1.1 MATLAB系统环境\u003c/h2\u003e\n\u003ch3 id=\"matlab操作界面的组成\"\u003eMATLAB操作界面的组成\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e\u003cstrong\u003eMATLAB主窗口\u003c/strong\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e命令行窗口\u003c/strong\u003e\n\u003cul\u003e\n\u003cli\u003e命令行窗口含有 \u003ccode\u003e\u0026gt;\u0026gt;\u003c/code\u003e 命令提示符,表示MATLAB处于准备状态,可以接受并执行命令,按下回车键后MATLAB会执行输入命令,并在后面显示执行结果\u003c/li\u003e\n\u003cli\u003e如果指令过长可以分行输入,在一行末尾写 \u003ccode\u003e...\u003c/code\u003e 并按下回车键,在下个命令行继续输入,\u003ccode\u003e...\u003c/code\u003e称为续行符。\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e当前文件夹窗口\u003c/strong\u003e\n\u003cul\u003e\n\u003cli\u003e在MATLAB编程过程中生成的文件自动存放在当前文件夹,我们可以通过cd命令(例如我们要进入E盘下的work文件夹,可以\u003ccode\u003ecd e:\\work\u003c/code\u003e)或者选择文件工具栏中的文件夹来设置当前文件夹。\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e工作区窗口\u003c/strong\u003e\n\u003cul\u003e\n\u003cli\u003e可用于变量的显示和操作,可显示你当前创建的变量。并且可对其保存,修改,删除。\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ol\u003e","title":"专题一:MATLAB基础知识"},{"content":"前言 学OI的时候就做过树形dp的题,不过那时候全在划水。看了看题解还不太懂就直接照着题解写了,现在再回来看还是不会QAQ,所以就再看看然后自己写了一遍。\nA. 没有上司的舞会 题意 有 $N$ 个职员被邀请去参加公司的舞会,他们每个人对应着一个快乐指数 $h_i$ ,如果该职员来了就会为舞会增加$h_i$ 点快乐指数。这 $N$ 个职员之间有从属关系,也就是说他们的关系就像一棵以顶级上司为根的树,父结点就是子结点的直接上司。如果一个职员的直接上司来到了舞会,那么他本人就不会再来。问邀请哪些职员可获得最大的快乐指数,最大为多少。\n思路 职员之间的关系是以树的形式给出的,所以先用链式前向星来存储数。存的时候我们用vis数组记录一下如何那个人有上司,就将他标记一下,最终没有标记的就是没有上司的,也就是顶级上司,也就是我们的根节点root。 树形dp,顾名思义,在树上进行dp,通过递归dfs,先算出子树的状态,再通过递归的回溯来合并。那么我们考虑一下设计状态,很明显一个人的状态有来和不来,两个情况。所以我们设计状态 $dp[i][0/1]$ 来表示职员 i 来或者不来,我们用u来表示当前节点,用v来表示当前节点的子节点,那么状态转移如下:\n$dp[u][0]=max(dp[v][0],dp[v][1]) $ (上司u没有来,那么下属v可以来,也可以不来,选一个大的策略)\n$dp[u][1]=dp[v][0]+h[u]$ (上司u来了,下属v肯定不来)\n最终的答案就是 $max(dp[root][0],dp[root][1])$ ,上司来和不来两种策略中的最大一种。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=6005; int head[maxn]; struct edge { int next; int to; }e[maxn]; int cnt,n,l,k,vis[maxn],root; int r[maxn]; int dp[maxn][2]; void add(int l,int k) { e[++cnt].next=head[l]; e[cnt].to=k; head[l]=cnt; } void dfs(int u) { dp[u][0]=0; dp[u][1]=r[u]; for(int i=head[u];i;i=e[i].next) { int v=e[i].to; dfs(v); dp[u][1]+=dp[v][0]; dp[u][0]+=max(dp[v][1],dp[v][0]); } } int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) scanf(\u0026#34;%d\u0026#34;,\u0026amp;r[i]); for(int i=1;i\u0026lt;n;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;l,\u0026amp;k); add(k,l); vis[l]++; } scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;l,\u0026amp;k); for(int i=1;i\u0026lt;=n;i++) { if(!vis[i]) root=i; } dfs(root); printf(\u0026#34;%d\u0026#34;,max(dp[root][0],dp[root][1])); return 0; } B. 战略游戏 题意 小姜老师要建立一个树,树节点两两之间通过道路连接,他要在这些节点上放一些小人,每个小人可监管与该节点相连的道路,问最少放置多少小人可以监管所有道路。(数据保证0为根节点)\n思路 这个题跟上个题有点像,首先我们也是用链式前向星把树给存下来,不过这个题的输入跟上道题有点不一样,本质都是一样的。因为我们只需要dfs下去,然后向上回溯的时候合并,所以只需要存单向边即可。 对于一个节点我们也是有两种策略,选或者不选,那么我们也可以把状态写成 $dp[i][1/0]$ ,对应着 i 这个节点选或者不选,我们把当前节点看作u,子节点看作v,状态转移如下:\n$dp[u][1]+=\\Sigma (dp[v][0],dp[v][1]) +1$ (u选了,v选不选都可以,加上自身的1)\n$dp[u][0]+=\\Sigma dp[v][1]$ (如果u没有选,那么v一定要选,才能监管到u的道路)\n很显然这个答案是 $min(dp[0][0],dp[0][1])$\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=1505; struct edge { int next,to; }e[maxn]; int u,v; int head[maxn]; int dp[maxn][2]; int num; int n,cnt; void add(int u,int v) { e[++cnt].next=head[u]; e[cnt].to=v; head[u]=cnt; } void dfs(int u) { dp[u][1]=1; for(int i=head[u];i;i=e[i].next) { int v=e[i].to; dfs(v); dp[u][1]+=min(dp[v][1],dp[v][0]); dp[u][0]+=dp[v][1]; } } int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=0;i\u0026lt;n;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;u,\u0026amp;num); for(int i=1;i\u0026lt;=num;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;v); add(u,v); } } dfs(0); printf(\u0026#34;%d\u0026#34;,min(dp[0][0],dp[0][1])); return 0; } C. 二叉苹果树 题意 有一颗二叉苹果树,也就是说树枝如果分叉,一定是分二叉。苹果树有 $n$ 个节点,树根编号为 1 。每个树枝上都有一定数量的苹果,如果最终保留 $q$ 根树枝,问最多能够保留多少苹果。\n思路 这个树形dp要比上面的还要难一些,因为我们的状态不能够只考虑是否保留当前的树枝了,因为保留当前树枝也会有很多种关于保留子树枝选择。看了题解大佬的说法是,可以定义成 $f[u][j]$ 来表示 u 的子树上保留 j 条边时所能获得最大的苹果数。所以我们考虑一下转移方程,首先我们能保留的最大边数是当前子树所具有的所有树枝,对于一个节点下的两个树枝,我们可以选择取,或者不取,那么这就类似于一个背包问题,对于一定的容量(一定量的树枝),我们取几个树枝才能获得最大的价值。但是我们注意,对于一个节点u,我们如果要取他的节点v,那么我们u-v之间这个树枝一定要保留,不然会不能取得v,这是一个隐藏的条件。 因此转移方程: $dp[u][i]=max(dp[u][i],dp[u][i-j-1]+dp[v][j]+w[u][v] $ ,$w[u][v]$为当前u-v树枝的苹果数。代码里面因为我懒得计算子树的树枝数了,所以就直接从最大的q来枚举了,就没考虑那么多,可能复杂度稍微高一点,但是高不到哪去其实QAQ\u0026hellip;\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=105; struct edge { int next,to,w; }e[maxn]; int n,cnt,q; int u,v,w; int dp[maxn][maxn]; int head[maxn]; void add(int u,int v,int w) { e[++cnt].next=head[u]; e[cnt].to=v; e[cnt].w=w; head[u]=cnt; } void dfs(int u) { for(int i=head[u];i;i=e[i].next) { int v=e[i].to; dfs(v); for(int j=q;j\u0026gt;=0;j--) { for(int k=0;k\u0026lt;=j-1;k++) { dp[u][j]=max(dp[u][j],dp[u][j-1-k]+dp[v][k]+e[i].w); } } } } int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;q); for(int i=1;i\u0026lt;n;i++) { scanf(\u0026#34;%d%d%d\u0026#34;,\u0026amp;u,\u0026amp;v,\u0026amp;w); add(u,v,w); } dfs(1); printf(\u0026#34;%d\u0026#34;,dp[1][q]); return 0; } ","permalink":"https://blog.zzsqwq.cn/posts/31/","summary":"\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003e学OI的时候就做过树形dp的题,不过那时候全在划水。看了看题解还不太懂就直接照着题解写了,现在再回来看还是不会QAQ,所以就再看看然后自己写了一遍。\u003c/p\u003e","title":"树形dp例题"},{"content":"A. Two Rabbits 题意 两个兔子分别位于 $(x,0)$ 和 $(y,0)$ ,两个人对头蹦,前者往前蹦 $a$ ,后者往前蹦 $b$ ,问两人是否能恰好相遇。\n思路 算一下两个人直接得距离 $s$ ,每次两者距离减少 $a+b$ ,看 $s$ 是否能被 $a+b$ 整除,如果可以就能够相遇。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; int t; int x,y,a,b; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { scanf(\u0026#34;%d%d%d%d\u0026#34;,\u0026amp;x,\u0026amp;y,\u0026amp;a,\u0026amp;b); int p=a+b; int f=y-x; if(f%p==0) { printf(\u0026#34;%d\\n\u0026#34;,f/p); } else printf(\u0026#34;-1\\n\u0026#34;); } return 0; } B. Longest Palindrome 题意 给出 $n$ 段长度为 $m$ 的字符串,从中挑选出一些组成最长的回文字串,输出这个回文子串的长度和内容,如果有多种情况输出一种即可。如果没有符合的,就输出0 。$(1\\le n\\le 100,1\\le m\\le 50)$\n思路 因为这个数据规模非常小,所以 $O(n^2m)$ 也是可以接受的(说实话我不是很会算,大概是个差不多的式子),那么我们可以选择暴力匹配,用每个字符串去匹配后面的,如果是两个互为回文串,那么就把其中任何一个计入到sub字符串中,然后用一个 vis 数组来标记他们两个已经被使用过了,最终一个字符串匹配完后面所有的发现没有合适的,那么就考虑他自己是不是一个回文串,如果是一个回文串,单独标记它是放在中间。最后我们的sub是存放了一半回文串。 统计答案的时候,先将sub加到答案ans中,检查一下是否中间有合适的回文串,如果有的话也加到ans里面,最后讲sub逆序一下,加到ans里面。最终输出答案的时候,看一下ans是不是空串,如果是空串,就输出0,否则输出长度和ans。(string是真的好用!!!)\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=105; int n,m; string ans,sub,mid; bool ifmid; string str[maxn]; bool vis[maxn]; int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;m); for(int i=1;i\u0026lt;=n;i++) cin\u0026gt;\u0026gt;str[i]; for(int i=1;i\u0026lt;=n;i++) { for(int j=i+1;j\u0026lt;=n;j++) { if(vis[j]) continue; bool flag=true; for(int k=0;k\u0026lt;m;k++) { if(str[i][k]==str[j][m-k-1]) { continue; } else { flag=false; break; } } if(flag) { vis[i]=vis[j]=true; sub+=str[i]; } } if(!vis[i]) { bool flag=true; for(int j=0;j\u0026lt;m;j++) { if(str[i][j]!=str[i][m-1-j]) { flag=false; break; } } if(flag) { mid=str[i]; ifmid=true; } } } ans+=sub; reverse(sub.begin(),sub.end()); if(ifmid) ans+=mid; ans+=sub; if(!ans.empty()) { cout\u0026lt;\u0026lt;ans.length()\u0026lt;\u0026lt;endl\u0026lt;\u0026lt;ans; } else cout\u0026lt;\u0026lt;0; return 0; } C. Air Conditioner 题意 餐厅老板有一个空调,餐厅初始温度为 $m$ ,会陆续来 $n$ 个顾客。餐厅老板每分钟可以控制空调的温度+1,-1,或者是不变。这 $n$ 个顾客会按来的时间顺序给出,每个人有一个感到舒适的温度范围,如果空调的温度在这个范围里面,那么顾客就会满意。问餐厅老板是否可以达到让每个人都满意。\n思路 首先我们先思考从餐厅开始到第一个客人来临的时候,假设第一个人来临的时间是 $t$ ,舒适区间为 $[l,r]$,那么我们可以很容易发现只要 $[l,r]$ 与 $[m-t,m+t]$ 有交集,那么就是可以满足第一个客人条件。如果第二个和第一人的时间差为 $\\Delta t$ ,那么这个时候要计算可达到的舒适区间就是在上次交集的区间上左右变化 $\\Delta t$ ,为什么是交集呢。我一开始想错了。。一直写成并集,然后一直调不出来。但实际上不是这样的,我们可以理解为只有交集那部分才是符合上个顾客要求的,如果超出那个范围,就不能够满足上个顾客要求。所以挨个顾客扫一遍就行了。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; int q,n,m; int last,l,h,t; int nowl,nowr,delt; int lef,righ; bool flag; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;q); while(q--) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;m); lef=righ=m; last=0; flag=true; for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d%d%d\u0026#34;,\u0026amp;t,\u0026amp;l,\u0026amp;h); delt=t-last; nowl=lef-delt; nowr=righ+delt; last=t; if(nowl\u0026gt;h||nowr\u0026lt;l) flag=false; else { lef=max(nowl,l); righ=min(nowr,h); } } if(flag) { printf(\u0026#34;YES\\n\u0026#34;); } else printf(\u0026#34;NO\\n\u0026#34;); } } ","permalink":"https://blog.zzsqwq.cn/posts/30/","summary":"\u003ch2 id=\"a-two-rabbitshttpscodeforcescomcontest1304problema\"\u003eA. \u003ca href=\"https://codeforces.com/contest/1304/problem/A\"\u003eTwo Rabbits\u003c/a\u003e\u003c/h2\u003e\n\u003ch3 id=\"题意\"\u003e题意\u003c/h3\u003e\n\u003cp\u003e两个兔子分别位于 $(x,0)$ 和 $(y,0)$ ,两个人对头蹦,前者往前蹦 $a$ ,后者往前蹦 $b$ ,问两人是否能恰好相遇。\u003c/p\u003e","title":"Codeforces#620 (Div.2)"},{"content":"A. 矩阵取数游戏 题意 给定一个 $n\\times m$ 的矩阵,其中每个元素为非负整数。每次你可以从每行的行首或行末取一个元素,得到的分数为当前元素的值 $a_{ij}\\times 2^k$ ,$k$ 为当前是第几次取该行上的元素。 问最大得分为多少。\n思路 首先我们发现,虽然答案问的是 $n$ 行,但是我们发现,不同行之间是不会相互影响的,我们只需要讨论一行的情况,然后对每行都处理一遍就可以了。 那么对于一行上的 $m$ 个元素,我们每一次取都有两种选择,一个是取行首,一个是取行尾。我们发现这是一个区间问题,对于区间 $[i,j]$ 的最优情况,我们可以从 $[i+1,j]$ 和 $[i,j-1]$ 这两个的最优情况转移过来,因此我们可以定义 $f[i][j]$ 是从第 $i$ 个元素到第 $j$ 的元素得分的最大值,然后从上述两个状态转移过来。 还有一个问题就是我们的 $2^k$ 问题,我们考虑到大区间的最优值是从小区间转移来,也就是说小区间乘的指数高,大区间乘的指数低,我们又是从小区间推到大区间,转移一次就乘一次,最后肯定是大区间的少,小区间的多了。qwq因为这个题的次数可能很高,会爆long long,实在是不想写高精度,就用了__int128,第一次用,感觉还不错QAQ..\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=85; int n,m; __int128 map[maxn][maxn]; __int128 dp[maxn][maxn],ans; void read(__int128 \u0026amp;x) { x=0; char ch; ch=getchar(); while(ch\u0026lt;\u0026#39;0\u0026#39;||ch\u0026lt;\u0026#39;0\u0026#39;) ch=getchar(); while(ch\u0026gt;=\u0026#39;0\u0026#39;\u0026amp;\u0026amp;ch\u0026lt;=\u0026#39;9\u0026#39;) { x=x*10+ch-\u0026#39;0\u0026#39;; ch=getchar(); } } void out(__int128 x) { if(x\u0026gt;=10) out(x/10); putchar(x%10+\u0026#39;0\u0026#39;); } int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;m); for(int i=1;i\u0026lt;=n;i++) { for(int j=1;j\u0026lt;=m;j++) read(map[i][j]); } for(int i=1;i\u0026lt;=n;i++) { for(int f=1;f\u0026lt;=m;f++) { for(int j=1;j\u0026lt;=m;j++) dp[f][j]=0; } for(int len=1;len\u0026lt;=m;len++) { for(int j=1;j+len-1\u0026lt;=m;j++) { int k=j+len-1; dp[j][k]=max(dp[j+1][k]*2+map[i][j]*2,dp[j][k-1]*2+map[i][k]*2); } } ans+=dp[1][m]; } out(ans); return 0; } B. 关路灯 题意 在一条街道上有 $n$ 个路灯开着,他们可以看作分布在 $x$ 轴上,每个路灯有一定的坐标,也就是代表他们的位置。每个路灯也有一定的功率 $x$ ,代表一秒钟消耗多少电能。姜大佬初始位置在 $c$ ,他每天早晨出来关掉路灯。它可以先关左边的也可以先关右边的,他的行走速率是 $1m/s$ ,问最少消耗多少电能能关掉所有路灯。\n思路 又是一道区间dp的题,那么我们可以思考一下,首先小姜老师肯定不能跳着关路灯,也就是说这个区间内中间的路灯都被关闭了,他会关一个区间的左端点或者右端点,而不会关这个区间外面的。那么我们就可以枚举区间长度来解决这个问题,从小的枚举到大的。 那么我们思考一下如何定义这个状态。我们可以定义关闭区间 $[i,j]$ 的路灯,最少消耗电能为 $f[i][j]$ ,如果需要转移状态的话,我们想到,对于一个方向,小姜老师可以继续往前走,关掉前面那盏灯,也可以返回去,关闭它屁股后面那盏灯。因为是有两个方向的,所以我们可以拓宽一维,用 $f[i][j][0/1]$ 来表示小姜老师现在是在往左走还是往右走,那么很明显 $f[i][j][0]$ 这个状态可以从 $f[i+1][j][0/1]$ 来转移分别对应着小姜老师继续往前走关眼前的,和返回关屁股后的。相应的 $f[i][j][1]$ 就可以从 $f[i][j-1][0/1]$ ,转移的时候再加上消耗的电能即可!\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=55; const int inf=100000000; int n,c; int lt[maxn]; //lantern pos int en[maxn]; //energy int sum[maxn]; //prefix sum int dp[maxn][maxn][2]; int calc(int i,int j) { return sum[n]-(sum[j]-sum[i-1]); } int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;c); for(int i=1;i\u0026lt;=n;i++) { for(int j=1;j\u0026lt;=n;j++) { for(int k=0;k\u0026lt;=1;k++) dp[i][j][k]=inf; } } for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;lt[i],\u0026amp;en[i]); sum[i]=en[i]+sum[i-1]; } dp[c][c][0]=dp[c][c][1]=0; for(int len=2;len\u0026lt;=n;len++) { for(int i=1;i+len-1\u0026lt;=n;i++) { int j=i+len-1; dp[i][j][0]=min(dp[i+1][j][0]+(lt[i+1]-lt[i])*calc(i+1,j),dp[i+1][j][1]+(lt[j]-lt[i])*calc(i+1,j)); dp[i][j][1]=min(dp[i][j-1][0]+(lt[j]-lt[i])*calc(i,j-1),dp[i][j-1][1]+(lt[j]-lt[j-1])*calc(i,j-1)); } } printf(\u0026#34;%d\u0026#34;,min(dp[1][n][0],dp[1][n][1])); return 0; } C. 小a和uim之大逃离 题意 给定一个 $n\\times m$ 的矩阵,每个格子中有 $0\\sim k$ 滴魔液,小姜老师和它朋友可以从任意地点开始,一起向右或者向下走,他们每个人有一个容量为 $k$ 的瓶子,由小姜老师开始轮流收集地上的魔液,当收集魔液大于 $k$ 的时候,会对 $k+1$ 取模,问他们有多少种方法使得收集的魔液数量相同。\n思路 很显然我们可以写一个5维dp,用 $f[i][j][p][l][0/1]$ 来表示,当到了坐标为 $(i,j)$ 的格子的时候,小姜老师拥有魔液 $p$ 滴,他的朋友拥有魔液 $l$ 滴,并且这一次是由小姜老师采集的/由他的朋友采集的。这样的话,感觉比较好些,但是。。空间占用非常的高,我们优化一下,因为问的是收集相等,所以只需要维护他们的差就可以了,也就是说,只需要将 $(p-l+k)\\%k$ 维护一下就可以了,因此循环枚举坐标以及他们的差,从低的向高的转移就可以了。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=805; int map[maxn][maxn]; int dp[maxn][maxn][16][2]; const int mod=1e9+7; int n,m,k; long long ans; int main() { //\tfreopen(\u0026#34;test.in\u0026#34;,\u0026#34;r\u0026#34;,stdin); scanf(\u0026#34;%d%d%d\u0026#34;,\u0026amp;n,\u0026amp;m,\u0026amp;k); k++; for(int i=1;i\u0026lt;=n;i++) { for(int j=1;j\u0026lt;=m;j++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;map[i][j]); dp[i][j][map[i][j]%k][0]=1; } } for(int i=1;i\u0026lt;=n;i++) { for(int j=1;j\u0026lt;=m;j++) { for(int t=1;t\u0026lt;=k;t++) { dp[i][j][t%k][0]+=dp[i-1][j][(t-map[i][j]+k)%k][1];dp[i][j][t%k][0]%=mod; dp[i][j][t%k][0]+=dp[i][j-1][(t-map[i][j]+k)%k][1];dp[i][j][t%k][0]%=mod; dp[i][j][t%k][1]+=dp[i-1][j][(t+map[i][j])%k][0];dp[i][j][t%k][1]%=mod; dp[i][j][t%k][1]+=dp[i][j-1][(t+map[i][j])%k][0];dp[i][j][t%k][1]%=mod; } } } for(int i=1;i\u0026lt;=n;i++) { for(int j=1;j\u0026lt;=m;j++) { ans+=dp[i][j][0][1]%mod; ans%=mod; } } printf(\u0026#34;%lld\u0026#34;,ans); } ","permalink":"https://blog.zzsqwq.cn/posts/29/","summary":"\u003ch2 id=\"a-矩阵取数游戏httpswwwluogucomcnproblemp1005\"\u003eA. \u003ca href=\"https://www.luogu.com.cn/problem/P1005\"\u003e矩阵取数游戏\u003c/a\u003e\u003c/h2\u003e\n\u003ch3 id=\"题意\"\u003e题意\u003c/h3\u003e\n\u003cp\u003e给定一个 $n\\times m$ 的矩阵,其中每个元素为非负整数。每次你可以从每行的行首或行末取一个元素,得到的分数为当前元素的值 $a_{ij}\\times 2^k$ ,$k$ 为当前是第几次取该行上的元素。 问最大得分为多少。\u003c/p\u003e","title":"dp练习"},{"content":"前言 STL之前只会用 stack 和 queue ,set 和 map 啥的也不太会用。学习一下。\n队列(queue) 概述 队列是一种特殊的线性表,是一种先进先出(FIFO)的数据结构。它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。\n用法 首先使用之前需要声明头文件 #include\u0026lt;queue\u0026gt; ,通过 queue\u0026lt;typename\u0026gt; q 的形式来进行定义队列,上述为定义了一个队列元素类型为 typename 的队列,队列名称为 q,typename可以为C++原有数据类型,例如int,char,string这些,也可以是自定义的结构体类型等。\n主要函数及用途 使用下述函数都是用类似于 队列名称.函数名() 的形式,好比pop函数就是 q.pop()\npush(x) 将元素x从队尾入队 front( ) \u0026amp; back( ) 分别为获取队首元素和队尾元素,使用的时候必须确保队列不为空 pop( ) 弹出队首元素,使用的时候必须确保队列不为空 empty( ) 判断队列是否为空,空返回true,不空返回false size( ) 查询队列中有多少个元素 应用实例 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;iostream\u0026gt; #include\u0026lt;queue\u0026gt; using namespace std; queue\u0026lt;int\u0026gt; q; int main() { q.push(1); if(!q.empty()) printf(\u0026#34;%d\\n\u0026#34;,q.front()); // q.push(2); if(!q.empty()) printf(\u0026#34;%d\\n\u0026#34;,q.back()); printf(\u0026#34;%d\\n\u0026#34;,q.size()); if(!q.empty()) q.pop(); if(q.empty()) printf(\u0026#34;queue is empty\\n\u0026#34;); else printf(\u0026#34;queue is not empty\\n\u0026#34;); if(!q.empty()) q.pop(); if(q.empty()) printf(\u0026#34;queue is empty\\n\u0026#34;); } /* 运行结果 1 2 2 queue is not empty queue is empty */ 栈(stack) 概述 与队列相对应,是一种先进后出(FILO)的数据结构,限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。\n用法 首先使用之前需要声明头文件 #include\u0026lt;stack\u0026gt; ,通过 stack\u0026lt;typename\u0026gt; s 的形式来进行定义栈,上述为定义了一个队列元素类型为 typename 的栈,栈名称为 s,typename可以为C++原有数据类型,例如int,char,string这些,也可以是自定义的结构体类型等。\n主要函数及用途 使用下述函数都是用类似于 栈名称.函数名() 的形式,好比pop函数就是 s.pop()\npush(x) 将元素x压栈 pop( ) 将栈顶元素出栈,使用时确保栈不为空 top( ) 获取栈顶元素的值,使用时要确保栈不为空 size( ) 返回栈中元素的个数 empty( ) 查询栈是否为空,空返回true,不空返回false 应用实例 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;iostream\u0026gt; #include\u0026lt;stack\u0026gt; using namespace std; stack\u0026lt;int\u0026gt; s; int main() { s.push(1); s.push(2); printf(\u0026#34;Now the top element is %d\\n\u0026#34;,s.top()); //Now the top element is 2 printf(\u0026#34;Now the stack size is %d\\n\u0026#34;,s.size()); //Now the stack size is 2 if(!s.empty()) s.pop(); //元素2 弹出栈 printf(\u0026#34;Now the top element is %d\\n\u0026#34;,s.top()); //Now the top element is 1 printf(\u0026#34;Now the stack size is %d\\n\u0026#34;,s.size()); //Now the stack size is 1 if(s.empty()) printf(\u0026#34;stack is empty\\n\u0026#34;); else printf(\u0026#34;stack is not empty\\n\u0026#34;); //stack is not empty if(!s.empty()) s.pop(); //元素1 弹出栈 if(s.empty()) printf(\u0026#34;stack is empty\\n\u0026#34;); //stack is empty else printf(\u0026#34;stack is not empty\\n\u0026#34;); } /* 运行结果 Now the top element is 2 Now the stack size is 2 Now the top element is 1 Now the stack size is 1 stack is not empty stack is empty */ 映射(map) 概述 map是STL的一个关联容器,提供一对一的数据处理能力,可以建立两个数据之间一一映射关系,map的定义需要关键字和存储值两个参数,我们可以通过关键字来查找对应的存储值(感觉类似于下标可以为任何类型的数组)吧,因为map的底层实现为红黑树(虽然我没学过),所以具有自动排序功能,也就是说map内部有序。\n用法 使用之前声明头文件 #include\u0026lt;map\u0026gt; ,通过 map\u0026lt;typename,typename\u0026gt; m 的形式来定义映射,如果我们要建立string和int这两个类型之间的一一映射,就可以写成 map\u0026lt;string,int\u0026gt; m ,我们可以通过关键字string来查找对应的int值。下述的讲述我们用这个m这个映射来进行。\n迭代器 迭代器就是类似于指针吧,我们可以通过map\u0026lt;string,int\u0026gt;::iterator it ,来定义一个对应映射的迭代器,他能够用来指向map中的元素,通过它们我们可以对map执行定点删除,遍历等操作。\n主要函数及用途 1. 插入数据 通过insert函数进行插入 m.insert(pair\u0026lt;string,int\u0026gt;(\u0026quot;zs\u0026quot;,1)) m.insert(make_pair(\u0026quot;zs\u0026quot;,2)) 通过类似于数组的形式插入 m[\u0026quot;zs\u0026quot;] = 2 上述两种形式有一定的区别,因为集合中元素是唯一的,用insert函数插入的时候,如果已经有相应的关键字,那么就不会插入。而如果用类似于数组的方式进行插入,就会覆盖原关键字对应的值。\nmap\u0026lt;string,int\u0026gt; m; int main() { m.insert(pair\u0026lt;string,int\u0026gt;(\u0026#34;zs\u0026#34;,1)); printf(\u0026#34;%d \u0026#34;,m[\u0026#34;zs\u0026#34;]); m.insert(make_pair(\u0026#34;zs\u0026#34;,2)); printf(\u0026#34;%d \u0026#34;,m[\u0026#34;zs\u0026#34;]); m[\u0026#34;zs\u0026#34;]=2; printf(\u0026#34;%d \u0026#34;,m[\u0026#34;zs\u0026#34;]); /* 输出结果 1 1 2 */ } 2. 查找数据 通过find函数来查找关键字在map中的位置,如果找到了的话就返回对应的迭代器,如果没有找到的话就返回尾部的迭代器(end函数返回的值)。\nmap\u0026lt;string,int\u0026gt; m; int main() { map\u0026lt;string,int\u0026gt;::iterator it; m[\u0026#34;zs\u0026#34;]=1; it=m.find(\u0026#34;zs\u0026#34;); cout\u0026lt;\u0026lt;it-\u0026gt;first\u0026lt;\u0026lt;\u0026#34; \u0026#34;\u0026lt;\u0026lt;it-\u0026gt;second; /* 输出结果 zs 1 */ } 3. 删除数据 清空map,可以使用clear函数。 删除特定元素 先用find函数找到特定元素的迭代器,通过erase函数清除。 直接通过相应关键字清除。 删除一串序列,通过erase(起始迭代器,终点迭代器) 来实现。 map\u0026lt;string,int\u0026gt; m; int main() { map\u0026lt;string,int\u0026gt;::iterator it; m[\u0026#34;zs\u0026#34;]=1; it=m.find(\u0026#34;zs\u0026#34;); m.erase(it); it=m.find(\u0026#34;zs\u0026#34;); if(it==m.end()) printf(\u0026#34;Not find zs\\n\u0026#34;); m[\u0026#34;zs\u0026#34;]=2; m.erase(\u0026#34;zs\u0026#34;); it=m.find(\u0026#34;zs\u0026#34;); if(it==m.end()) printf(\u0026#34;Not find zs\u0026#34;); /* 输出结果 Not find zs Not find zs */ } 4. 其他 count(\u0026ldquo;关键字\u0026rdquo;) 查询相应关键字在map中是否出现过,出现过返回1,没出现返回0 empty( ) 判断是否为空,空返回true,不空返回false begin( ) \u0026amp; end( ) 分别为返回头和尾迭代器,配合迭代器可实行遍历 iterator-\u0026gt;first \u0026amp; iterator-\u0026gt;second 分别对应相应迭代器指向的元素的关键字和值 集合(set) 概述 set为一个容器,用来存储同一数据类型的数据,并且能从一个数据集合中取出数据,在set中每个元素的值都唯一(集合的唯一性),并且内部能根据元素的值自动进行排序。\n用法 使用之前需要声明头文件 #include\u0026lt;set\u0026gt; ,通过 set\u0026lt;typename\u0026gt; s 来定义一个存储数据类型为typename的集合,名字叫做s。下述实例用此做基础。\n迭代器 通过set\u0026lt;typename\u0026gt;::iterator it,可以来定义一个相应的set的迭代器,用来遍历和指向其中元素。\n主要函数及用途 1. 插入数据 插入特定元素可以通过 s.insert(3) 插入对应键值,返回值为pair\u0026lt;set::iterator,bool\u0026gt; ,后续bool变量标志是否成功,如果元素3已经存在,那么bool值为false,迭代器对应的是该元素在其中的位置,如果元素不存在其中,返回true,并且返回的迭代器对应的在集合中位置 插入一个区间的元素,例如有整数数组a ,可以用 s.insert(a,a+3) ,可以将a中的 a[0] a[1] a[2] 插入到set中。 2. 删除数据 删除和map非常像,也是三种。具体可参考map讲解。\n3. 查找元素 也是可以通过find函数,也是和map非常的像~\n4. 其他 begin() \u0026amp; end( ) 返回头尾迭代器,注意尾迭代器是尾元素的后一位。 clear( ) 清除set容器中所有元素 empty( ) 判断set容器是否为空,为空则返回true,不空返回false size( ) 返回当前set容器中元素的个数 rebegin( ) \u0026amp; rend( ) 返回尾和头迭代器,配合reverse_iterator可以反序遍历set 关于vector和string等 vector好的学习文章 : C++ vector容器浅析\nstring好的学习文章 : C++ STL(一)介绍及string\n","permalink":"https://blog.zzsqwq.cn/posts/28/","summary":"\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003eSTL之前只会用 stack 和 queue ,set 和 map 啥的也不太会用。学习一下。\u003c/p\u003e","title":"关于STL的一些总结"},{"content":"A. 配对 题意 给定含有 $n$ 个正整数的集合 $A$ 和 $B$ ,你需要建立他们之间的一一映射。将配对的两个数相加可以得到 $n$ 个和,问第 $k$ 大的和最大为多少。\n思路 首先我们可以确定,组成前 $k$ 个最大的和一定用的是两个序列里面前 $k$ 大的数字。那么我们只需要知道如何配对能使第 $k$ 大的和最大。我们把问题简化一下如果 $A_1 \u0026lt; A_2$ ,$B_1 \u0026lt; B_2$ ,那么如果想要第二个和最大,肯定是需要 $A_1$ 和 $B_2$ 匹配,$A_2$ 和 $B_1$ 匹配,然后两个选一个最小的。所以这个问题我们类推一下,就是将 $A$ 和 $B$ 序列进行排序,然后取两个里面前 $k$ 个数,$A$ 中大的依次匹配 $B$ 中小的。然后在这 $k$ 个和中取一个最小值即可。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;iostream\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;algorithm\u0026gt; using namespace std; const int maxn=1e5+5; int a[maxn]; int b[maxn]; int n,k,ans=1e9+7; int cmp(int a,int b) { return a\u0026gt;b; } int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;k); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;a[i]); } for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;b[i]); } sort(a+1,a+1+n,cmp); sort(b+1,b+1+n,cmp); for(int i=1;i\u0026lt;=k;i++) { ans=min(ans,a[i]+b[k-i+1]); } printf(\u0026#34;%d\u0026#34;,ans); } B. 十字阵列 题意 给定一个 $n\\times m$ 的网格,每一个交点都一个敌人。你可以使用共 $h$ 次魔法,第 $i$ 次魔法能对第 $x_i$ 行和第 $y_i$ 列的所有敌人造成 $w_i$ 点伤害,交界点的伤害只计算一次。。如果施放完所有所有魔法后,如果一个点 $(i,j)$ 共受到 $z_i$ 点伤害,问 $\\sum{z_i(i+j)}$ 为多少。\n思路 无脑的计数题QAQ..真的是水题啊,我们只需要给每次魔法施放的 $w_i$ 乘上一个 $(i,j)$ 即可,但是因为是一行一列都会变化,那么其实我们可以优化一下,先把一行一列的 $\\sum(i+j)$ 给求出来,然后施法的时候直接乘上这个常数就可以了。(这个题还有个很神奇的地方就是,我明明算的不会爆int然后开的int,然后就错了,后来一直找问题没找出来,后来全改成long long就AC了,太奇怪了。。)\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=2005; typedef long long ll; int mod = 1e9+7; ll row[maxn]; ll col[maxn]; ll x,y,z; ll n,m,h; ll ans,now; int main() { scanf(\u0026#34;%lld%lld%lld\u0026#34;,\u0026amp;n,\u0026amp;m,\u0026amp;h); for(int i=1;i\u0026lt;=n;i++) { row[i]=(m*i)%mod+(m)*(m+1)/2; row[i]%=mod; } for(int j=1;j\u0026lt;=m;j++) { col[j]=(n*j)%mod+(n)*(n+1)/2; col[j]%=mod; } for(int i=1;i\u0026lt;=h;i++) { scanf(\u0026#34;%lld%lld%lld\u0026#34;,\u0026amp;x,\u0026amp;y,\u0026amp;z); now=((row[x]+col[y]-(x+y))%mod)*(z%mod); now%=mod; ans+=now; ans%=mod; } printf(\u0026#34;%lld\\n\u0026#34;,ans); } C. 垃圾陷阱 题意 奶牛卡门想要从垃圾井底上到地面,对于一个垃圾它可以吃掉,或者是堆起来。初始卡门有10个小时的能量,吃掉一个垃圾会给他提供 $f_i$ 个小时的能量,叠起来一个垃圾会获得 $h_i$ 点高度,当垃圾总高度超过井的深度 $D$ 的时候,卡门就能上到地面。一个垃圾当 $t_i$ 小时时会到达井底。给出所有垃圾的状态,问奶牛能否到达地面。\n思路 这个题面被我翻译的屎一样,QAQ,如果看不懂还是去看原题叭。。 这是一个类似于背包的题,对于一个垃圾,我们有两种选择,一个是吃掉它,一个是把他堆起来。。这个状态其实我没找好,看了题解发现可以设 $f[i][j]$ 来表示当用了前 $i$ 个垃圾时,当高度为 $j$ 的时候的最大的体力值(体力值就是还能继续活动多长时间)。我们用结构体数组 $a$ 来表示垃圾,写出如下转移方程。\n如果选择把这个垃圾吃掉,那么 $f[i][j]=max(f[i-1][j]+a[i].f,f[i][j])$\n如果选择把这个垃圾搭起来,那么$f[i][j+a[i].h]=max(f[i-1][j+a[i].h],f[i-1][j])$\n我们发现边界就是 $f[0][0]=10$ ,也就是用了0个垃圾,高度为0的时候体力值为10。\n注意一个地方我们如果到达了地面,就直接输出时间,然后退出程序即可,如果没有的话,我们可以选择遍历每一个垃圾下的 $0$ 高度,也就是说所有垃圾都不叠是最长的寿命,所以输出一个其中的最大值即可。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=105; struct node { int t,f,h; }a[maxn]; int cmp(node a,node b) { return a.t\u0026lt;b.t; } int d,g; int dp[maxn][maxn]; //dp[i][j] 用i个垃圾,当高度为j时所具备的最高生命值 int main() { freopen(\u0026#34;test.in\u0026#34;,\u0026#34;r\u0026#34;,stdin); scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;d,\u0026amp;g); for(int i=1;i\u0026lt;=g;i++) { scanf(\u0026#34;%d%d%d\u0026#34;,\u0026amp;a[i].t,\u0026amp;a[i].f,\u0026amp;a[i].h); } sort(a+1,a+1+g,cmp); memset(dp,-1,sizeof(dp)); dp[0][0]=10; for(int i=1;i\u0026lt;=g;i++) { for(int j=0;j\u0026lt;=d;j++) { if(dp[i-1][j]\u0026gt;=a[i].t) { if(j+a[i].h\u0026gt;=d) { printf(\u0026#34;%d\u0026#34;,a[i].t); return 0; } dp[i][j]=max(dp[i-1][j]+a[i].f,dp[i][j]); dp[i][j+a[i].h]=max(dp[i-1][j+a[i].h],dp[i-1][j]); } } } int ans=0; for(int i=1;i\u0026lt;=g;i++) ans=max(ans,dp[i][0]); printf(\u0026#34;%d\u0026#34;,ans); } ","permalink":"https://blog.zzsqwq.cn/posts/27/","summary":"\u003ch2 id=\"a-配对httpsacnowcodercomacmcontest3007a\"\u003eA. \u003ca href=\"https://ac.nowcoder.com/acm/contest/3007/A\"\u003e配对\u003c/a\u003e\u003c/h2\u003e\n\u003ch3 id=\"题意\"\u003e题意\u003c/h3\u003e\n\u003cp\u003e给定含有 $n$ 个正整数的集合 $A$ 和 $B$ ,你需要建立他们之间的一一映射。将配对的两个数相加可以得到 $n$ 个和,问第 $k$ 大的和最大为多少。\u003c/p\u003e","title":"杂题训练"},{"content":"A. Three Strings 题意 给定三个长度为 $n$ 的字符串 $a$ , $b$ , $c$ ,遍历每个 $c$ 中每个字符 $c_i$,可以将其替换成 $a_i$ 或者 $b_i$ ,必须操作其中一个,问能否通过此操作使得字符串 $a$ , $b$ 相同。\n思路 仔细思考一下,如果要使得最终两个字符串相同的话,必须字符串 $c$ 中出现的字符,在 $a$ 或者 $b$ 字符串出现过,如果每个位置都出现过,那么就是可以的,否则不行。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=105; char a[maxn],b[maxn],c[maxn]; int t; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { scanf(\u0026#34;%s\u0026#34;,a); scanf(\u0026#34;%s\u0026#34;,b); scanf(\u0026#34;%s\u0026#34;,c); int len=strlen(c); bool flag=true; for(int i=0;i\u0026lt;len;i++) if(c[i]!=a[i]\u0026amp;\u0026amp;c[i]!=b[i]) { flag=false; } if(flag) { printf(\u0026#34;YES\\n\u0026#34;); } else printf(\u0026#34;NO\\n\u0026#34;); } return 0; } B. Motarack\u0026rsquo;s Birthday 题意 给定一个含有 $n$ 个整数的序列 $a$ ,其中有一些数丢失,问将丢失的数赋值为多少才能使得相邻两数之差的绝对值的最大值的最小。\n思路 我们想一下首先不缺失的数相邻两数之差是一定,无论赋值前后都不影响。而如果两个相邻的数都缺失的话,那么他们之间差的绝对值一定是0,也不用去看。这样的话我们就看一下,不缺失和缺失两数之间差的绝对值如何能够最小。因为最终所有的缺失的数都是赋值为同一个数,所以我们考虑一下发现需要考虑一下 缺失和不缺失的数相邻的时候,不缺失的那个数的最大值和最小值,我们只需要取他们的和的平均,那么绝对值就可以最小了。所以最终我们就把缺失的值赋为两数均值,然后求一遍相邻数之差绝对值的最大值就好了。(好像这道题难点不是思路,而是实现起来有很多边界等乱七八糟的要自习考虑一下。)\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=100005; const int inf=1000000000; int n,t; int a[maxn]; int minn,maxx,ans,anss; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { minn=inf,maxx=-inf,anss=-inf; scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;a[i]); if(i\u0026gt;1\u0026amp;\u0026amp;a[i]==-1\u0026amp;\u0026amp;a[i-1]!=-1) { minn=min(minn,a[i-1]); maxx=max(maxx,a[i-1]); } } for(int i=1;i\u0026lt;=n;i++) { if(i\u0026lt;n\u0026amp;\u0026amp;a[i]==-1\u0026amp;\u0026amp;a[i+1]!=-1) { minn=min(minn,a[i+1]); maxx=max(maxx,a[i+1]); }\t} ans=(minn+maxx)/2; for(int i=1;i\u0026lt;=n;i++) { if(a[i]==-1) a[i]=ans; if(i\u0026gt;1) anss=max(anss,abs(a[i]-a[i-1])); } printf(\u0026#34;%d %d\\n\u0026#34;,anss,ans); } return 0; } C. Ayoub\u0026rsquo;s function 题意 给定一个01字符串 $s$ ,其中含有 $m$ 个1,用 $f(s)$ 来表示字符串 $s$ 的有多少个字串其中含有1,求出符合条件的字符串 $s$ 中, $f(s)$ 的最大值是多少。\n思路 这题正着想不太好想,含有1的子串可以有很多种情况,但是正难则反,我们可以求出不含1的字串有多少情况,也就是全0的字串有多少种情况,然后用所有情况减去这个就行。 首先可以发现字符串 $s$ 一共有 $\\binom{n}{2}+n$ 种连续子串,那么如果一些0是连续的,那么好比有连续 $l$ 个0的话,我们可以发现他是有 $\\binom{l}{2}+l$ 种情况的。这个字符串一共是含有 $n-m$ 个0的,现在我们思考一下如何摆放这 $(n-m)$ 个0,才能使得 $f(s)$ 最大。那么如果 $f(s)$ 要尽量大,也就是说全0对应的情况就要尽可能的少,所以我们需要将这 $n-m$ 尽可能的均分成 $m+1$ 份,类似于排列组合的插空法,将他们插到其中,但是我们发现有很大的可能是不能均分的,也就是说可能会有余数,那么我们就把余数均匀的分给前面余数个空,这样其实每个多贡献了 $(n-m)/(m+1) +1 $ 个。所以答案也就不难写出来了。不过不要忘了开long long。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; typedef long long ll; ll n,m; ll t; int main() { scanf(\u0026#34;%lld\u0026#34;,\u0026amp;t); while(t--) { scanf(\u0026#34;%lld%lld\u0026#34;,\u0026amp;n,\u0026amp;m); ll sum=n*(n+1)/2; ll p=n-m; ll mod=p%(m+1); ll k=p/(m+1); printf(\u0026#34;%lld\\n\u0026#34;,sum-(m+1)*k*(k+1)/2-(k+1)*mod); } return 0; } ","permalink":"https://blog.zzsqwq.cn/posts/26/","summary":"\u003ch2 id=\"a-three-stringshttpscodeforcescomcontest1301problema\"\u003eA. \u003ca href=\"https://codeforces.com/contest/1301/problem/A\"\u003eThree Strings\u003c/a\u003e\u003c/h2\u003e\n\u003ch3 id=\"题意\"\u003e题意\u003c/h3\u003e\n\u003cp\u003e给定三个长度为 $n$ 的字符串 $a$ , $b$ , $c$ ,遍历每个 $c$ 中每个字符 $c_i$,可以将其替换成 $a_i$ 或者 $b_i$ ,必须操作其中一个,问能否通过此操作使得字符串 $a$ , $b$ 相同。\u003c/p\u003e","title":"Codeforces#619 (Div.2)"},{"content":"前言 今天又是颓废的一天,被大佬拉去跟他一起做牛客网的题,QAQ\u0026hellip;那我会点啥嘛,就只能替大佬写两道水题了···\nA. 牛牛战队的比赛地 题意 由于牛牛战队经常要外出比赛,因此在全国各地建立了很多训练基地,每一个基地都有一个坐标 $(x,y)$ 。 这周末,牛牛队又要出去比赛了,各个比赛的赛点都在 $x$ 轴上。牛牛战队为了方便比赛,想找一个到达训练基地最大距离最小的地方作为比赛地。请你求出选择的比赛地距离各训练基地最大距离的最小值。\n思路 这个题首先一看到这种什么最大的最小,第一直觉就是二分。首先我们想一下应该二分什么,肯定先想的是枚举 $x$ 轴上的点,但是这样就会有个问题,二分要用的话必须是单调的,那么我们不能够确定越往右或者越往左,他们的这个值是单调的。因此我们可以用三分,一直向单峰逼近,最终寻找到那个极值点。(说实话这是我第一次接触到三分法,我太菜了。)\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;iostream\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;algorithm\u0026gt; using namespace std; const int maxn=100005; struct node { int x,y; }p[maxn]; //point int n; const double eps=1e-6; double lmid,rmid,lans,rans; double check(double x) { double ans=0; for(int i=1;i\u0026lt;=n;i++) { double dis=(p[i].x-x)*(p[i].x-x)+p[i].y*p[i].y; ans=max(ans,dis); } return ans; } int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;p[i].x,\u0026amp;p[i].y); } double l=-10000,r=10000; double ans=9999999999; while(r-l\u0026gt;=eps) { lmid=(r+l)/2; rmid=(r+lmid)/2; lans=check(lmid); rans=check(rmid); if(lans\u0026lt;rans) { ans=min(ans,lans); r=rmid; } else { ans=min(ans,rans); l=lmid; } } printf(\u0026#34;%lf\u0026#34;,sqrt(ans)); return 0; } B. 牛牛与牛妹的约会 题意 你想从 $(a,0)$ 点到 $(b,0)$ 点,你可以除了可以以 $1m/s$ 的速度奔跑,还可以用1秒的时间来引导闪现,这将使你从 $(x,0)$ 点闪现到 $(\\sqrt[3]{x},0)$ 点,问最少需要多长时间到达 $(b,0)$ 点。$(Ps:a,b \\in[-10^6,10^6])$\n思路 一道贪心的题目,当闪现所能贡献的距离大于 $1m$ ,那么我就选择用闪现,不然就直接奔跑。那么我们可以用距离的变化来体现闪现贡献的距离,一直用闪现到不能用之后,就直接加上最后剩下的距离即可。注意pow这个函数有点坑?如果底数是负数并且指数不是整数的话好像会返回很奇怪的值···(跟大佬调了好长时间都卡在这了)\n代码实现 #include\u0026lt;iostream\u0026gt; #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;algorithm\u0026gt; using namespace std; int t,x,y; double ans,a,b; double dis,cdis; int main(void) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;x,\u0026amp;y); a =(double)x; b=(double)y; dis = abs(a-b); if(a\u0026lt;0) { cdis=abs(-pow(-a,1.0/3.0)-b); } else cdis = abs(pow(a,1.0/3.0)-b); ans = 0; while(dis-cdis\u0026gt;1.0) { if(a\u0026lt;0) { a=-pow(-a,1.0/3.0); } else a=pow(a,1.0/3.0); ans+=1; dis = cdis; if(a\u0026lt;0) { cdis = abs(-pow(-a,1.0/3.0)-b); } else cdis = abs(pow(a,1.0/3.0)-b); } ans+=dis; printf(\u0026#34;%.9lf\\n\u0026#34;,ans); } return 0; } C. 碎碎念 题意 大佬豪和弱鸡战合作做题,如果大佬豪AC掉题目,那么弱鸡战会说 “宁好强啊!”,如果大佬豪WA掉了题目,那么弱鸡战会嘲讽大佬豪 $k$ 句 “宁好弱啊!” 。我们规定大佬豪提交只有AC和WA两种状态。因为大佬豪非常的强,如果一道题他WA掉了一发,那么他的下一发一定会AC。如果已知最终弱鸡战嘲讽了 $x$ 句,那么很明显可以对应很多的提交序列。现在想问你如果弱鸡战嘲讽数在 $[l,r]$ 这个区间,一共会有多少种提交序列。答案对 $1e9+7$ 取模。\n思路 首先原始题面不是这样,我把名字改了一下,QAQ\u0026hellip; QAQ刷了这么多天的dp好像终于有点作用了,我终于看出来这是一道dp题了,还找对了他们的状态,不过转移方程却写错了。那么首先我们可以用 $f[i]$ 来表示,如果说了 $i$ 句话,那么一共有多少种可能的序列,但是这样的话我们发现没法确保上文上的如果WA掉了,下一发一定是AC。 所以我们可以考虑加一维状态来表示是通过哪种提交状态到达第 $i$ 句话的,也就是写成 $dp[0/1][i]$ 这个状态,$dp[0][i]$ 代表是从 $i-1$ 句话直接AC转移过来的,$dp[1][i]$ 是从 $i-k$ 句话通过WA转移过来的。所以这样的话转移方程就可以写出来了。\n$dp[0][i] = dp[0][i-1]+dp[1][i-1]$ (可以从WA和AC转移过来)\n$dp[1][i]=dp[0][i-k]$ (只能从第 $i-k$ 状态是AC的时候转移,不能连续两次WA)\n因为最终是一个区间查询,那么我们可以用前缀和来优化。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; using namespace std; const int maxn=100005; int k,q; int l,r; int mod =1e9+7; int dp[2][maxn]; int sum[maxn]; int ans[maxn]; int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;k,\u0026amp;q); dp[0][0]=1; for(int i=1;i\u0026lt;=100000;i++) { dp[0][i]=dp[0][i-1]+dp[1][i-1]; dp[0][i]%=mod; if(i\u0026gt;=k) { dp[1][i]=dp[0][i-k]; dp[1][i]%=mod; } ans[i]=dp[0][i]+dp[1][i]; ans[i]%=mod; sum[i]=sum[i-1]+ans[i]; sum[i]%=mod; } for(int i=1;i\u0026lt;=q;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;l,\u0026amp;r); printf(\u0026#34;%d\\n\u0026#34;,(sum[r]-sum[l-1]+mod)%mod); } return 0; } D. 牛牛战队的秀场 题意 在半径为 $r$ 的圆内有一个正接 $n$ 边形,随便选取一个顶点编号为 $1$ ,顺时针编号为 $2\\sim n$ ,规定只能沿多边形边走,问从顶点 $i$ 到顶点 $j$ 最短路径为多少。\n思路 很显然只有两条路可以走,我们只需要算出正多边形的每条边的边长,然后比较两条路径的大小,哪一个短就走哪一个就行,不过如果用了cos() 函数记得特判一下 $n=4$ 的情况,不然会发生错误。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; int n,ri; double r; int i,j; double pi = 3.1415926535898; int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;ri); scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;i,\u0026amp;j); double k=(double)2*pi/(double)n; double s; r=(double)ri; if(n==4) { s=sqrt(2*r*r); } else s=sqrt((double)2*r*r-2.0*r*r*cos(k)); int p=abs(i-j); if(p\u0026gt;n/2) { printf(\u0026#34;%lf\u0026#34;,s*(n-p)); } else printf(\u0026#34;%lf\u0026#34;,s*p); return 0; } ","permalink":"https://blog.zzsqwq.cn/posts/25/","summary":"\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003e今天又是颓废的一天,被大佬拉去跟他一起做牛客网的题,QAQ\u0026hellip;那我会点啥嘛,就只能替大佬写两道水题了···\u003c/p\u003e","title":"日常水题"},{"content":"A. 方格取数 题意 有一个 $N*N$ 的整数方阵,每个点初始值为0,在一些点上放上数,一个人从左上角走到右下角,规定只能向下或向右走,当他经过的点上有数时会取走它,问走两遍最多能取的数的和最大为多少。\n思路 也就是说我们要找两条路径使他取数最大,首先我一开始想法是先走一遍,找到最大的那个路径,将这条路径上所有点设为0,然后再回来找这个方阵中最大的那个路径,两个加起来就行。但是路径上所有的点设为0这个地方不是很好实现,因此我们可以考虑另一个思路,两次同时走。我们把这两次看成两个人走的,表述方便。 我们用 $dp[i][j][k][l]$ 来表示当第一个人走到 $(i,j)$ 第二个人走到 $(k,l)$ 时做能取数最多为多少 ,那么我们就可以考虑一下转移怎么转移,因为到达一个点只能是从左边来,或者是从上边来,因此第一个人从 $(i-1,j)$ 或者 $(i,j-1)$ 转移来,那么第二个人就从 $(k-1,l)$ 或者 $(k,l-1)$ 转移来,那么这个转移方程就是四种转移方式。我们需要保证一个问题,就是他俩经过同一个点的判定情况。我们需要将第二个人的坐标通过第一个人来限制,也就是说要确保第二个人和第一个人步数是相同的,当他们步数相同的时候,那么就不存在他们经过同一个点但是时间却是不同的情况了,因为到达一个点的步数是一定的。 再就是这个状态数组其实还是可以压缩到三维和二维的,这个就先不谈了,可以看洛谷的题解区。 这个题是一个经典的多维dp的题目,感觉还是挺有意义的。而且这个题和 传纸条 很像,可以双倍经验。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=15; int map[maxn][maxn]; int n,x,y,z; int m; int dp[maxn][maxn][maxn][maxn]; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); while(1) { scanf(\u0026#34;%d%d%d\u0026#34;,\u0026amp;x,\u0026amp;y,\u0026amp;z); if(x==0\u0026amp;\u0026amp;y==0\u0026amp;\u0026amp;z==0) break; map[x][y]=z; } for(int i=1;i\u0026lt;=n;i++) { for(int j=1;j\u0026lt;=n;j++) { for(int k=1;k\u0026lt;=n;k++) { m=i+j-k; if(m\u0026lt;=0) continue; if(i==k\u0026amp;\u0026amp;j==m) dp[i][j][k][m]=max(max(dp[i-1][j][k-1][m],dp[i-1][j][k][m-1]),max(dp[i][j-1][k-1][m],dp[i][j-1][k][m-1]))+map[i][j]; else dp[i][j][k][m]=max(max(dp[i-1][j][k-1][m],dp[i-1][j][k][m-1]),max(dp[i][j-1][k-1][m],dp[i][j-1][k][m-1]))+map[i][j]+map[k][m]; } } } printf(\u0026#34;%d\u0026#34;,dp[n][n][n][n]); return 0; } B. 创意吃鱼法 题意 给出一个 $N*M$ 的只包含0和1的数阵,求只有对角线为1,其余位置为0的子方阵的最大边长。\n思路 这个题我们需要考虑两个方向,这个对角线既可以是斜向左上,也可以是斜向右上的。我们先考虑前者,后者同理即可。我们可以用两个数组 $col[i][j]$ 和 $row[i][j]$ 分别来表示,包含 $(i,j)$ 这个点往上一列有多少个0,以及包含这个点往左一行有多少个0,(这个在程序里好像我写反了,但是没啥区别说实话)。然后我们用 $f[i][j]$ 来表示,从这个点左上走满足条件的方阵的最大边长。那么很显然这个值和上方的0,左方的0,以及左上的状态有关,这个点是1的话,转移方程就是 $f[i][j]=min(f[i-1][j-1],min(col[i-1][j],row[i][j-1]))+1$ 。如果是0的话我们就更新 $col$ 和 $row$ 数组的值。然后求完斜向左上的再求一遍斜向右上的,取一个最大值即可。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=2505; int n,m; int map[maxn][maxn]; int col[maxn][maxn],row[maxn][maxn]; int dp[maxn][maxn]; int ans; int main() { //\tfreopen(\u0026#34;test.in\u0026#34;,\u0026#34;r\u0026#34;,stdin); scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;m); for(int i=1;i\u0026lt;=n;i++) { for(int j=1;j\u0026lt;=m;j++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;map[i][j]); if(!map[i][j]) { row[i][j]=row[i-1][j]+1; col[i][j]=col[i][j-1]+1; } else { dp[i][j]=min(dp[i-1][j-1],min(row[i-1][j],col[i][j-1]))+1; ans=max(dp[i][j],ans); } } } memset(row,0,sizeof(row)); memset(col,0,sizeof(col)); memset(dp,0,sizeof(dp)); for(int i=1;i\u0026lt;=n;i++) { for(int j=m;j\u0026gt;=1;j--) { if(!map[i][j]) { row[i][j]=row[i-1][j]+1; col[i][j]=col[i][j+1]+1; } else { dp[i][j]=min(dp[i-1][j+1],min(row[i-1][j],col[i][j+1]))+1; ans=max(ans,dp[i][j]); } } } printf(\u0026#34;%d\u0026#34;,ans); } C. 乌龟棋 题意 给出标号分别为1,2,3,4的四种卡片若干张,分别可以移动1,2,3,4步,玩家初始处于坐标为1的位置。玩家出一张牌,可移动相应的步数。移动到不同的坐标会加不同的分数,很明显不同的出牌顺序会对应着不同的分数,求玩家能获得的最大分数为多少。\n思路 很显然我们可以通过已经出的牌计算出现在已经到达到哪个位置。我们可以用一个四重循环,来循环每张牌用的数量,很明显我们到达一个目标位置所用的最后一张牌可以是1,2,3,4的任何一个,因此我们可以从这个四个状态转移过来,找其中最大那个就可以了,注意要判断一下要转移过来的状态是否合法。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=355; const int maxm=125; int n,m,pos; int w[maxn]; int x,num[5]; int dp[42][42][42][42]; int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;m); for(int i=1;i\u0026lt;=n;i++) scanf(\u0026#34;%d\u0026#34;,\u0026amp;w[i]); for(int i=1;i\u0026lt;=m;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;x); num[x]++; } memset(dp,-1,sizeof(dp)); dp[0][0][0][0]=w[1]; for(int a=0;a\u0026lt;=num[1];a++) { for(int b=0;b\u0026lt;=num[2];b++) { for(int c=0;c\u0026lt;=num[3];c++) { for(int d=0;d\u0026lt;=num[4];d++) { pos=1+a+(b\u0026lt;\u0026lt;1)+c*3+(d\u0026lt;\u0026lt;2); if(a\u0026gt;0\u0026amp;\u0026amp;dp[a-1][b][c][d]!=-1) { dp[a][b][c][d]=max(dp[a][b][c][d],dp[a-1][b][c][d]+w[pos]); } if(b\u0026gt;0\u0026amp;\u0026amp;dp[a][b-1][c][d]!=-1) { dp[a][b][c][d]=max(dp[a][b][c][d],dp[a][b-1][c][d]+w[pos]); } if(c\u0026gt;0\u0026amp;\u0026amp;dp[a][b][c-1][d]!=-1) { dp[a][b][c][d]=max(dp[a][b][c][d],dp[a][b][c-1][d]+w[pos]); } if(d\u0026gt;0\u0026amp;\u0026amp;dp[a][b][c][d-1]!=-1) { dp[a][b][c][d]=max(dp[a][b][c][d],dp[a][b][c][d-1]+w[pos]); } } } } } printf(\u0026#34;%d\u0026#34;,dp[num[1]][num[2]][num[3]][num[4]]); return 0; } D. 能量项链 题意 给出一段含有 $n$ 个珠子的环状项链,对于相邻的两个珠子,前一颗珠子的尾标记等于后方珠子的头标记。 例如项链为 $[2,4,6,8]$ , 那么用加入标记表示就是 $[(2,4),(4,6),(6,8),(8,2)]$ 。当两个珠子两两合并的时候会产生的能量大小为 前方珠子头标记 $\\times$ 前方珠子尾标记 $\\times$ 后方珠子尾标记。显然合并的顺序不同最终会产生不同的能量值,问能产生的最大能量值为多少。\n思路 这道题和合并石子很像,也是一个区间dp的例题,我们也是通过枚举区间长度,然后枚举区间断点来分割区间。这个题也是一个环状,我们也是断环为链,不过处理释放的能量值的问题,我是用了一个结构体,来表示每一颗珠子的标记,通过这个来计算释放能量。不过记得处理子区间也要从处理到 $1\\sim 2n$, 这个地方卡了我巨长时间,因为你后面要用到这个状态,如果不计算子区间无法转移到后面。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; typedef long long ll; const int maxn=105; int n; ll dp[maxn\u0026lt;\u0026lt;1][maxn\u0026lt;\u0026lt;1]; struct node { ll w; ll nxt; }a[maxn\u0026lt;\u0026lt;1]; int main() { //\tfreopen(\u0026#34;test.in\u0026#34;,\u0026#34;r\u0026#34;,stdin); scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%lld\u0026#34;,\u0026amp;a[i].w); a[i+n].w=a[i].w; } for(int i=1;i\u0026lt;=n*2-1;i++) { a[i].nxt=a[i+1].w; } for(int i=1;i\u0026lt;=2*n;i++) dp[i][i]=0; for(int p=2;p\u0026lt;=n;p++) { for(int i=1;i\u0026lt;=2*n-p+1;i++) //重要(卡我巨长时间) { int j=i+p-1; for(int k=i;k\u0026lt;j;k++) { dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+a[i].w*a[k].nxt*a[j].nxt); } } } //\tfor(int i=1;i\u0026lt;=n;i++) //\t{ //\tprintf(\u0026#34;%d \u0026#34;,dp[i][i+1]); //\t} ll ans=0; for(int i=1;i\u0026lt;=n;i++) ans=max(ans,dp[i][i+n-1]); printf(\u0026#34;%lld\u0026#34;,ans); return 0; } ","permalink":"https://blog.zzsqwq.cn/posts/24/","summary":"\u003ch2 id=\"a-方格取数httpswwwluogucomcnproblemp1004\"\u003eA. \u003ca href=\"https://www.luogu.com.cn/problem/P1004\"\u003e方格取数\u003c/a\u003e\u003c/h2\u003e\n\u003ch3 id=\"题意\"\u003e题意\u003c/h3\u003e\n\u003cp\u003e有一个 $N*N$ 的整数方阵,每个点初始值为0,在一些点上放上数,一个人从左上角走到右下角,规定只能向下或向右走,当他经过的点上有数时会取走它,问走两遍最多能取的数的和最大为多少。\u003c/p\u003e","title":"dp习题练习"},{"content":"前言 最近感觉遇到了好多单调队列和单调栈的问题,但是因为以前没学好,所以遇见了就一脸懵逼,然后绝对下决心来学一下。。感觉遇到啥都不会,这可咋办呐。。补不完的漏洞。 单调队列(Monotone queue) 单调队列,即单调递减或单调递增的队列。使用频率不高,但在有些程序中会有非同寻常的作用。\n理解 顾名思义,他就是一个单调的队列,那么我们可以规定他是单调递增的还是单调递减的,他和普通的队列有点区别,队列一般是尾进头出,而单调队列要实现的话要确保头和尾都可以出,尾可以进。如果要用STL库的话可以用里面的双端队列。 跟普通队列相比他的进队需要确保一个条件就是要不破坏原有序列的单调性,好比我们有一个单调递增的单调队列,也就是从队首到队尾是单调递增的,那么有一段序列是 $[2,3,1,5,8,7,4,2]$ ,我们从左到右依次入队。\n队列中元素 关于元素进出的备注 2 2入队 2,3 3比2大,可以满足递增性质,入队 1 因为1比2,3都小,要满足递增性质,先把2,3出队,再将1入队 1,5 5比1大,可以满足递增性质,入队 1,5,8 8比5大,可以满足递增性质,入队 1,5,7 7小于8,大于5,要满足递增性质,我们把8出队,然后将7入队 1,4 4小于5、7,但是大于1,因此7,5依次出队,4入队 1,2 2小于4,大于1,因此4出队,2入队 根据上述例子不难看出,我们要入队的时候首先要确保队尾元素要比想要入队的元素小,然后才能入队,否则的话就一直循环让尾部元素出队,直到能够满足单调性为止。\n单调队列的应用 求区间的最值问题。下面写的两个例题都是这个用处。 优化dp,我现在能接触到的就是一个用单调队列优化多重背包的一个题,但是那个题我学了这个东西之后还是不理解为什么可以那么做。例题如下:宝物筛选 单调队列的一些例题 A. Sliding Window 题意 给出一个含有 $n$ 个整数的序列 $a$ ,给出滑动窗口长度 $k$ ,窗口从序列最左端滑动到序列最右端,问滑动过程中每个时刻窗口中最大值和最小值是多少。\n思路 一道很经典的单调队列的模板题,用于解决定长区间的最大最小值。我们可以维护两个单调队列,一个是单调递增的,一个是单调递减的。因为两种情况类似,我们考虑一下求窗口中最大值的方案。\n求最大值我们用的是单调递减的序列,这样就能够保证每次队首的就是答案,但是,这是为什么呢?我们来考虑一下,因为这是一个单调递减的序列,那么我们每次序列元素入队的时候,我们就去看当前队尾的元素是不是要比他大,如果比他还小,那么我们就直接将队尾元素出队,因为这时候要入队的元素(已经被窗口覆盖了)已经比他大了,那么在接下来的窗口中,肯定就没他什么事了,因为它一定不是最大的,那么如果一直将队尾元素出队到加入入队元素后还继续能保持队列的单调性了,但是这个元素还不是在队首,这就说明,队首的元素还是要比他大的(单调性易得)。\n所以这时候队首元素就是这个窗口中最大的了吗?也还不能确定,因为我们还不能确保这个队首元素就在窗口中,因此我们需要看看这个元素的位置和当前入队元素的位置之差是不是要比窗口长度大了,如果大于窗口长度,那么就说明队首元素已经不在窗口了,我们就将队首元素出队,最后输出队首元素就能确保它既在窗口中,又是窗口中所有元素的最大值了!\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=1000005; int n,k; int head,tail,a[maxn]; struct node { int pos,value; }q[maxn]; void getmax() { head=tail=0; for(int i=1;i\u0026lt;=n;i++) { while(head!=tail\u0026amp;\u0026amp;i-q[head].pos\u0026gt;=k) head++; while(head!=tail\u0026amp;\u0026amp;a[i]\u0026lt;=q[tail-1].value) tail--; q[tail].value=a[i],q[tail++].pos=i; if(i\u0026gt;=k) printf(\u0026#34;%d \u0026#34;,q[head].value); } putchar(\u0026#39;\\n\u0026#39;); for(int i=1;i\u0026lt;=n;i++) q[i].value=q[i].pos=0; } void getmin() { head=tail=0; for(int i=1;i\u0026lt;=n;i++) { while(head!=tail\u0026amp;\u0026amp;i-q[head].pos\u0026gt;=k) head++; while(head!=tail\u0026amp;\u0026amp;a[i]\u0026gt;=q[tail-1].value) tail--; q[tail].value=a[i],q[tail++].pos=i; if(i\u0026gt;=k) printf(\u0026#34;%d \u0026#34;,q[head].value); } } int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;k); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;a[i]); } getmax(); getmin(); return 0; } B. Max Sum of Max-K-sub-sequence 题意 给定长度为 $n$ 的整数循环序列 $a$ ,也就是$a[1],a[2],\\cdots,a[n],a[1]\\cdots$ 这样的序列,问最大连续长度为 $k$ 的连续子区间的序列和最大为多少,并且输出这个区间的左右坐标。\n思路 我们把这道题转换一下,我们先处理好前缀和,好比我们要求 $a[1],a[2],a[3]$ 的序列和,那么也就是 $sum[3]-sum[0]$ ,因此我们在求这个题的时候就可以循环遍历 $1\\sim{n-k+1}$ ,求长度为 $k$ 的定长区间中前缀和数组的最小值即可。但是我们要注意前缀和数组要处理到 $n-k+1$ 。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int inf=1000000; const int maxn=200005; int t; int n,k,a[maxn],sum[maxn]; int head,tail; struct node { int pos,value; }q[maxn]; int ans,l,r; int main() { //\tfreopen(\u0026#34;test.in\u0026#34;,\u0026#34;r\u0026#34;,stdin); scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { l=r=0; head=tail=0; ans=-inf; scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;k); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;a[i]); sum[i]=sum[i-1]+a[i]; } for(int i=n+1;i\u0026lt;=n+k-1;i++) { sum[i]=sum[i-1]+a[i-n]; } for(int i=1;i\u0026lt;=n+k-1;i++) { while(head!=tail\u0026amp;\u0026amp;i-q[head].pos\u0026gt;k) head++; while(head!=tail\u0026amp;\u0026amp;sum[i-1]\u0026lt;=q[tail-1].value) tail--; q[tail].pos=i-1,q[tail++].value=sum[i-1]; //\tif(i!=q[head].pos) //\t{ int p=sum[i]-q[head].value; if(p\u0026gt;ans) { ans=p; int k=q[head].pos+1; k\u0026gt;n?l=k%n:l=k; i\u0026gt;n?r=i%n:r=i; } //\t} } printf(\u0026#34;%d %d %d\\n\u0026#34;,ans,l,r); for(int i=1;i\u0026lt;=n+k-1;i++) q[i].pos=q[i].value=-inf; } return 0; } 单调栈(Monotone stack) 单调增或单调减的栈,跟单调队列差不多,但是只用到它的一端。\n理解 单调栈也是在普通栈的基础上加了单调性,一般是用从栈底到栈顶的单调性来命名,好比从栈底到栈顶是单调递增的,那么他就是单调增的栈。跟单调队列一样,他的入栈规则也是要不破坏单调性,因此一个单调递增的栈如果有元素要入栈,如果他比栈顶的元素还要大,就可以直接入栈,如果他比栈顶的元素小,那么就要将栈顶的元素一直出栈到比要入栈元素小为止。如果序列为 $[2,3,1,5,4,7]$,要加入单调递增栈中,过程如下。PS:注意从左到右对应栈底到栈顶。\n栈中的元素 关于元素进出的备注 2 元素2压入栈中 2,3 3大于2,压入栈中 1 1小于3、2,因此全部弹出将1入栈 1,5 5大于1,压入栈中 1,4 4比5小,比1大,弹出5,压入4 1,4,7 7大于4,压入栈中 根据上述描述不难看出,其实单调栈就是单调队列的半部分,他能完成的任务理论上单调队列都能够完成,但是有些时候不需要麻烦的去维护单调队列只需要维护单调栈即可完成。\n单调栈的应用 确定一个元素的左边区间第一个比它大的元素,第一个比它小的元素 确定右边区间第一个比他大or比他小的元素(根据单调性来看) 确定这个元素是否是一定区间内的最值,或者确定以他为最值的区间长度 单调栈的一些例题 A. 单调栈模板 题意 给出含有 $n$ 个整数的序列 $a$ ,定义 $f(i)$ 为第 $i$ 个元素后第一个大于 $a_i$ 的下标,求 $f(1)\\cdots f(n)$\n思路 直接就是模板,对应了上述应用里的第二个。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=3000005; int n,a[maxn]; int stack[maxn]; int top,ans[maxn]; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;a[i]); } a[0]=1e9+5; for(int i=1;i\u0026lt;=n;i++) { while(top\u0026gt;=0\u0026amp;\u0026amp;a[i]\u0026gt;a[stack[top]]) { ans[stack[top]] = i; top--; } stack[++top]=i; } while(top) { ans[stack[top]]=0; top--; } for(int i=1;i\u0026lt;=n;i++) { printf(\u0026#34;%d \u0026#34;,ans[i]); } return 0; } B. 发射站 题意 某地有 $N$ 个能量发射站排成一行,每个发射站 $i$ 都有不相同的高度 $H_i$,并能向两边(两端的发射站只能向一边)同时发射能量值为 $V_i$ 的能量,发出的能量只被两边最近的且比它高的发射站接收。计算出接受能量最多的发射站接受的能量为多少。\n思路 维护一个单调递减栈,一个元素新加进来如果是大于栈顶元素的话,那么栈顶元素出栈,并给入栈元素加上能量值。如果不大于栈顶元素的话,就将栈顶元素加上发射能量,然后将元素入栈。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=1000005; int n,h[maxn],v[maxn]; int stack[maxn],top,ans; int f[maxn]; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;h[i],\u0026amp;v[i]); } for(int i=1;i\u0026lt;=n;i++) { while(top\u0026gt;=0\u0026amp;\u0026amp;h[i]\u0026gt;h[stack[top]]) { f[i]+=v[stack[top]]; top--; } f[stack[top]]+=v[i]; stack[++top]=i; } for(int i=1;i\u0026lt;=n;i++) ans=max(ans,f[i]); printf(\u0026#34;%d\u0026#34;,ans); return 0; } C. 音乐会的等待 题意 给出一段序列 $a$ 代表 $n$ 个人,在一个区间 $[l,r]$ 如果区间内没有大于 $min(a[i],a[r])$ 的那么两个人可以相互看到。问这个序列中有多少对人可以相互看到。\n思路 我们可以维护一个单调递减栈,然后分情况讨论一下。\n如果要入栈元素大于当前元素,那么当前元素和入栈元素是可以相互看见的,因为这是找了左边区间第一个比它小的元素了,然后因为这是一个单调递减栈,所以我们可以一直出栈比入栈元素小的元素,可以发现这些都是可以互相看见的。而且最终的栈顶元素和要入栈元素也是可以看见的。 如果入栈元素小于当前元素,他可以和栈顶元素看见,而不能和后面的人看见,因为栈顶元素挡住他了。 如果入栈元素和当前元素高度相同,那么他们俩其实是等效的,如果有人比他们高,其实是可以直接看见两个,所以我们只需要将他们看成一个结构体,记录他们的数量和高度即可,每次统计的时候加上数量就行。 代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; typedef long long ll; const int maxn=500005; int n; int h[maxn]; ll ans; struct node { ll cnt; // num ll p; //height }stack[maxn]; int top; int main() { //\tfreopen(\u0026#34;test.in\u0026#34;,\u0026#34;r\u0026#34;,stdin); scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;h[i]); } for(int i=1;i\u0026lt;=n;i++) { node temp; temp.cnt=1; temp.p=h[i]; while(top\u0026gt;=0\u0026amp;\u0026amp;h[i]\u0026gt;stack[top].p) { ans+=stack[top].cnt; top--; } if(h[i]==stack[top].p) { ans+=stack[top].cnt; temp.cnt+=stack[top].cnt; top--; } stack[++top].cnt=temp.cnt; stack[top].p=temp.p; if(top!=0) ans+=1; } printf(\u0026#34;%lld\u0026#34;,ans); } 参考链接 单调队列和单调栈详解\n[SMOJ2116]诺诺的队列\n一些关于单调队列和单调栈优化dp的实例\n","permalink":"https://blog.zzsqwq.cn/posts/23/","summary":"\u003ch1 id=\"前言\"\u003e前言\u003c/h1\u003e\n\u003cpre\u003e\u003ccode\u003e最近感觉遇到了好多单调队列和单调栈的问题,但是因为以前没学好,所以遇见了就一脸懵逼,然后绝对下决心来学一下。。感觉遇到啥都不会,这可咋办呐。。补不完的漏洞。\n\u003c/code\u003e\u003c/pre\u003e","title":"单调队列和单调栈总结"},{"content":"A. Non-zero 题意 给出一段含有 $n$ 个数的序列 $a$ ,可以对其中任何数加一,问最少操作多少次让每一个数和序列和都不为0。\n思路 输入的时候如果输入的是 $0$ 就将答案加一,最后如果序列和为 $0$ 的话答案加一。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; int t,n,sum,p,ans; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { sum=ans=0; scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;p); if(p==0) { ans++; sum+=1; } else sum+=p; } if(sum==0) printf(\u0026#34;%d\\n\u0026#34;,ans+1); else printf(\u0026#34;%d\\n\u0026#34;,ans); } } B. Assigning to Classes 题意 将 $2n$ 个数分成个奇数序列,问两个奇数序列的中位数之差最小为多少。\n思路 直接就将序列排序然后输出中间两个数之差即可。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn = 100005; int t,n,a[maxn\u0026lt;\u0026lt;1]; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); int p=n\u0026lt;\u0026lt;1; for(int i=1;i\u0026lt;=p;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;a[i]); } sort(a+1,a+1+p); printf(\u0026#34;%d\\n\u0026#34;,abs(a[n]-a[n+1])); } return 0; } C. Anu Has a Function 题意 给出函数 $f: f(x,y)=(x|y)-y $ ,给出序列 $a$,序列 $a$ 中含有 $n$ 个数,可以表示为$[a_1,a_2\\cdots,a_n ]$ ,定义 $x=f(f(\u0026hellip;f(f(a_1,a_2),a_3),\u0026hellip;a_{n-1}),a_n)$ ,你可以对序列 $a$ 中元素进行重排,求使得 $x$ 最大的序列 $a$ 。如果有多种情况,输出一种即可。\n思路 第一种思路是因为 $f(x,y)=(x|y)-y$ ,我们可以发现对于经过这样的运算之后,如果 $x$ 的某一位是1,如果 $y$ 的相应位是0,那么运算出来的 $f(x,y)$ 对应位就是1,如果 $y$ 对应位是1,那么运算出来就是0。那么对于 $x$ 的计算过程中的每一位这个规律都是适应的。因此我们只需要将位数从高到低依次扫一遍,如果这个位数为1的情况在序列所有元素中只出现了一次,那么就将唯一出现1的那个数放到第一位即可。\n第二种思路 $$ \\because f(x,y)=(x|y) - y {\\Longleftrightarrow} f(x,y) = x\u0026amp;({\\sim} y) \\therefore x=(a_1)\u0026amp;({\\sim}a_2)\u0026amp;({\\sim} a_3){\\cdots}({\\sim}a_n) $$ 我们发现后面其实都是可交换的,所以第一个只有第一个是起决定作用的,那么我们就可以处理一个前缀和后缀的 and 数组,这样我们就可以 $O(1)$ 的计算出后面那部分,然后遍历序列 $a$ 找到最合适的 $a_1$。\n代码实现 第一种思路 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=100005; int n,a[maxn],maxk; int cnt; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;a[i]); maxk=max(maxk,a[i]); } int p=1,k=0; while(p\u0026lt;=maxk) { k++; p\u0026lt;\u0026lt;=1; } for(int i=k;i\u0026gt;=0;i--) { cnt=0; for(int j=1;j\u0026lt;=n;j++) { if(a[j]\u0026amp;(1\u0026lt;\u0026lt;i)) { cnt++; if(cnt==1) swap(a[j],a[1]); } } //\tprintf(\u0026#34;%d %d\\n\u0026#34;,i,cnt); if(cnt==1) { for(int j=1;j\u0026lt;=n;j++) { printf(\u0026#34;%d \u0026#34;,a[j]); } return 0; } } for(int i=1;i\u0026lt;=n;i++) { printf(\u0026#34;%d \u0026#34;,a[i]); } return 0; } 第二种思路 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=100005; int n,a[maxn]; int ans; int pre[maxn],suf[maxn]; //pre is prefix,suf is suffix int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;a[i]); a[i]=~a[i]; if(i==1) pre[i]=a[i]; else pre[i]=pre[i-1]\u0026amp;a[i]; } suf[n]=a[n]; for(int i=n-1;i\u0026gt;=1;i--) { suf[i]=suf[i+1]\u0026amp;a[i]; } for(int i=1;i\u0026lt;=n;i++) { int p=a[i]; p=~a[i]; if(i==1) { int now=suf[i+1]\u0026amp;p; ans=max(ans,now); } else if(i==n) { int now=pre[i-1]\u0026amp;p; if(now\u0026gt;ans) { swap(a[i],a[1]); ans=now; } } else { int now=pre[i-1]\u0026amp;suf[i+1]\u0026amp;p; if(now\u0026gt;ans) { swap(a[i],a[1]); ans=now; } } } for(int i=1;i\u0026lt;=n;i++) { printf(\u0026#34;%d \u0026#34;,~a[i]); } return 0; } D. Aerodynamic 题意 给定一个凸多边形 $P$ 的所有顶点,可以将凸多边形沿向量 $(x,y)$ 平移,我们定义多边形 $T$ 是所有 $P$ 平移到与原点有交点后所构成的点集所形成的图形(我知道这句话有点绕,我实在是解释不明白,实在不行康康原题吧)。那么问这个 $T$ 是否是和 $P$ 相似的,如果是输出YES,不是输出NO。\n思路 就是判断这个图形是不是中心对称图形就行了,证明还不会,暂且放一下,会了再写QAQ..\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=100005; int n; int x[maxn],y[maxn]; bool check() { int p=n/2; //\tprintf(\u0026#34;%d\u0026#34;,p); int x1=x[1]+x[1+p]; int y1=y[1]+y[1+p]; for(int i=2;i\u0026lt;=p;i++) { if(x1!=x[i]+x[i+p]||y1!=y[i]+y[i+p]) { return false; } } return true; } int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;x[i],\u0026amp;y[i]); } if(n\u0026amp;1) { printf(\u0026#34;NO\u0026#34;); } else { if(check()) { printf(\u0026#34;YES\u0026#34;); } else printf(\u0026#34;NO\u0026#34;); } return 0; } ","permalink":"https://blog.zzsqwq.cn/posts/22/","summary":"\u003ch2 id=\"a-non-zerohttpscodeforcescomcontest1300problema\"\u003eA. \u003ca href=\"https://codeforces.com/contest/1300/problem/A\"\u003eNon-zero\u003c/a\u003e\u003c/h2\u003e\n\u003ch3 id=\"题意\"\u003e题意\u003c/h3\u003e\n\u003cp\u003e给出一段含有 $n$ 个数的序列 $a$ ,可以对其中任何数加一,问最少操作多少次让每一个数和序列和都不为0。\u003c/p\u003e","title":"Codeforces #618 (Div.2)"},{"content":"1. 分组背包 题意 在01背包基础上,将其中的物体分成 $k$ 组,每组内的物品相互冲突,即只能取其中一个,问最大价值。\n思路 同一组中各个物品是相互排斥的,那么我们对于处理可以外层循环组别,然后循环体积,最后循环组内的物品,然后套用01背包的转移方程 $dp[i]=max(dp[i],dp[i-v[k]]+w[k])$ 即可。我们来思考一下他的正确性,为什么只要这样循环就能确保每个组最多只取用一种呢?很明显组内的我们对于同一个体积 $V$ ,求体积 $V$ 对应的最大价值的时候,是从这个组内所有物品中取了能获得最大价值的策略,很明显当我们转移任何一个 $dp[i-v[k]]$ 的状态的时候,他们其中都不包含第 $i$ 组的物品,都是只包含了前 $i-1$ 组的物品,因为我们最终取得最大价值的路径是确定的,因此通过这个方式我们就可以确保每个组内只取一种,但是如果体积和组内物品的循环调换过来,就不行了,因为之前的状态就会包含当前组内的其他物品。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn =1005; const int maxt = 105; struct item { int a,b; }p[maxt][maxn]; int cnt[maxt]; int n,m; int dp[maxn]; int q,w,e,maxe; int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;m,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d%d%d\u0026#34;,\u0026amp;q,\u0026amp;w,\u0026amp;e); cnt[e]++; p[e][cnt[e]].a=q; p[e][cnt[e]].b=w; maxe=max(maxe,e); } for(int i=1;i\u0026lt;=maxe;i++) { for(int j=m;j\u0026gt;=0;j--) { for(int k=1;k\u0026lt;=cnt[i];k++) { if(j\u0026gt;=p[i][k].a) dp[j]=max(dp[j],dp[j-p[i][k].a]+p[i][k].b); } } } printf(\u0026#34;%d\u0026#34;,dp[m]); } 2. 有依赖的背包 题意 在01背包的基础上给物品加上依赖,某个物品可能为附件,必须买了主件之后才能买。规定一个物品最多有两个附件,并且附件不会再有附件,也不存在循环依赖(附件再依赖于主件)。问能获得的最大价值为多少。\n思路 这道题有三种思路,难度依次递增。\n这道题的附件很少,可能为0,1,2。那么我们就在01背包的基础上,分五种情况来转移,分别是都不买,只买一个主件,只买主件和附件1,只买主件和附件2,买主件和两个附件。然后在这个基础上取一个最大的即可。但是这个思路对于附件可以很多的情况,就会特别麻烦。 第二种思路是转化成分组背包,我们注意到对于每一个主件和附件的搭配都是唯一的,也就是每种方案都是互斥的。好比最多那五种情况,我们就可以分成一组。然后进行分组背包即可。那么我们分组的时候,可以考虑到一个优化,也就是如果他们的体积相同,我们只需要选价值大的那个就可以啦。所以我们先对主件和附件这个集合,进行01背包,然后背出来相同体积下最大价值的方案,分到对应组里。这个思路对于附件也有附件的情况,就不好写了,不能直接01背包。 第三种思路可以应对附件也有附件的情况,可以用森林来表示所有物品之间的关系,然后树上dp做。然而,我不会。QAQ\u0026hellip; 代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=32005; const int maxm=65; int n,m; int num[maxm]; struct Item { int v,p,q; }item[maxm],minor[maxm][maxm]; int dp[maxn],cnt[maxm]; int vi[maxm][maxm],pi[maxm][maxm]; int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;m); for(int i=1;i\u0026lt;=m;i++) { scanf(\u0026#34;%d%d%d\u0026#34;,\u0026amp;item[i].v,\u0026amp;item[i].p,\u0026amp;item[i].q); if(item[i].q) { num[item[i].q]++; minor[item[i].q][num[item[i].q]].v=item[i].v; minor[item[i].q][num[item[i].q]].p=item[i].v*item[i].p; } } for(int i=1;i\u0026lt;=m;i++) { if(num[i]) { memset(dp,-1,sizeof(dp)); dp[0]=0; for(int j=1;j\u0026lt;=num[i];j++) { for(int k=n-item[i].v;k\u0026gt;=minor[i][j].v;k--) { if(dp[k-minor[i][j].v]!=-1) { dp[k]=max(dp[k],dp[k-minor[i][j].v]+minor[i][j].p);\t} } } for(int k=0;k\u0026lt;=n-item[i].v;k++) { if(dp[k]!=-1) { cnt[i]++; vi[i][cnt[i]]=k+item[i].v; pi[i][cnt[i]]=dp[k]+item[i].v*item[i].p; } } } if(!item[i].q) { cnt[i]++; vi[i][cnt[i]]=item[i].v; pi[i][cnt[i]]=item[i].v*item[i].p; } } memset(dp,0,sizeof(dp)); for(int i=1;i\u0026lt;=m;i++) { if(!cnt[i]) continue; for(int j=n;j\u0026gt;=0;j--) { for(int k=1;k\u0026lt;=cnt[i];k++) { if(j\u0026gt;=vi[i][k]) { dp[j]=max(dp[j],dp[j-vi[i][k]]+pi[i][k]); } } } } //\tint ans; //\tfor(int i=1;i\u0026lt;=n;i++) ans=max(ans,dp[i]); printf(\u0026#34;%d\u0026#34;,dp[n]); return 0; } 3. 多米诺骨牌(隐式背包) 题意 多米诺骨牌有上下两个部分,分别具有一定点数。所有多米诺骨牌上部分点数之和与下部分点数之和差的绝对值为 $x$ ,多米诺骨牌可以进行上下翻转,问当 $x$ 最小的时候最少翻转几次。\n思路 害,本来好像没有隐式背包这个说法,我自己瞎起的名字。。其实就是没那么裸的背包,实际上转化一下还是道背包的题。这道题本来其实看起来和背包没有什么关系,但是实际想一想,假如我们把所有多米诺骨牌一开始都调成上面大下面小的情况,然后调整过的把他的消耗值设为-1,没有调整过的把消耗值设为1。达成上大下小目的需要消耗的次数为n。调整后的上下点数差为V。我们每次调整之后 $V$ 会减少牌的上下点数之差,这就是我们需要的体积。然后一开始把 $dp[V]$ 设为n。然后转移方程为 $dp[i]=min(dp[i],dp[i+v[i]]+w[i]) $ 最后只需要求从 $0\\sim V$ 最小的那个点数差对应的翻转次数值就可以了。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=1005; int ini; int n; int up[maxn],down[maxn]; int v[maxn],w[maxn]; int dp[10005]; int V; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;up[i],\u0026amp;down[i]); if(up[i]\u0026gt;=down[i]) { V+=up[i]-down[i]; v[i]=(up[i]-down[i])*2; w[i]=1; } else { V+=down[i]-up[i]; ini++; v[i]=(down[i]-up[i])*2; w[i]=-1; } } for(int i=0;i\u0026lt;=V;i++) dp[i]=233333; //\tdp[V]=ini; dp[V]=ini; for(int i=1;i\u0026lt;=n;i++) { for(int j=0;j\u0026lt;=V-v[i];j++) { if(dp[j+v[i]]!=233333) dp[j]=min(dp[j],dp[j+v[i]]+w[i]); } } for(int i=0;i\u0026lt;=V;i++) { if(dp[i]!=233333) { printf(\u0026#34;%d\u0026#34;,dp[i]); break; } } return 0; } ","permalink":"https://blog.zzsqwq.cn/posts/21/","summary":"\u003ch3 id=\"1-分组背包httpswwwluogucomcnproblemp1757\"\u003e1. \u003ca href=\"https://www.luogu.com.cn/problem/P1757\"\u003e分组背包\u003c/a\u003e\u003c/h3\u003e\n\u003chr\u003e\n\u003ch4 id=\"题意\"\u003e题意\u003c/h4\u003e\n\u003cp\u003e在01背包基础上,将其中的物体分成 $k$ 组,每组内的物品相互冲突,即只能取其中一个,问最大价值。\u003c/p\u003e","title":"背包进阶"},{"content":"前言 今天跟着背包九讲把背包再学习一下,dd_engi大佬的背包九讲Github链接: 背包九讲\n1. 采药(01背包) 题意 有 $n$ 个价值为 $w_i$ ,体积为 $v_i$ 的物品,装入体积为 $V$ 的背包中,问能获得的最大为多少。\n思路 首先我们可以用 $f[i][j]$ 来定义前 $i$ 个物品放入体积为 $j$ 的背包中能获得最大体积,对于每一个物品,我们可以分两种情况来讨论,分别是装和不装,然后取他们两个的最大值。已经正确的定义了状态,转移方程就不难写出来了,是 $f[i][j]=max(f[i-1][j],f[i-1][j-v[i]]+w[i])$ ,然后推的话就直接外层循环物品,内层循环体积递推即可。最后 $f[n][V]$ 就是我们需要的答案。\n但是看了大佬们的题解,他们说,空间复杂度还可以再优化,那么我们可以看看如果优化的话,肯定是不能去掉体积那一维的,所以就是去掉第几个物品那一维。所以从 $f[i][j]$ 变成了 $f[j]$ 。那么我们想想,当我们推第 $i$ 个物体的状态的时候,我们需要已知第 $i-1$ 个的状态,我们物体循环是 $1\\sim n$ 那么肯定 $f[i][j]$ 一开始对应的是 $f[i-1][j]$ ,那么如果顺推体积 $0\\sim V$ 的话我们可以发现,当我们推 $f[i][j]$ 需要状态 $f[i-1][j-v[i]]$ 的时候,这时候如果直接调用 $f[j-v[i]]$ 对应的是 $f[i][j-v[i]]$ 也就是说,这不是我们需要的结果,这时候的状态可能已经取过一次i了,那么我们就可以逆推体积 $V\\sim c[i]$ ,这样我们调用 $f[j-v[i]]$ 就刚好对应的是没取过 $i$ 的情况了!最后推出来 $f[V]$ 就是对应的答案了!\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=105; int t,m; int f[1005]; int a[maxn],b[maxn]; int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;t,\u0026amp;m); for(int i=1;i\u0026lt;=m;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;a[i],\u0026amp;b[i]); } for(int i=1;i\u0026lt;=m;i++) { for(int j=t;j\u0026gt;=a[i];j--) { f[j]=max(f[j],f[j-a[i]]+b[i]); } } printf(\u0026#34;%d\u0026#34;,f[t]); return 0; } 2. 疯狂的采药(完全背包) 题意 有 $n$ 种价值为 $w_i$ ,体积为 $v_i$ 的物品,每一种物品有无数个,装入体积为 $V$ 的背包中,问能获得的最大为多少。\n思路 那么很显然我们可以把一个它转化成 $\\sum_{i=1}^n \\lfloor{\\frac{V}{v_i}}\\rfloor$ 个物品的01背包,也可以在取每个物体的时候循环 $\\lfloor{\\frac{V}{v_i}}\\rfloor$ 次,但是我们可以思考对上述01背包的优化,我们发现如果顺着取,刚好对应的就是我们需要的状态,也就是说我们只需要将 $V$ 的循环正过来就可以了!\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=100005; int t,m; int f[100005]; int a[maxn],b[maxn]; int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;t,\u0026amp;m); for(int i=1;i\u0026lt;=m;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;a[i],\u0026amp;b[i]); } for(int i=1;i\u0026lt;=m;i++) { for(int j=a[i];j\u0026lt;=t;j++) { f[j]=max(f[j],f[j-a[i]]+b[i]); } } printf(\u0026#34;%d\u0026#34;,f[t]); return 0; } 3. 宝物筛选(多重背包) 题意 有 $N$ 种物品和一个容量为 $V$ 的背包。第 $i$ 种物品最多有 $m_i$ 件可用,每件耗费的空间是 $v_i$,价值是 $w_i$ 。求解将哪些物品装入背包可使这些物品的耗费的空间总和不超过背包容量,且价值总和最大。\n思路 那么这道题裸的做法就是对于转移 $f[v]$ 这个方程的时候,考虑取多少个物品,可以取一个,可以取两个,在不超过体积情况下最多取 $m[i]$ 个,转移方程 $f[v]=max(f[v],f[v-k*v[i]])\\quad k\\in[1,m_i]$ 。那么这样其实时间复杂度还是很高的,所以大佬们给出了优化方案\n第一种就是把 $m_i$ 个物品进行二进制拆分,把他们拆成 $1$,$2^1$,$2^2$ ····等等,一直拆到不能再拆,这样我们就能够将 $m_i$ 个物品拆成 $log(m_i)$ 个物品,但是他们还是能够表示出所有的情况。然后就继续01背包背一下就可以了。 单调队列优化,我不会,我太菜了。。 代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; using namespace std; int n,m,ans,cnt; int a,b,c; const int maxn=1000005; int f[maxn]; int w[maxn],v[maxn]; int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;m); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d%d%d\u0026#34;,\u0026amp;a,\u0026amp;b,\u0026amp;c); for(int j=1;j\u0026lt;=c;j*=2) //二进制拆分 { v[++cnt]=j*a; w[cnt]=j*b; c-=j; } if(c) { v[++cnt]=a*c; w[cnt]=b*c; } } for(int i=1;i\u0026lt;=cnt;i++) { for(int j=m;j\u0026gt;=w[i];j--) { f[j]=max(f[j],f[j-w[i]]+v[i]); } } printf(\u0026#34;%d\\n\u0026#34;,f[m]); return 0; } ","permalink":"https://blog.zzsqwq.cn/posts/20/","summary":"\u003ch3 id=\"前言\"\u003e前言\u003c/h3\u003e\n\u003cp\u003e今天跟着背包九讲把背包再学习一下,dd_engi大佬的背包九讲Github链接: \u003ca href=\"https://github.com/tianyicui/pack\"\u003e背包九讲\u003c/a\u003e\u003c/p\u003e\n\u003chr\u003e\n\u003ch3 id=\"1-采药01背包httpswwwluogucomcnproblemp1048\"\u003e1. \u003ca href=\"https://www.luogu.com.cn/problem/P1048\"\u003e采药(01背包)\u003c/a\u003e\u003c/h3\u003e\n\u003chr\u003e\n\u003ch4 id=\"题意\"\u003e题意\u003c/h4\u003e\n\u003cp\u003e有 $n$ 个价值为 $w_i$ ,体积为 $v_i$ 的物品,装入体积为 $V$ 的背包中,问能获得的最大为多少。\u003c/p\u003e","title":"一些关于背包的题"},{"content":"1. 石子归并 题意 $N$ 堆石子摆成一条线。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价。计算将 $N$ 堆石子合并成一堆的最小代价。 思路 很经典的区间dp例题,我们可以用 $dp[i][j]$ 来表示合并 $i\\sim j$ 所需的最小代价,通过枚举中间的断点,来通过方程 $dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+cost[i][j])$ ,其中 $cost[i][j]$ 表示从 $i\\sim j$ 的石子总数,通过前缀和很容易计算。在进行状态转移时需要前面状态已知,因为是枚举中间断点,所以断开区间的长度一定要小于原区间,因此在转移之前需要确保比他短的区间都已经达到了最小代价,因此我们可以通过枚举区间长度从 $2\\sim N$ 来实现。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int inf=1000005; const int maxn=105; int n; int sum[maxn],a[maxn]; int dp[maxn][maxn]; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;a[i]); sum[i]=sum[i-1]+a[i]; } for(int i=1;i\u0026lt;=n;i++) dp[i][i]=0; for(int p=2;p\u0026lt;=n;p++) { for(int i=1;i\u0026lt;=n-p+1;i++) { int j=i+p-1; dp[i][j]=inf; for(int k=i;k\u0026lt;j;k++) { dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]); } } } printf(\u0026#34;%d\u0026#34;,dp[1][n]); return 0; } 2. P1880 [NOI1995]石子合并 题意 $N$ 堆石子摆成一个环。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价。计算将 $N$ 堆石子合并成一堆的最小代价和最大代价。\n思路 这个题和上个题只有两个地方不同,一个是从线到环,一个是同时求最大和最小代价。害,其实这样也没变什么东西,也是跟上面一样,枚举区间长度和切割点。我们可以把一个环想象成一个链,如果这个环是由 N 个元素构成,那么这个链就由 N+N 个元素构成,这么这样就能确保你每次枚举区间的时候能取到合法的值,好比你要可以合并最后一个和第一个,那么就是对应的 $dp[n][n]+dp[n+1][n+1]+cost[n][n+1]$ 。不过这样最后寻找答案的时候肯定不只是 $dp[i][n]$ 了,你要从 $dp[1][n]\\sim dp[n][n*2]$ 中寻找最优的答案。同时求最大和最小代价就直接开两个数组记录就可以了。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int inf=1000005; const int maxn=105; int n; int sum[maxn\u0026lt;\u0026lt;1],a[maxn\u0026lt;\u0026lt;1]; int ansmax,ansmin=12345678; int dp[maxn\u0026lt;\u0026lt;1][maxn\u0026lt;\u0026lt;1],f[maxn\u0026lt;\u0026lt;1][maxn\u0026lt;\u0026lt;1]; //later is max , fromer is min int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;a[i]); a[i+n]=a[i]; sum[i]=sum[i-1]+a[i]; } for(int i=n+1;i\u0026lt;=2*n;i++) { sum[i]=sum[i-1]+a[i]; } for(int i=1;i\u0026lt;=n*2;i++) dp[i][i]=f[i][i]=0; for(int p=2;p\u0026lt;=n;p++) { for(int i=1;i\u0026lt;=2*n-p+1;i++) { int j=i+p-1; dp[i][j]=inf; for(int k=i;k\u0026lt;j;k++) { dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]); f[i][j]=max(f[i][j],f[i][k]+f[k+1][j]+sum[j]-sum[i-1]); } } } for(int i=1;i\u0026lt;=n;i++) ansmax=max(ansmax,f[i][i+n-1]); for(int i=1;i\u0026lt;=n;i++) ansmin=min(ansmin,dp[i][i+n-1]); printf(\u0026#34;%d\\n%d\u0026#34;,ansmin,ansmax); return 0; } 3. P1140 相似基因 题意 有 $A : T :C : G $ 四种碱基,他们之间可以两两配对,特殊的,一个碱基也可以和空碱基配对,但是空碱基和空碱基配对是不被允许的,当不同的碱基间两两配对时,会具有一定的相似度,问给定两段序列 $s$,$t$ 能获得的最大相似度是多少。\n碱基配对时相似度的定义如下 A C G T 空 A 5 -1 -2 -1 -3 C -1 5 -3 -2 -4 G -2 -3 5 -2 -2 T -1 -2 -2 5 -1 空 -3 -4 -2 -1 非法 思路 首先用一个二维数组来存储对应的相似值表。因为对应的两段序列,我感觉这种题一般都是用 $dp[i][j]$ 来表示第一段序列从 $1\\sim i$ 对应第二段序列 $1\\sim j$ 所能获得的最大相似度,那么思考一下状态转移。\n首先可以是碱基对空碱基,这时候 $s$ 要匹配碱基,$t$ 中匹配空碱基,这样的话就从应该从 $dp[i-1][j] $转移过来,对应的转移方程为 $dp[i][j]=max(dp[i][j],dp[i-1][j]+map[s[i]][blank])$\n也可以是空碱基对碱基,对应的转移方程为$dp[i][j]=max(dp[i][j],dp[i][j-1]+map[blank][t[j]])$\n也可以是碱基对碱基,对应的转移方程为$dp[i][j]=max(dp[i][j],dp[i-1][j-1]+map[s[i]][t[j]])$\n害,想到这里我又突然懵逼了,我在想是否能确保两个序列所有的碱基都被用到,仔细想想确实是可以的,因为状态定义的就是用了前 $i$ 个碱基和前 $j$ 个碱基所获得的最大相似度。最后我们就处理一下边界就可以了,边界我们可以发现是 $dp[i][0]$ 和 $dp[0][i]$ ,这就是可以对应着空碱基和相应 $s[i]$ 和 $t[i]$ 的碱基,因此只需要用循环依次转移一遍就可以了。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int inf=1000005; const int maxn=105; int n,m; int a[maxn],b[maxn]; char s[maxn],c[maxn]; int dp[maxn][maxn]; const int map[5][5]={{5,-1,-2,-1,-3}, {-1,5,-3,-2,-4}, {-2,-3,5,-2,-2}, {-1,-2,-2,5,-1}, {-3,-4,-2,-1,0}}; //A 0 C 1 G 2 T 3 blank 4 int main() { scanf(\u0026#34;%d%s%d%s\u0026#34;,\u0026amp;n,s+1,\u0026amp;m,c+1); for(int i=1;i\u0026lt;=n;i++) { if(s[i]==\u0026#39;A\u0026#39;) a[i]=0; if(s[i]==\u0026#39;C\u0026#39;) a[i]=1; if(s[i]==\u0026#39;G\u0026#39;) a[i]=2; if(s[i]==\u0026#39;T\u0026#39;) a[i]=3; } for(int i=1;i\u0026lt;=m;i++) { if(c[i]==\u0026#39;A\u0026#39;) b[i]=0; if(c[i]==\u0026#39;C\u0026#39;) b[i]=1; if(c[i]==\u0026#39;G\u0026#39;) b[i]=2; if(c[i]==\u0026#39;T\u0026#39;) b[i]=3; } for(int i=1;i\u0026lt;=n;i++) dp[i][0]=dp[i-1][0]+map[a[i]][4]; for(int i=1;i\u0026lt;=m;i++) dp[0][i]=dp[0][i-1]+map[4][b[i]]; for(int i=1;i\u0026lt;=n;i++) { for(int j=1;j\u0026lt;=m;j++) { dp[i][j]=-inf; dp[i][j]=max(dp[i][j],dp[i][j-1]+map[4][b[j]]); dp[i][j]=max(dp[i][j],dp[i-1][j]+map[a[i]][4]); dp[i][j]=max(dp[i][j],dp[i-1][j-1]+map[a[i]][b[j]]); } } printf(\u0026#34;%d\u0026#34;,dp[n][m]); return 0; } ","permalink":"https://blog.zzsqwq.cn/posts/19/","summary":"\u003ch3 id=\"1-石子归并httpswww51nodcomchallengeproblemhtmlproblemid1021\"\u003e1. \u003ca href=\"https://www.51nod.com/Challenge/Problem.html#problemId=1021\"\u003e石子归并\u003c/a\u003e\u003c/h3\u003e\n\u003chr\u003e\n\u003ch4 id=\"题意\"\u003e题意\u003c/h4\u003e\n\u003cpre\u003e\u003ccode\u003e$N$ 堆石子摆成一条线。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价。计算将 $N$ 堆石子合并成一堆的最小代价。\n\u003c/code\u003e\u003c/pre\u003e\n\u003chr\u003e\n\u003ch4 id=\"思路\"\u003e思路\u003c/h4\u003e\n\u003cp\u003e很经典的区间dp例题,我们可以用 $dp[i][j]$ 来表示合并 $i\\sim j$ 所需的最小代价,通过枚举中间的断点,来通过方程 $dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+cost[i][j])$ ,其中 $cost[i][j]$ 表示从 $i\\sim j$ 的石子总数,通过前缀和很容易计算。在进行状态转移时需要前面状态已知,因为是枚举中间断点,所以断开区间的长度一定要小于原区间,因此在转移之前需要确保比他短的区间都已经达到了最小代价,因此我们可以通过枚举区间长度从 $2\\sim N$ 来实现。\u003c/p\u003e","title":"基础线性dp例题 #2"},{"content":"前言 某位大佬曾经说过,dp不会没问题,想不到状态转移方程没问题,多做题就会了。所以,我打算多刷点dp题。那么,先从基础刷起吧。\n1. P1091 合唱队形 题意 已知序列 $a$ 有 $n$ 个数,通过取出其中一些数可以使他满足严格的先增再减序列,问最少取出几个。\n思路 很显然想要求最少取出几个,我们就看严格先增再减的序列的最长长度即可。我们可以用 $g[i]$ 来存储到 $a[i]$ 为止的最长递增子序列的长度,然后用 $l[i]$ 来存储从 $a[i]$ 到序列末尾最长的递减子序列的长度。处理 $g[i]$ 从前往后扫,处理 $l[i]$ 需要从后往前扫。处理完 $f$ 和 $g$ 数组那么就从左到右扫一遍,$ans=max(ans,g[i]+l[i]-1)$ 。答案即是 $n-ans$ 。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; #include\u0026lt;cstring\u0026gt; using namespace std; const int maxn=105; int n; int a[maxn],g[maxn],l[maxn]; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;a[i]); } for(int i=1;i\u0026lt;=n;i++) { for(int j=0;j\u0026lt;i;j++) { if(a[i]\u0026gt;a[j]) g[i]=max(g[i],g[j]+1); } } for(int i=n;i\u0026gt;=1;i--) { for(int j=n+1;j\u0026gt;i;j--) { if(a[i]\u0026gt;a[j]) l[i]=max(l[i],l[j]+1); } } int maxout=0; for(int i=1;i\u0026lt;=n;i++) { maxout=max(maxout,g[i]+l[i]-1); } printf(\u0026#34;%d\u0026#34;,n-maxout); return 0; } 2. P1280 尼克的任务 题意 尼克的一个工作日为 $n$ 分钟,从第一分钟开始到第 $n$ 分钟结束。当尼克到达单位后他就开始干活。如果在同一时刻有多个任务需要完成,尼克可以任选其中的一个来做,而其余的则由他的同事完成,反之如果只有一个任务,则该任务必需由尼克去完成,假如某些任务开始时刻尼克正在工作,则这些任务也由尼克的同事完成。如果某任务于第 $p$ 分钟开始,持续时间为 $t$ 分钟,则该任务将在第 $p+t-1$ 分钟结束。(实在不会总结题意,就直接复制过来了)\n思路 我们可以设 $f[i]$ 为时间从 $i\\sim n$ 所能获得最长空闲时间,最终 $f[1]$ 对应的就是答案。假设在这个 $i$ 分钟有 $k[i]$ 个任务可以,那么我们可以分以下情况转移\n$k[i]=0$ , 那么 $f[i]=f[i+1]+1$\n$k[i]\\not=0$ ,那么可以循环 $1 \\sim k[i]$ 遍历这个时间点开始的任务,$f[i]=max(f[i],f[i+k[i].t])$\n思路是这样的,但是我们记录 $k[i].t$ 并不好记录,因此我们可以先将任务开始时间按降序排序,用一个一个变量 $cnt$ 来代表已经取到第几个任务了,那么这样一直取下去,最终就能够遍历所有的任务。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=10005; struct task { int l,r; }t[maxn]; int cmp(struct task a,struct task b) { return a.l\u0026gt;b.l; } int dp[maxn]; int p[maxn]; int cnt=1,n,k; int main() { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;k); for(int i=1;i\u0026lt;=k;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;t[i].l,\u0026amp;t[i].r); p[t[i].l]++; } sort(t+1,t+1+k,cmp); for(int i=n;i\u0026gt;=1;i--) { if(!p[i]) { dp[i]=dp[i+1]+1; } else { for(int j=1;j\u0026lt;=p[i];j++) { dp[i]=max(dp[i],dp[i+t[cnt].r]); cnt++; } } } printf(\u0026#34;%d\\n\u0026#34;,dp[1]); return 0; } 我太懒了····就写了两道,明天继续加油吧。。\n","permalink":"https://blog.zzsqwq.cn/posts/18/","summary":"\u003ch3 id=\"前言\"\u003e前言\u003c/h3\u003e\n\u003chr\u003e\n\u003cp\u003e某位大佬曾经说过,dp不会没问题,想不到状态转移方程没问题,多做题就会了。所以,我打算多刷点dp题。那么,先从基础刷起吧。\u003c/p\u003e\n\u003ch3 id=\"1-p1091-合唱队形httpswwwluogucomcnproblemp1091\"\u003e1. \u003ca href=\"https://www.luogu.com.cn/problem/P1091\"\u003eP1091 合唱队形\u003c/a\u003e\u003c/h3\u003e\n\u003chr\u003e\n\u003ch4 id=\"题意\"\u003e题意\u003c/h4\u003e\n\u003cp\u003e已知序列 $a$ 有 $n$ 个数,通过取出其中一些数可以使他满足严格的先增再减序列,问最少取出几个。\u003c/p\u003e\n\u003chr\u003e","title":"基础线性dp例题"},{"content":"A. Array with Odd Sum 题意 给出包含 n 个正整数的序列 a ,你可以把任何一个元素 $a_i$ ,赋值给另一个元素 $a_j$ ($i\\neq j$) ,问通过任意此操作能否将序列 a 的和变为奇数。可以输出 YES ,不可以输入 NO.\n思路 首先当起始和为奇数的时候,就直接可输出 YES 了,如果是偶数的话,我们可以发现,如果序列元素中同时包含奇数和偶数,那么就是可以的,否则不可以。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; using namespace std; int t,n,flag,sum,p,flag1,flag2; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { flag=false; flag2=flag1=false; sum=0; scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;p); sum+=p; if(p%2==1) flag1=true; if(p%2==0) flag2=true; } if(flag1\u0026amp;\u0026amp;flag2) flag=true; if(sum%2==1) printf(\u0026#34;YES\\n\u0026#34;); else { if(flag) printf(\u0026#34;YES\\n\u0026#34;); else printf(\u0026#34;NO\\n\u0026#34;); } } } B. Food Buying 题意 初始有 s 个货币,每次花费 x 个货币会返还 $\\lfloor{\\frac{x}{10}}\\rfloor$ 个货币,问最多共能花费多少货币。\n思路 贪心即可。剩余的货币一直除10累加,注意最终剩余不足10的处理。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; using namespace std; int t,s; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;s); { int p=s; int now=0; while(p) { if(p\u0026lt;10) break; now=p/10; s+=now; p%=10; p+=now; } } printf(\u0026#34;%d\\n\u0026#34;,s); } } C. Yet Another Walking Robot 题意 一个机器人初始在 $(0,0)$ 点,规定 \u0026lsquo;L\u0026rsquo; ,\u0026lsquo;R\u0026rsquo; ,\u0026lsquo;U\u0026rsquo; ,\u0026lsquo;D\u0026rsquo; 分别对应向左,向右,向上和向下。给定一段包含上述字母的序列 s ,机器人遵循指引序列移动。如果删除一段连续序列可使得机器人最终到达终点不变,问删除的最短序列的起始和终点为多少。\n思路 想了半天想了错误的解法。。一直在考虑 L 和 R 数相等,U 和 D 相等,通过这个方法来找序列。看了题解才发现是通过坐标来看。我们可以开一个map记录坐标和步数的关系,从左到右扫序列,如果没有到达过这个坐标,就记录当前是第几次移动到达这个坐标的,如果到达过的话,就看上一次到达这个坐标时的步数,计算他们的序列长度,如果小于计算的就更新答案。因为是需要找最小的,因此只需要记录上一次到达的步数即可。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;map\u0026gt; using namespace std; const int maxn=200005; int t,n; char s[maxn]; bool flag; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); int l=-1,r=n; scanf(\u0026#34;%s\u0026#34;,s+1); pair\u0026lt;int,int\u0026gt; pos; //first为x second为y map\u0026lt;pair\u0026lt;int,int\u0026gt;,int\u0026gt; last; pos.first=pos.second=0; last[pos]=0; for(int i=1;i\u0026lt;=n;i++) { if(s[i]==\u0026#39;L\u0026#39;) pos.first--; if(s[i]==\u0026#39;R\u0026#39;) pos.first++; if(s[i]==\u0026#39;U\u0026#39;) pos.second++; if(s[i]==\u0026#39;D\u0026#39;) pos.second--; /*\tif(i==2) { printf(\u0026#34;%d %d\\n\u0026#34;,pos.first,pos.second); } */\tif(last.count(pos)!=0) { int p=i-last[pos]; //\tif(i==2) printf(\u0026#34;%d %d\\n\u0026#34;,i,last[pos]); if(p\u0026lt;r-l) { l=last[pos]; r=i;\t}\t//\tif(i==2 )printf(\u0026#34;%d %d\\n\u0026#34;,l,r); } last[pos]=i; } if(l==-1) { printf(\u0026#34;-1\\n\u0026#34;); } else { printf(\u0026#34;%d %d\\n\u0026#34;,l+1,r); } } return 0; } D. Fight with Monsters 题意 由你先手和对手轮流击打 $n$ 个血量为 $h_i$ 的小怪兽,你可以对怪物造成 $a$ 点伤害,对手可以造成 $b$ 点伤害。你有 $k$ 次机会使对手跳过他的回合。当小怪兽血量 $h\\le0$ 时视为被击杀,当你击杀怪兽,你获得一分,当对手击杀,你不得分。求你最多能获得多少分数。\n思路 先看一下对于每个怪兽我们要击杀需要花费多少机会,你和对手一个回合会击杀怪兽 $a+b$ 点血量,因此你可以一直将回合进行到怪兽血量小于$a+b$,接下来我们可以分两种情况讨论。\n怪兽血量为0,那么我们就需要回溯对手最后一个回合,然后需要使用的机会就是 $\\lceil\\frac{h_i}{a}\\rceil$ 次\n怪兽血量不为0,我们需要使用的机会就是 $\\lceil\\frac{h_i}{a}\\rceil-1$ 次,注意这里不能直接写 $\\lfloor\\frac{h_i}{a}\\rfloor$ 次,因为如果 $h_i$ 刚好能被 $a$ 整除,后面这个写法就错了。\n计算出了每个怪兽需要花费的机会那么就好做了,就变成了一个贪心问题,我们去尽可能得击杀需要的机会少的,当机会消耗完毕,得到的就是答案了。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=200005; int n,a,b,k; int f[maxn]; int cmp(int a,int b) { return a\u0026lt;b; } int h[maxn],ans; int main() { scanf(\u0026#34;%d%d%d%d\u0026#34;,\u0026amp;n,\u0026amp;a,\u0026amp;b,\u0026amp;k); int p=a+b; for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;h[i]); h[i]%=p; if(h[i]==0) { h[i]+=b; f[i]=ceil((double)h[i]/a); } else f[i]=ceil((double)h[i]/a)-1; } sort(f+1,f+1+n,cmp); for(int i=1;i\u0026lt;=n;i++) { if(k-f[i]\u0026lt;0) break; ans++; k-=f[i]; } printf(\u0026#34;%d\\n\u0026#34;,ans); } ","permalink":"https://blog.zzsqwq.cn/posts/17/","summary":"\u003ch3 id=\"a-array-with-odd-sumhttpscodeforcescomcontest1296problema\"\u003eA. \u003ca href=\"https://codeforces.com/contest/1296/problem/A\"\u003eArray with Odd Sum\u003c/a\u003e\u003c/h3\u003e\n\u003chr\u003e\n\u003ch4 id=\"题意\"\u003e题意\u003c/h4\u003e\n\u003cp\u003e给出包含 \u003cstrong\u003en\u003c/strong\u003e 个正整数的序列 \u003cstrong\u003ea\u003c/strong\u003e ,你可以把任何一个元素 $a_i$ ,赋值给另一个元素 $a_j$ ($i\\neq j$) ,问通过任意此操作能否将序列 \u003cstrong\u003ea\u003c/strong\u003e 的和变为奇数。可以输出 \u003cstrong\u003eYES\u003c/strong\u003e ,不可以输入 \u003cstrong\u003eNO\u003c/strong\u003e.\u003c/p\u003e\n\u003chr\u003e\n\u003ch4 id=\"思路\"\u003e思路\u003c/h4\u003e\n\u003cp\u003e首先当起始和为奇数的时候,就直接可输出 \u003cstrong\u003eYES\u003c/strong\u003e 了,如果是偶数的话,我们可以发现,如果序列元素中同时包含奇数和偶数,那么就是可以的,否则不可以。\u003c/p\u003e","title":"Codeforces#617(Div.3)"},{"content":"1. P1378 油滴扩展 题意 在长方形框中,最多有 n ($0\\le{n}\\le6$)个相异点,在框中点上依次放置可扩展的油滴,当碰到其他油滴边界或者长方形边框时会停止,扩展呈圆形展开。放置下一个时会确保上一个已经扩展完成。问通过变换放置顺序可使得最终框中剩下的面积最小为多少。\n思路 这是个裸的dfs,情况最多也就 $6! = 720$ 种,所以我们可以只需要设置一个vis数组来记录是否已经放置过这个油滴,计算已扩展油滴和将要放的油滴之间的距离可以用 两点距离-扩展油滴的半径来实现 ,但是有个坑需要注意,就是当一个油滴已经放在已经有扩展油滴覆盖的区域,那么他俩的距离是0,而不是负数,因此在计算半径的时候需要优化一下。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; #define pi 3.1415926 using namespace std; const int maxn=10; int n,x,y,xx,yy; double rx[maxn]; double maxans; bool vis[maxn]; int dx[maxn],dy[maxn]; double diss(int x1,int y1,int x2,int y2) //计算两点距离 { return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } double radius(int p) //计算半径 { double ans=min(abs(dx[p]-x),min(abs(dy[p]-y),min(abs(dx[p]-xx),abs(dy[p]-yy)))); for(int i=1;i\u0026lt;=n;i++) { if(vis[i]\u0026amp;\u0026amp;i!=p) { double dis=diss(dx[i],dy[i],dx[p],dy[p]); ans=min(ans,max(dis-rx[i],0.0)); } } return ans; } void dfs(int nowcnt,double area) //area为拓展总面积 nowcnt为现在已经放置了几个 { if(nowcnt==n) { maxans=max(maxans,area); return ; } for(int i=1;i\u0026lt;=n;i++) { if(!vis[i]) { vis[i]=true; rx[i]=radius(i); dfs(nowcnt+1,area+pi*rx[i]*rx[i]); rx[i]=0; vis[i]=false; } } } int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); scanf(\u0026#34;%d%d%d%d\u0026#34;,\u0026amp;x,\u0026amp;y,\u0026amp;xx,\u0026amp;yy); double sum=abs(x-xx)*abs(y-yy); //矩形总面积 for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;dx[i],\u0026amp;dy[i]); } dfs(0,0.0); printf(\u0026#34;%0.0lf\u0026#34;,sum-maxans); return 0; } 2. P1120 小木棍 题意 将一些长度为 x 的等长木棍全部切成 n 段不超过50的小木棍,求长木棍长度 x 的最小长度。\n思路 首先这个题是有个坑的,题目给出来了,输入的小木棍长度可能会有大于50的,因此我们需要筛掉它。\n那么很显然这个题是一道搜索题,我们可以写搜索函数dfs(int nowcnt,int nxt,int lenlast,int len).上述参数分别表示: 现在在寻找第几根小木棍,我们寻找下一个拼接段应该从哪里开始找,当前这根拼接还需要多长,以及我们要拼成多长的木棍。搜索的复杂度这么高,对于 $n\\le65$ 的数据肯定不能直接无脑搜,因此需要想想怎么优化。\n首先要从大到小排序这个很关键的,因为你从大的先凑就能够保证后面选择的时候容错率更高一些。\n很显然我们可以剪掉当 lenlast\u0026lt;0 的情况,这个地方我们可以在拼接的时候就判断,也可以在拼接后判断。\n在寻找下一个拼接片段的时候,我们可以通过二分搜索来查找下一个不超过lenlast的片段,我选择了直接用STL的库中的lower_bound函数。(其实因为是我的二分总是写炸)\n再就是我们对于相等片段的处理,很显然当前片段不符合情况那么与他等长的也都不会符合,因此我们可以直接循环筛掉。当然更优的方法可以提前处理一个跳表,直接跳到下一个与他不同的位置。\n最后这个优化还是挺难想的,就是如果当前片段搜下去已经不符合情况,但是当前的lenlast是等于当前片段长度的,也就是说你正好用了尽可能满足条件的一个方案,也还是没达到目的,你们你继续往下搜,用比他还要劣的方案肯定也是不可能的,因此直接就break跳出循环不需要往下搜了。\n不过就算加了这么多优化我还是T了三个点,直接 O2一开跑路了嘿嘿\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=70; int n,a[maxn],temp,icnt=1; int totlen,maxlen,cnt; bool vis[maxn],finish; int cmp(int a,int b) { return a\u0026gt;b; } void dfs(int nowcnt,int nxt,int lenlast,int len) //nowcnt:现在正在拼接第几根 //nxt:我们应该从哪里开始检索 //lenlast:现在拼接还需要多少才能拼接完成 //len:每根木棍的理想长度 { if(lenlast\u0026lt;0) return; if(lenlast==0) { //\tprintf(\u0026#34;test\\n\u0026#34;); if(nowcnt==cnt) { printf(\u0026#34;%d\\n\u0026#34;,len); finish=true; return ; } int p=1; for(p=1;p\u0026lt;=n;p++) if(!vis[p]) break; vis[p]=true; dfs(nowcnt+1,p+1,len-a[p],len); if(finish) return ; vis[p]=false; } else { int pos=lower_bound(a+nxt,a+1+n,lenlast,greater\u0026lt;int\u0026gt;())-a; for(int i=pos;i\u0026lt;=n;i++) { //\tprintf(\u0026#34;what\\n\u0026#34;); if(!vis[i]\u0026amp;\u0026amp;lenlast-a[i]\u0026gt;=0) { vis[i]=true; dfs(nowcnt,i+1,lenlast-a[i],len); if(finish) return; vis[i]=false; while(a[i+1]==a[i]) i++; if(i==n) return; if(lenlast-a[i]==0) break; } } } } int main() { //\tfreopen(\u0026#34;test.in\u0026#34;,\u0026#34;r\u0026#34;,stdin); scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); for(int i=1;i\u0026lt;=n;i++) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;temp); if(temp\u0026gt;50) a[i]=0; else a[i]=temp; maxlen=max(maxlen,a[i]); totlen+=a[i]; } sort(a+1,a+1+n,cmp); while(!a[n]) n--; for(int l=maxlen;l\u0026lt;=totlen;l++) { finish=false; if(totlen%l!=0) continue; cnt=totlen/l; vis[1]=true; dfs(1,2,l-a[1],l); vis[1]=false; if(finish) return 0; } return 0; } 3. YOKOF - Power Calculus 题意 给出一个正整数 n ,只能使用乘法或者除法,可以乘除 $x$ 或者过程中产生的中间值 $x^i$ ,输出使得 $x$ 变为 $x^n$ 所需的最少步数。$(n\\le100)$\n思路 很显然我们一直是对指数进行操作,看似是乘除,直接转化为指数的加减。因此我们需要记录一个状态数组来记录乘除中间所产生的 $x^i$ ,以便后续过程中使用。但是这道题直接搜索的话,又会超时,因为他把大量的时间浪费在高深度上,但是这个却不一定是最优解。因此需要用到迭代加深搜索(IDDFS).\n迭代加深搜索(IDDFS)主要用于处理一些题目可能会搜到很深但是答案却不是最优的问题。有的时候dfs搜索的深度是无穷的,而且他的复杂度是呈指数级增长的,因此这其中某些情况就可以用IDDFS,在每次搜索的时候,我们给深度一个限制,当达到这个最大深度却没有得到答案的时候,就返回,然后逐步提升深度,这样我们就可以避免将时间浪费在那些无谓的高深度搜索上了。\n$$ \\sum_{i=0}^n2^i=2^{n+1}-1(指数级别增长实例) $$\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; using namespace std; int n; int x[1005]; //用来记录每次生成的中间状态 bool dfs(int k,int dep,int maxdep) { if(k\u0026lt;=0||dep\u0026gt;maxdep||k\u0026lt;\u0026lt;(maxdep-dep)\u0026lt;n) return false; if(k==n||k\u0026lt;\u0026lt;(maxdep-dep)==n) return true; x[dep]=k; for(int i=0;i\u0026lt;=dep;i++) { if(dfs(k+x[i],dep+1,maxdep)) return true; //对应乘法 if(dfs(k-x[i],dep+1,maxdep)) return true; //对应除法 } x[dep]=0; return false; } int main() { while(scanf(\u0026#34;%d\u0026#34;,\u0026amp;n)\u0026amp;\u0026amp;n) { for(int i=0;;i++) { if(dfs(1,0,i)) { printf(\u0026#34;%d\\n\u0026#34;,i); break; } } } } ","permalink":"https://blog.zzsqwq.cn/posts/16/","summary":"\u003ch3 id=\"1-p1378-油滴扩展httpswwwluogucomcnproblemp1378\"\u003e1. \u003ca href=\"https://www.luogu.com.cn/problem/P1378\"\u003eP1378 油滴扩展\u003c/a\u003e\u003c/h3\u003e\n\u003chr\u003e\n\u003ch4 id=\"题意\"\u003e题意\u003c/h4\u003e\n\u003cp\u003e在长方形框中,最多有 n ($0\\le{n}\\le6$)个相异点,在框中点上依次放置可扩展的油滴,当碰到其他油滴边界或者长方形边框时会停止,扩展呈圆形展开。放置下一个时会确保上一个已经扩展完成。问通过变换放置顺序可使得最终框中剩下的面积最小为多少。\u003c/p\u003e","title":"洛谷的一些搜索题"},{"content":"希腊字母表 一些技巧和特殊符号 上标:num_i -\u0026gt; $num_i$\n下标:e^x -\u0026gt; $e^x$ (如果下标或上标不明显,可嵌套多层来达到目的)\n上下标是一串字符的话可用{}括起来表示 根号:\\sqrt3{x} -\u0026gt; $\\sqrt3{x}$\n省略号: 在下面\\dots -\u0026gt; $\\dots$ 在中间\\cdots -\u0026gt; $\\cdots$\n方框: \\boxed{example} -\u0026gt; $\\boxed{example}$ (还有一个\\fbox与此类似 \\fobx{example} -\u0026gt; $\\fbox{example}$)\n字体加粗: \\mathbf{example} -\u0026gt; $\\mathbf{example}$\n字体斜体且加粗: \\boldsymbol{example} -\u0026gt; $\\boldsymbol{example}$\n插入普通文本(自适应大小): \\text{测试} -\u0026gt; $\\text{测试}$\n一些基本符号 求和: \\sum_1^n -\u0026gt; $\\sum_1^n$\n积分: \\int_1^n -\u0026gt; $\\int_1^n$ \\iint -\u0026gt; $\\iint$ 以此类推$\\cdots$\n极限: \\lim_{x \\to +\\infty} -\u0026gt; $\\lim_{x \\to +\\infty}$\n分数: \\frac{1}{2} -\u0026gt; $\\frac{1}{2}$ 如果要写多层分数可以用\\cfrac (可以避免字母逐层缩小的限制)\n组合数: \\binom{5}{2} -\u0026gt; $\\binom{5}{2}$\n下取整: \\lfloor{x}\\rfloor -\u0026gt; $\\lfloor{x}\\rfloor$\n下取整: \\lceil{x}\\rceil -\u0026gt; $\\lceil{x}\\rceil$\n关于矩阵和行列式 矩阵:用法如下,元素中间使用\u0026amp;来分割同行元素,用\\\\来换行 \\begin{matrix} 1 \u0026amp; 2 \u0026amp; 3\\\\ 4 \u0026amp; 5 \u0026amp; 6\\\\ 7 \u0026amp; 8 \u0026amp; 9\\\\ \\end{matrix} $$ \\begin{matrix} 1 \u0026amp; 2 \u0026amp; 3\\ 4 \u0026amp; 5 \u0026amp; 6\\ 7 \u0026amp; 8 \u0026amp; 9\\ \\end{matrix} $$\n行列式: 与矩阵相似,加上行列式的名字以及左右分割线即可 A= \\left| \\begin{matrix} 1 \u0026amp; 2 \u0026amp; 3 \\\\ 4 \u0026amp; 5 \u0026amp; 6 \\\\ 7 \u0026amp; 8 \u0026amp; 9 \\\\ \\end{matrix} \\right| $$ A= \\left| \\begin{matrix} 1 \u0026amp; 2 \u0026amp; 3 \\ 4 \u0026amp; 5 \u0026amp; 6 \\ 7 \u0026amp; 8 \u0026amp; 9 \\ \\end{matrix} \\right| $$\n分段函数和方程组 分段函数:写法如下,每一个条件用 表达式和条件之间用 \u0026amp; 连接 f(x)= \\begin{cases} x/2, \u0026amp; {n\u0026gt;2}\\\\ 2x , \u0026amp; {n=2}\\\\ 3x , \u0026amp; {n\u0026lt;2}\\\\ \\end{cases} $$ f(x)= \\begin{cases} x/2, \u0026amp; {n\u0026gt;2}\\ 2x , \u0026amp; {n=2}\\ 3x , \u0026amp; {n\u0026lt;2}\\ \\end{cases} $$\n方程组: 写法如下,不是一个对称的,注意left后面为{ ,right后面为. 用\\\\换行 \\left\\{ \\begin{array}{} a_1x+b_1y+c_1z=d_1\\\\ a_2x+b_2y+c_2z=d_2\\\\ a_3x+b_3y+c_3z=d_3 \\end{array} \\right. $$ \\left{ \\begin{array}{} a_1x+b_1y+c_1z=d_1\\ a_2x+b_2y+c_2z=d_2\\ a_3x+b_3y+c_3z=d_3 \\end{array} \\right. $$\nPs: 上面的矩阵,行列式,分段函数和方程组有一个问题需要我们注意,因为反斜杠 \\ 需要转义,那么对于每次换行需要两个\\\\ ,也就是说你打的时候总需要打四个,对于前面声明begin和end,或者left和right前面的反斜杠,你打的时候就要打两个,对于markdown编辑器里面编辑LaTeX可能会自适应,不会自动转义,但是我们推博客的时候,一定要注意这个地方,不然会显示错误。也就是对于上述描述中的反斜杠,都要按两倍来写\n2020.8.17更新\n对于Hexo搭建的博客,用mathjax渲染,需要上述的规则。如果博客用的是typecho系统并且LaTeX插件为MardownKatex,那么不需要注意上述规则。(其他的系统我没有试过,暂且不谈) 先总结这么多,后面那些进阶的用到了再总结。\n参考文献:\nTypora中利用LaTeX 插入数学公式\nLATEX 公式总结\n","permalink":"https://blog.zzsqwq.cn/posts/10/","summary":"\u003ch3 id=\"希腊字母表\"\u003e希腊字母表\u003c/h3\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"https://blog.zzsqwq.cn/usr/uploads/2020/08/248320705.png\" alt=\"xila.png\" /\u003e\n\u003c/p\u003e","title":"LaTeX的一些总结"},{"content":"A : Display The Number 题意 用一定数目的灯管,显示尽可能大的数\n思路 因为位数多的肯定更大,所以肯定用尽量少的灯管搭建单个数字更好,最少的两个分别是两个灯管显示的1,以及三个灯管显示的7,所以就是尽可能的用1,如果最后剩余正好三个就显示7。这就转化成了判断奇数还是偶数的题,奇数就显示7111····,偶数就是1111···。注意要把7放在前面(我就踩坑了)。\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; using namespace std; int t,n; int cnt=0; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { scanf(\u0026#34;%d\u0026#34;,\u0026amp;n); if(n%2==0) { int p=n/2; for(int i=1;i\u0026lt;=p;i++) printf(\u0026#34;1\u0026#34;); } else { printf(\u0026#34;7\u0026#34;); n-=3; int p=n/2; for(int i=1;i\u0026lt;=p;i++) printf(\u0026#34;1\u0026#34;); } printf(\u0026#34;\\n\u0026#34;); } return 0; } B : Infinite Prefixes 题意 给定一段01字符串 s 为循环节,得到无限循环的01字符串 t,求 t 中有多少前缀满足0个数-1个数等于期望值x (空前缀也算是一个前缀)\n前缀:例如\u0026quot;abcd\u0026quot;的前缀包括 \u0026quot; \u0026ldquo;,\u0026ldquo;a\u0026rdquo;,\u0026ldquo;ab\u0026rdquo;,\u0026ldquo;abc\u0026rdquo;,\u0026ldquo;abcd\u0026rdquo;.\n思路 首先我们先记录循环节 s 中每个位置对应的01个数差,记为$num_i,i\\in[1,n]$ ( s 长度记为n)\n首先我们可以发现当 x=0 的时候,空前缀也会有贡献,因此不能忽略空前缀。\n如果循环节 s 的01数相等,那么我们可以发现最后循环节一位$num_n$总为0,那么可以分两种情况来讨论\n如果循环节中存在大于等于1个前缀满足期望值x,那么就有无限个满足,因此输出-1 如果循环节 s 中不存在满足期望值的前缀,那么 t 中也一定不存在 再来看一般情况,如果一个前缀中包含多个循环节 s ,那么前面每个循环节对于最终01个数差的贡献总为$num_n$,因此我们可以用所期望的值 x,利用1~n 循环减去每一位的 $num_i$,如果所得是$num_n$的非负倍数,那么就是符合期望的,否则不是。(本来一直这里不太明白,后来发现对于循环节中的每一个位置,在后续循环的过程中,如果$num_n$不为0,那么这个位置每次对应的值总是唯一的)\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cmath\u0026gt; using namespace std; int num[100005]; int t,cnt,n,x; bool flag=false; char s[100005]; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;t); while(t--) { cnt=0; flag=false; scanf(\u0026#34;%d%d\u0026#34;,\u0026amp;n,\u0026amp;x); scanf(\u0026#34;%s\u0026#34;,s+1); for(int i=1;i\u0026lt;=n;i++) { if(s[i]==\u0026#39;0\u0026#39;) { num[i]=num[i-1]+1;\t} else num[i]=num[i-1]-1; if(num[i]==x) flag=true; } int p=num[n]; if(p==0) { if(flag==true) { printf(\u0026#34;-1\\n\u0026#34;); continue; } else { printf(\u0026#34;0\\n\u0026#34;); continue; } } else { for(int i=1;i\u0026lt;=n;i++) { int m=x-num[i]; if(m%p==0\u0026amp;\u0026amp;m/p\u0026gt;=0) { cnt++; } } } if(x==0) cnt++; printf(\u0026#34;%d\\n\u0026#34;,cnt); } } C : Obtain The String 题意 给定字符串 s 和 t ,每次从 s 中选取子序列放入起始为空串的 z 后,问最少需要多少次操作使得 z=t\n思路 看了小姜老师的博客解法说是贪心,想了好一会,好像确实是可以贪心的···? 设置两个指针从 s 和 t 串的头部开始扫,对于 t 串中的每个字母,循环扫 s 串在其中找与它相同的,最终的答案就是扫 s 串的次数。(小姜老师说这个实质上就是每次尽可能找尽可能多的后缀,仔细想想确实是这样。)不过这么一直暴力扫下去肯定不是最优的方法,想办法去优化。还是借鉴大佬的想法用一个lens*26的跳表,然后O(lent)扫一遍 t 即可.\n跳表nxt的作用,用于寻找下一个所寻找字符在s中的位置。\nnxt[x][y]用于指向从x位置开始下一个y的位置+1 (next在C++属于保留字,注意不要踩坑)\n代码实现 #include\u0026lt;cstdio\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;algorithm\u0026gt; #include\u0026lt;cstring\u0026gt; #include\u0026lt;iostream\u0026gt; using namespace std; const int maxn=100005; char s[maxn],t[maxn]; int nxt[maxn][30]; int p,lens,lent; int pos,ans; int main() { scanf(\u0026#34;%d\u0026#34;,\u0026amp;p); while(p--) { ans=1; scanf(\u0026#34;%s\u0026#34;,s+1); scanf(\u0026#34;%s\u0026#34;,t); lent=strlen(t),lens=strlen(s+1); //\tprintf(\u0026#34;%d\u0026#34;,lens); for(int c=0;c\u0026lt;26;c++) { nxt[lens+1][c]=-1; for(int i=lens;i\u0026gt;=1;i--) { if(s[i]-\u0026#39;a\u0026#39;==c) { nxt[i][c]=i+1; } else nxt[i][c]=nxt[i+1][c]; } } pos=1; for(int i=0;i\u0026lt;lent;i++) { pos=nxt[pos][(int)t[i]-\u0026#39;a\u0026#39;]; if(pos==-1) { ans++; pos=1; pos=nxt[pos][(int)t[i]-\u0026#39;a\u0026#39;]; if(pos==-1) { ans=-1; break; } } } printf(\u0026#34;%d\\n\u0026#34;,ans); } } ","permalink":"https://blog.zzsqwq.cn/posts/8/","summary":"\u003ch3 id=\"a--display-the-numberhttpscodeforcescomcontest1295problema\"\u003eA : \u003ca href=\"https://codeforces.com/contest/1295/problem/A\"\u003eDisplay The Number\u003c/a\u003e\u003c/h3\u003e\n\u003ch4 id=\"题意\"\u003e题意\u003c/h4\u003e\n\u003cp\u003e用一定数目的灯管,显示尽可能大的数\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"https://s2.ax1x.com/2020/02/02/1te6Re.md.png\" alt=\"A\" /\u003e\n\u003c/p\u003e","title":"CodeforcesER #81"},{"content":"Github:@zzsqwq\nE-mail: trizsqwq@gmail.com\nTelegram: @zzsqwq\nsspai: @zzsqwq\n","permalink":"https://blog.zzsqwq.cn/about/","summary":"\u003cp\u003e\u003cstrong\u003eGithub:\u003ca href=\"https://github.com/zzsqwq\"\u003e@zzsqwq\u003c/a\u003e\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eE-mail: \u003ca href=\"mailto:trizsqwq@gmail.com\"\u003etrizsqwq@gmail.com\u003c/a\u003e\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eTelegram: \u003ca href=\"https://t.me/zzsqwq\"\u003e@zzsqwq\u003c/a\u003e\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003esspai: \u003ca href=\"https://sspai.com/u/zzsqwq\"\u003e@zzsqwq\u003c/a\u003e\u003c/strong\u003e\u003c/p\u003e","title":"About"},{"content":"To request a link, please make sure your blog has https enabled.\nHuaDeity https://blog.huadeity.com\n70loKirin https://qllokirin.github.io\nAngine https://angine.tech\nMurphyHou https://cosmicdusty.cc\nOrangii https://orangii.cn\npg999w https://blog.pg999w.top\nJiacheng Lyu https://ljcheng.cc\nSiYun https://siyun916.github.io\nBowen https://www.tomcatdeng.cn\n斯文孙 https://www.vhrise.com\nimmortalqx https://immortalqx.github.io\nKehan https://blog.kehan.xyz\nZhang Jiale https://zjlzjl.com\n","permalink":"https://blog.zzsqwq.cn/friends/","summary":"\u003cp\u003eTo request a link, please make sure your blog has \u003ca href=\"https://en.wikipedia.org/wiki/HTTPS\"\u003ehttps\u003c/a\u003e enabled.\u003c/p\u003e\n\u003cp\u003eHuaDeity \u003ca href=\"https://blog.huadeity.com\"\u003ehttps://blog.huadeity.com\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e70loKirin \u003ca href=\"https://qllokirin.github.io\"\u003ehttps://qllokirin.github.io\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eAngine \u003ca href=\"https://angine.tech\"\u003ehttps://angine.tech\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eMurphyHou \u003ca href=\"https://cosmicdusty.cc\"\u003ehttps://cosmicdusty.cc\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eOrangii \u003ca href=\"https://orangii.cn\"\u003ehttps://orangii.cn\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003epg999w \u003ca href=\"https://blog.pg999w.top\"\u003ehttps://blog.pg999w.top\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eJiacheng Lyu \u003ca href=\"https://ljcheng.cc\"\u003ehttps://ljcheng.cc\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eSiYun \u003ca href=\"https://siyun916.github.io\"\u003ehttps://siyun916.github.io\u003c/a\u003e\u003c/p\u003e\n\u003c!-- Kircute https://kircute.jimmytoluene.com --\u003e\n\u003cp\u003eBowen \u003ca href=\"https://www.tomcatdeng.cn\"\u003ehttps://www.tomcatdeng.cn\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e斯文孙 \u003ca href=\"https://www.vhrise.com\"\u003ehttps://www.vhrise.com\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eimmortalqx \u003ca href=\"https://immortalqx.github.io\"\u003ehttps://immortalqx.github.io\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eKehan \u003ca href=\"https://blog.kehan.xyz\"\u003ehttps://blog.kehan.xyz\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eZhang Jiale \u003ca href=\"https://zjlzjl.com\"\u003ehttps://zjlzjl.com\u003c/a\u003e\u003c/p\u003e","title":"Friends"}] \ No newline at end of file diff --git a/index.xml b/index.xml index 7c0f3f59..3e104052 100644 --- a/index.xml +++ b/index.xml @@ -115,490 +115,490 @@ <p>由于软件可能较多,不能一次性写完。同时,因为我也在不断体验新的软件,有新的感受,因此这篇博客应该是持续更新的,欢迎常来看看。</p> <h2 id="速览表">速览表</h2> <table> -<thead> -<tr> -<th>App 名称</th> -<th>简短描述</th> -<th>功能限制</th> -<th>订阅形式</th> -<th>价格</th> -<th>购入时间</th> -<th>购入渠道</th> -<th>同类型产品</th> -</tr> -</thead> -<tbody> -<tr> -<td>AIDente</td> -<td>电池电量管理</td> -<td>有免费使用功能,但有共功能需要收费</td> -<td>买断</td> -<td>Free</td> -<td></td> -<td></td> -<td>Battery, BatFi</td> -</tr> -<tr> -<td>AdGuard</td> -<td>广告拦截软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>AltTab</td> -<td>增强 macOS App 切换</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Command-Tab Plus, Contexts,HyperSwitch,</td> -</tr> -<tr> -<td>Bartender 5</td> -<td>Menubar 管理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Bob</td> -<td>大概是最好用翻译软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>EasyDict</td> -</tr> -<tr> -<td>BuhoCleaner</td> -<td>垃圾清理器/软件卸载器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>CleanMyMac, Sensei</td> -</tr> -<tr> -<td>Clash X / Clash X Pro</td> -<td>代理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Surge, Stash</td> -</tr> -<tr> -<td>CleanBuddy</td> -<td>键盘锁定清理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Cleaner</td> -</tr> -<tr> -<td>CleanShot X</td> -<td>大概最好用的截图软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Cleaner</td> -<td>键盘屏幕锁定清理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>CleanBuddy</td> -</tr> -<tr> -<td>Dash</td> -<td>文档利器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Dato</td> -<td>Menubar 日历软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Fantastical, Itsycal</td> -</tr> -<tr> -<td>DevUtils</td> -<td>开发小工具合集</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Downie 4</td> -<td>各类视频下载器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>VDown</td> -</tr> -<tr> -<td>HapiGo</td> -<td>启动器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Alfred, Raycast</td> -</tr> -<tr> -<td>HazeOver</td> -<td>生产力工具,突出重点</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Hazel</td> -<td>自动清理集合</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>JetBrains 全家桶</td> -<td>包含 Clion/IDEA 等</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>VSCode, Eclipse</td> -</tr> -<tr> -<td>Lunar</td> -<td>显示器管理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>MonitorControl, DisplayBuddy, Better Display</td> -</tr> -<tr> -<td>Maccy</td> -<td>开源免费的剪切板管理工具</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Paste, PasteNow, PastePal</td> -</tr> -<tr> -<td>Manico</td> -<td>快速启动器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Command-Tab Plus</td> -</tr> -<tr> -<td>MimeStram</td> -<td>Gmail 客户端</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>MonitorControl</td> -<td>开源显示器管理,很够用</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Lunar, DisplayBuddy, Better Display</td> -</tr> -<tr> -<td>NetNewsWire</td> -<td>全平台 RSS 阅读器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Obsidian</td> -<td>笔记软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Omnivore</td> -<td>稍后读软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Pocket, MarkMark,</td> -</tr> -<tr> -<td>Only Switch</td> -<td>一键完成各种任务</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>One Switch</td> -</tr> -<tr> -<td>OpenImageOptim</td> -<td>图片压缩</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>TinyPNG</td> -</tr> -<tr> -<td>OrbStack</td> -<td>容器管理,平替 Docker Desktop</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Docker Desktop, Podman, lima, colima</td> -</tr> -<tr> -<td>Permute 3</td> -<td>图片/视频格式转换工具,类似于格式工厂</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>HandBrake, Omni Converter, Video Converter X2</td> -</tr> -<tr> -<td>Pixea</td> -<td>图片查看器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Viso, Picsee</td> -</tr> -<tr> -<td>Pixelmator Pro</td> -<td>图片编辑器,80% 平替 PhotoShop</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Adobe PhotoShop, Darkroom, Photomator, Capture One, Adobe LightRoom Classic</td> -</tr> -<tr> -<td>PopClip</td> -<td>划词增强</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Proxyman</td> -<td>大概是舒服的抓包工具,略贵</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Charles</td> -</tr> -<tr> -<td>Rectangle</td> -<td>分屏软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Magnet, Swish</td> -</tr> -<tr> -<td>Swish</td> -<td>触控板手势增强</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Stats</td> -<td>Menubar 状态监控</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>iStats Menu, Sensei</td> -</tr> -<tr> -<td>Subscriptions</td> -<td>订阅管理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Pandora on iOS</td> -</tr> -<tr> -<td>Surge</td> -<td>代理工具</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Clash X, Stash</td> -</tr> -<tr> -<td>TinyPNG</td> -<td>图片压缩</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>OpenImageOptim</td> -</tr> -<tr> -<td>Typora</td> -<td>Markdown 文本编辑器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Obsidian</td> -</tr> -<tr> -<td>Upscayl</td> -<td>AI 图片超分</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>AI Photo Enhancer by Pictura, Pixelmator Pro</td> -</tr> -<tr> -<td>Viso 6</td> -<td>图片查看器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Pixea, Xee</td> -</tr> -<tr> -<td>Zotero</td> -<td>文献管理,就是界面一般</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>coconutBattery</td> -<td>iPhone/iPad/Mac 电池信息查看</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>iRightMenu</td> -<td>右键增强</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>超级右键, iMouse,</td> -</tr> -<tr> -<td>iTerm2</td> -<td>终端模拟器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Alacritty, Warp, Wezterm, Terminal</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">App 名称</th> + <th style="text-align: left">简短描述</th> + <th style="text-align: left">功能限制</th> + <th style="text-align: left">订阅形式</th> + <th style="text-align: left">价格</th> + <th style="text-align: left">购入时间</th> + <th style="text-align: left">购入渠道</th> + <th style="text-align: left">同类型产品</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">AIDente</td> + <td style="text-align: left">电池电量管理</td> + <td style="text-align: left">有免费使用功能,但有共功能需要收费</td> + <td style="text-align: left">买断</td> + <td style="text-align: left">Free</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Battery, BatFi</td> + </tr> + <tr> + <td style="text-align: left">AdGuard</td> + <td style="text-align: left">广告拦截软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">AltTab</td> + <td style="text-align: left">增强 macOS App 切换</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Command-Tab Plus, Contexts,HyperSwitch,</td> + </tr> + <tr> + <td style="text-align: left">Bartender 5</td> + <td style="text-align: left">Menubar 管理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Bob</td> + <td style="text-align: left">大概是最好用翻译软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">EasyDict</td> + </tr> + <tr> + <td style="text-align: left">BuhoCleaner</td> + <td style="text-align: left">垃圾清理器/软件卸载器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">CleanMyMac, Sensei</td> + </tr> + <tr> + <td style="text-align: left">Clash X / Clash X Pro</td> + <td style="text-align: left">代理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Surge, Stash</td> + </tr> + <tr> + <td style="text-align: left">CleanBuddy</td> + <td style="text-align: left">键盘锁定清理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Cleaner</td> + </tr> + <tr> + <td style="text-align: left">CleanShot X</td> + <td style="text-align: left">大概最好用的截图软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Cleaner</td> + <td style="text-align: left">键盘屏幕锁定清理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">CleanBuddy</td> + </tr> + <tr> + <td style="text-align: left">Dash</td> + <td style="text-align: left">文档利器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Dato</td> + <td style="text-align: left">Menubar 日历软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Fantastical, Itsycal</td> + </tr> + <tr> + <td style="text-align: left">DevUtils</td> + <td style="text-align: left">开发小工具合集</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Downie 4</td> + <td style="text-align: left">各类视频下载器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">VDown</td> + </tr> + <tr> + <td style="text-align: left">HapiGo</td> + <td style="text-align: left">启动器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Alfred, Raycast</td> + </tr> + <tr> + <td style="text-align: left">HazeOver</td> + <td style="text-align: left">生产力工具,突出重点</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Hazel</td> + <td style="text-align: left">自动清理集合</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">JetBrains 全家桶</td> + <td style="text-align: left">包含 Clion/IDEA 等</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">VSCode, Eclipse</td> + </tr> + <tr> + <td style="text-align: left">Lunar</td> + <td style="text-align: left">显示器管理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">MonitorControl, DisplayBuddy, Better Display</td> + </tr> + <tr> + <td style="text-align: left">Maccy</td> + <td style="text-align: left">开源免费的剪切板管理工具</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Paste, PasteNow, PastePal</td> + </tr> + <tr> + <td style="text-align: left">Manico</td> + <td style="text-align: left">快速启动器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Command-Tab Plus</td> + </tr> + <tr> + <td style="text-align: left">MimeStram</td> + <td style="text-align: left">Gmail 客户端</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">MonitorControl</td> + <td style="text-align: left">开源显示器管理,很够用</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Lunar, DisplayBuddy, Better Display</td> + </tr> + <tr> + <td style="text-align: left">NetNewsWire</td> + <td style="text-align: left">全平台 RSS 阅读器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Obsidian</td> + <td style="text-align: left">笔记软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Omnivore</td> + <td style="text-align: left">稍后读软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Pocket, MarkMark,</td> + </tr> + <tr> + <td style="text-align: left">Only Switch</td> + <td style="text-align: left">一键完成各种任务</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">One Switch</td> + </tr> + <tr> + <td style="text-align: left">OpenImageOptim</td> + <td style="text-align: left">图片压缩</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">TinyPNG</td> + </tr> + <tr> + <td style="text-align: left">OrbStack</td> + <td style="text-align: left">容器管理,平替 Docker Desktop</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Docker Desktop, Podman, lima, colima</td> + </tr> + <tr> + <td style="text-align: left">Permute 3</td> + <td style="text-align: left">图片/视频格式转换工具,类似于格式工厂</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">HandBrake, Omni Converter, Video Converter X2</td> + </tr> + <tr> + <td style="text-align: left">Pixea</td> + <td style="text-align: left">图片查看器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Viso, Picsee</td> + </tr> + <tr> + <td style="text-align: left">Pixelmator Pro</td> + <td style="text-align: left">图片编辑器,80% 平替 PhotoShop</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Adobe PhotoShop, Darkroom, Photomator, Capture One, Adobe LightRoom Classic</td> + </tr> + <tr> + <td style="text-align: left">PopClip</td> + <td style="text-align: left">划词增强</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Proxyman</td> + <td style="text-align: left">大概是舒服的抓包工具,略贵</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Charles</td> + </tr> + <tr> + <td style="text-align: left">Rectangle</td> + <td style="text-align: left">分屏软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Magnet, Swish</td> + </tr> + <tr> + <td style="text-align: left">Swish</td> + <td style="text-align: left">触控板手势增强</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Stats</td> + <td style="text-align: left">Menubar 状态监控</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">iStats Menu, Sensei</td> + </tr> + <tr> + <td style="text-align: left">Subscriptions</td> + <td style="text-align: left">订阅管理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Pandora on iOS</td> + </tr> + <tr> + <td style="text-align: left">Surge</td> + <td style="text-align: left">代理工具</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Clash X, Stash</td> + </tr> + <tr> + <td style="text-align: left">TinyPNG</td> + <td style="text-align: left">图片压缩</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">OpenImageOptim</td> + </tr> + <tr> + <td style="text-align: left">Typora</td> + <td style="text-align: left">Markdown 文本编辑器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Obsidian</td> + </tr> + <tr> + <td style="text-align: left">Upscayl</td> + <td style="text-align: left">AI 图片超分</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">AI Photo Enhancer by Pictura, Pixelmator Pro</td> + </tr> + <tr> + <td style="text-align: left">Viso 6</td> + <td style="text-align: left">图片查看器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Pixea, Xee</td> + </tr> + <tr> + <td style="text-align: left">Zotero</td> + <td style="text-align: left">文献管理,就是界面一般</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">coconutBattery</td> + <td style="text-align: left">iPhone/iPad/Mac 电池信息查看</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">iRightMenu</td> + <td style="text-align: left">右键增强</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">超级右键, iMouse,</td> + </tr> + <tr> + <td style="text-align: left">iTerm2</td> + <td style="text-align: left">终端模拟器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Alacritty, Warp, Wezterm, Terminal</td> + </tr> + </tbody> </table> <h2 id="详细信息">详细信息</h2> <h3 id="aidente">AIDente</h3> @@ -2989,70 +2989,70 @@ Changes not staged for commit: <p>波士顿住房数据由哈里森和鲁宾菲尔德于1978年Harrison and Rubinfeld<sup><a href="https://blog.zzsqwq.cn/usr/uploads/2021/05/406125417.png">1</a></sup>收集。它包括了波士顿大区每个调查行政区的506个观察值。1980年Belsley et al.<sup><a href="https://blog.zzsqwq.cn/usr/uploads/2021/05/3238192089.png">2</a></sup>曾对此数据做过分析。</p> <p>数据一共14列,每一列的含义分别如下:</p> <table> -<thead> -<tr> -<th>英文简称</th> -<th>详细含义</th> -</tr> -</thead> -<tbody> -<tr> -<td>CRIM</td> -<td>城镇的人均犯罪率</td> -</tr> -<tr> -<td>ZN</td> -<td>大于25,000平方英尺的地块的住宅用地比例。</td> -</tr> -<tr> -<td>INDUS</td> -<td>每个镇的非零售业务英亩的比例。</td> -</tr> -<tr> -<td>CHAS</td> -<td>查尔斯河虚拟变量(如果环河,则等于1;否则等于0)</td> -</tr> -<tr> -<td>NOX</td> -<td>一氧化氮的浓度(百万分之几)</td> -</tr> -<tr> -<td>RM</td> -<td>每个住宅的平均房间数</td> -</tr> -<tr> -<td>AGE</td> -<td>1940年之前建造的自有住房的比例</td> -</tr> -<tr> -<td>DIS</td> -<td>到五个波士顿就业中心的加权距离</td> -</tr> -<tr> -<td>RAD</td> -<td>径向公路通达性的指标</td> -</tr> -<tr> -<td>TAX</td> -<td>每一万美元的全值财产税率</td> -</tr> -<tr> -<td>PTRATIO</td> -<td>各镇的师生比率</td> -</tr> -<tr> -<td>B</td> -<td>计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例</td> -</tr> -<tr> -<td>LSTAT</td> -<td>底层人口的百分比(%)</td> -</tr> -<tr> -<td><strong>price</strong></td> -<td>自有住房数的中位数,单位(千美元)</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">英文简称</th> + <th style="text-align: left">详细含义</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">CRIM</td> + <td style="text-align: left">城镇的人均犯罪率</td> + </tr> + <tr> + <td style="text-align: left">ZN</td> + <td style="text-align: left">大于25,000平方英尺的地块的住宅用地比例。</td> + </tr> + <tr> + <td style="text-align: left">INDUS</td> + <td style="text-align: left">每个镇的非零售业务英亩的比例。</td> + </tr> + <tr> + <td style="text-align: left">CHAS</td> + <td style="text-align: left">查尔斯河虚拟变量(如果环河,则等于1;否则等于0)</td> + </tr> + <tr> + <td style="text-align: left">NOX</td> + <td style="text-align: left">一氧化氮的浓度(百万分之几)</td> + </tr> + <tr> + <td style="text-align: left">RM</td> + <td style="text-align: left">每个住宅的平均房间数</td> + </tr> + <tr> + <td style="text-align: left">AGE</td> + <td style="text-align: left">1940年之前建造的自有住房的比例</td> + </tr> + <tr> + <td style="text-align: left">DIS</td> + <td style="text-align: left">到五个波士顿就业中心的加权距离</td> + </tr> + <tr> + <td style="text-align: left">RAD</td> + <td style="text-align: left">径向公路通达性的指标</td> + </tr> + <tr> + <td style="text-align: left">TAX</td> + <td style="text-align: left">每一万美元的全值财产税率</td> + </tr> + <tr> + <td style="text-align: left">PTRATIO</td> + <td style="text-align: left">各镇的师生比率</td> + </tr> + <tr> + <td style="text-align: left">B</td> + <td style="text-align: left">计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例</td> + </tr> + <tr> + <td style="text-align: left">LSTAT</td> + <td style="text-align: left">底层人口的百分比(%)</td> + </tr> + <tr> + <td style="text-align: left"><strong>price</strong></td> + <td style="text-align: left">自有住房数的中位数,单位(千美元)</td> + </tr> + </tbody> </table> <p>基于上述数据,请完成以下问题:</p> <p><strong>建立波士顿房价预测模型并对预测结果进行评价。</strong></p> @@ -3077,46 +3077,46 @@ $$ 其中 $x_i,y_i$ 为数据的每个分量,$\bar{x},\bar{y}$ 为数据的均值</p> <p>该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下:</p> <table> -<thead> -<tr> -<th>CRIM</th> -<th>ZN</th> -<th>INDUS</th> -<th>CHAS</th> -<th>NOX</th> -<th>RM</th> -<th>LSTAT</th> -</tr> -</thead> -<tbody> -<tr> -<td>-0.385832</td> -<td>0.360445</td> -<td>-0.483725</td> -<td>0.175260</td> -<td>-0.427321</td> -<td>0.695360</td> -<td>-0.737663</td> -</tr> -<tr> -<td><strong>AGE</strong></td> -<td><strong>DIS</strong></td> -<td><strong>RAD</strong></td> -<td><strong>TAX</strong></td> -<td><strong>PTRATIO</strong></td> -<td><strong>B</strong></td> -<td></td> -</tr> -<tr> -<td>-0.376955</td> -<td>0.249929</td> -<td>-0.381626</td> -<td>-0.468536</td> -<td>-0.507787</td> -<td>0.333461</td> -<td></td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">CRIM</th> + <th style="text-align: left">ZN</th> + <th style="text-align: left">INDUS</th> + <th style="text-align: left">CHAS</th> + <th style="text-align: left">NOX</th> + <th style="text-align: left">RM</th> + <th style="text-align: left">LSTAT</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">-0.385832</td> + <td style="text-align: left">0.360445</td> + <td style="text-align: left">-0.483725</td> + <td style="text-align: left">0.175260</td> + <td style="text-align: left">-0.427321</td> + <td style="text-align: left">0.695360</td> + <td style="text-align: left">-0.737663</td> + </tr> + <tr> + <td style="text-align: left"><strong>AGE</strong></td> + <td style="text-align: left"><strong>DIS</strong></td> + <td style="text-align: left"><strong>RAD</strong></td> + <td style="text-align: left"><strong>TAX</strong></td> + <td style="text-align: left"><strong>PTRATIO</strong></td> + <td style="text-align: left"><strong>B</strong></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">-0.376955</td> + <td style="text-align: left">0.249929</td> + <td style="text-align: left">-0.381626</td> + <td style="text-align: left">-0.468536</td> + <td style="text-align: left">-0.507787</td> + <td style="text-align: left">0.333461</td> + <td style="text-align: left"></td> + </tr> + </tbody> </table> <p>观察结果可以发现,在给定的十三个变量中,<strong>LSTAT <strong>与 <strong>price</strong> 的相关程度最高$(|r|&gt;0.7)$,其次是 <strong>RM</strong> 与</strong>PTRATIO</strong> $(|r|&gt;0.5)$,再者是 <strong>TAX,INDUS,NOX</strong> $(|r|&gt;0.4)$,除上述之外的七个变量都与 <strong>price</strong> 无较强的相关性,因此我们考虑使用六个相关性较强变量和十三个变量分别来对房价进行预测,并对他们进行对比,来寻找最优的回归模型。</p> <h5 id="模型的构建">模型的构建</h5> @@ -5907,34 +5907,34 @@ $$</p> <p><strong>tar</strong> 命令:压缩或解压命令。<code>tar [参数] 打包文件名 要打包的各个文件 </code> 。</p> <p>参数表:</p> <table> -<thead> -<tr> -<th>参数</th> -<th>含义</th> -</tr> -</thead> -<tbody> -<tr> -<td>-c</td> -<td>生成档案文件,创建打包文件</td> -</tr> -<tr> -<td>-v</td> -<td>列出归档解档的详细过程,显示进度</td> -</tr> -<tr> -<td>-f</td> -<td>指定档案文件名称,f后面一定是.tar文件,所以放选项最后</td> -</tr> -<tr> -<td>-t</td> -<td>列出档案中包含的文件</td> -</tr> -<tr> -<td>-x</td> -<td>解开档案文件</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">参数</th> + <th style="text-align: left">含义</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">-c</td> + <td style="text-align: left">生成档案文件,创建打包文件</td> + </tr> + <tr> + <td style="text-align: left">-v</td> + <td style="text-align: left">列出归档解档的详细过程,显示进度</td> + </tr> + <tr> + <td style="text-align: left">-f</td> + <td style="text-align: left">指定档案文件名称,f后面一定是.tar文件,所以放选项最后</td> + </tr> + <tr> + <td style="text-align: left">-t</td> + <td style="text-align: left">列出档案中包含的文件</td> + </tr> + <tr> + <td style="text-align: left">-x</td> + <td style="text-align: left">解开档案文件</td> + </tr> + </tbody> </table> <p>打包实例: <code>tar -cvf 文件名 要打包的文件</code> 解压实例:<code>tar -xvf 压缩包名</code></p> </li> @@ -9042,46 +9042,46 @@ QAQ刷了这么多天的dp好像终于有点作用了,我终于看出来这是 <p>顾名思义,他就是一个单调的队列,那么我们可以规定他是单调递增的还是单调递减的,他和普通的队列有点区别,队列一般是尾进头出,而单调队列要实现的话要确保头和尾都可以出,尾可以进。如果要用STL库的话可以用里面的双端队列。 跟普通队列相比他的进队需要确保一个条件就是要<strong>不破坏原有序列的单调性</strong>,好比我们有一个单调递增的单调队列,也就是从队首到队尾是单调递增的,那么有一段序列是 $[2,3,1,5,8,7,4,2]$ ,我们从左到右依次入队。</p> <table> -<thead> -<tr> -<th>队列中元素</th> -<th>关于元素进出的备注</th> -</tr> -</thead> -<tbody> -<tr> -<td>2</td> -<td>2入队</td> -</tr> -<tr> -<td>2,3</td> -<td>3比2大,可以满足递增性质,入队</td> -</tr> -<tr> -<td>1</td> -<td>因为1比2,3都小,要满足递增性质,先把2,3出队,再将1入队</td> -</tr> -<tr> -<td>1,5</td> -<td>5比1大,可以满足递增性质,入队</td> -</tr> -<tr> -<td>1,5,8</td> -<td>8比5大,可以满足递增性质,入队</td> -</tr> -<tr> -<td>1,5,7</td> -<td>7小于8,大于5,要满足递增性质,我们把8出队,然后将7入队</td> -</tr> -<tr> -<td>1,4</td> -<td>4小于5、7,但是大于1,因此7,5依次出队,4入队</td> -</tr> -<tr> -<td>1,2</td> -<td>2小于4,大于1,因此4出队,2入队</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">队列中元素</th> + <th style="text-align: left">关于元素进出的备注</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">2</td> + <td style="text-align: left">2入队</td> + </tr> + <tr> + <td style="text-align: left">2,3</td> + <td style="text-align: left">3比2大,可以满足递增性质,入队</td> + </tr> + <tr> + <td style="text-align: left">1</td> + <td style="text-align: left">因为1比2,3都小,要满足递增性质,先把2,3出队,再将1入队</td> + </tr> + <tr> + <td style="text-align: left">1,5</td> + <td style="text-align: left">5比1大,可以满足递增性质,入队</td> + </tr> + <tr> + <td style="text-align: left">1,5,8</td> + <td style="text-align: left">8比5大,可以满足递增性质,入队</td> + </tr> + <tr> + <td style="text-align: left">1,5,7</td> + <td style="text-align: left">7小于8,大于5,要满足递增性质,我们把8出队,然后将7入队</td> + </tr> + <tr> + <td style="text-align: left">1,4</td> + <td style="text-align: left">4小于5、7,但是大于1,因此7,5依次出队,4入队</td> + </tr> + <tr> + <td style="text-align: left">1,2</td> + <td style="text-align: left">2小于4,大于1,因此4出队,2入队</td> + </tr> + </tbody> </table> <p>根据上述例子不难看出,我们要入队的时候首先要确保队尾元素要比想要入队的元素小,然后才能入队,否则的话就一直循环让尾部元素出队,直到能够满足单调性为止。</p> <h2 id="单调队列的应用">单调队列的应用</h2> @@ -9219,38 +9219,38 @@ QAQ刷了这么多天的dp好像终于有点作用了,我终于看出来这是 <h2 id="理解-1">理解</h2> <p>单调栈也是在普通栈的基础上加了单调性,一般是用从栈底到栈顶的单调性来命名,好比从栈底到栈顶是单调递增的,那么他就是单调增的栈。跟单调队列一样,他的入栈规则也是<strong>要不破坏单调性</strong>,因此一个单调递增的栈如果有元素要入栈,如果他比栈顶的元素还要大,就可以直接入栈,如果他比栈顶的元素小,那么就要将栈顶的元素一直出栈到比要入栈元素小为止。如果序列为 $[2,3,1,5,4,7]$,要加入单调递增栈中,过程如下。<strong>PS:注意从左到右对应栈底到栈顶。</strong></p> <table> -<thead> -<tr> -<th>栈中的元素</th> -<th>关于元素进出的备注</th> -</tr> -</thead> -<tbody> -<tr> -<td>2</td> -<td>元素2压入栈中</td> -</tr> -<tr> -<td>2,3</td> -<td>3大于2,压入栈中</td> -</tr> -<tr> -<td>1</td> -<td>1小于3、2,因此全部弹出将1入栈</td> -</tr> -<tr> -<td>1,5</td> -<td>5大于1,压入栈中</td> -</tr> -<tr> -<td>1,4</td> -<td>4比5小,比1大,弹出5,压入4</td> -</tr> -<tr> -<td>1,4,7</td> -<td>7大于4,压入栈中</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">栈中的元素</th> + <th style="text-align: left">关于元素进出的备注</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">2</td> + <td style="text-align: left">元素2压入栈中</td> + </tr> + <tr> + <td style="text-align: left">2,3</td> + <td style="text-align: left">3大于2,压入栈中</td> + </tr> + <tr> + <td style="text-align: left">1</td> + <td style="text-align: left">1小于3、2,因此全部弹出将1入栈</td> + </tr> + <tr> + <td style="text-align: left">1,5</td> + <td style="text-align: left">5大于1,压入栈中</td> + </tr> + <tr> + <td style="text-align: left">1,4</td> + <td style="text-align: left">4比5小,比1大,弹出5,压入4</td> + </tr> + <tr> + <td style="text-align: left">1,4,7</td> + <td style="text-align: left">7大于4,压入栈中</td> + </tr> + </tbody> </table> <p>根据上述描述不难看出,其实单调栈就是单调队列的半部分,他能完成的任务理论上单调队列都能够完成,但是有些时候不需要麻烦的去维护单调队列只需要维护单调栈即可完成。</p> <h2 id="单调栈的应用">单调栈的应用</h2> @@ -10164,58 +10164,58 @@ $$ <li>碱基配对时相似度的定义如下</li> </ul> <table> -<thead> -<tr> -<th style="text-align:center"></th> -<th style="text-align:center">A</th> -<th style="text-align:center">C</th> -<th style="text-align:center">G</th> -<th style="text-align:center">T</th> -<th style="text-align:center">空</th> -</tr> -</thead> -<tbody> -<tr> -<td style="text-align:center">A</td> -<td style="text-align:center">5</td> -<td style="text-align:center">-1</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-1</td> -<td style="text-align:center">-3</td> -</tr> -<tr> -<td style="text-align:center">C</td> -<td style="text-align:center">-1</td> -<td style="text-align:center">5</td> -<td style="text-align:center">-3</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-4</td> -</tr> -<tr> -<td style="text-align:center">G</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-3</td> -<td style="text-align:center">5</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-2</td> -</tr> -<tr> -<td style="text-align:center">T</td> -<td style="text-align:center">-1</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">5</td> -<td style="text-align:center">-1</td> -</tr> -<tr> -<td style="text-align:center">空</td> -<td style="text-align:center">-3</td> -<td style="text-align:center">-4</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-1</td> -<td style="text-align:center">非法</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: center"></th> + <th style="text-align: center">A</th> + <th style="text-align: center">C</th> + <th style="text-align: center">G</th> + <th style="text-align: center">T</th> + <th style="text-align: center">空</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: center">A</td> + <td style="text-align: center">5</td> + <td style="text-align: center">-1</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-1</td> + <td style="text-align: center">-3</td> + </tr> + <tr> + <td style="text-align: center">C</td> + <td style="text-align: center">-1</td> + <td style="text-align: center">5</td> + <td style="text-align: center">-3</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-4</td> + </tr> + <tr> + <td style="text-align: center">G</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-3</td> + <td style="text-align: center">5</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-2</td> + </tr> + <tr> + <td style="text-align: center">T</td> + <td style="text-align: center">-1</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">5</td> + <td style="text-align: center">-1</td> + </tr> + <tr> + <td style="text-align: center">空</td> + <td style="text-align: center">-3</td> + <td style="text-align: center">-4</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-1</td> + <td style="text-align: center">非法</td> + </tr> + </tbody> </table> <hr> <h4 id="思路-2">思路</h4> diff --git a/posts/10/index.html b/posts/10/index.html index afaf9644..948c1c00 100644 --- a/posts/10/index.html +++ b/posts/10/index.html @@ -5,7 +5,7 @@ ">

LaTeX的一些总结

希腊字母表

xila.png


一些技巧和特殊符号

  • 上标:num_i -> $num_i$

  • 下标:e^x -> $e^x$ (如果下标或上标不明显,可嵌套多层来达到目的)

    • 上下标是一串字符的话可用{}括起来表示
  • 根号:\sqrt3{x} -> $\sqrt3{x}$

  • 省略号: 在下面\dots -> $\dots$ 在中间\cdots -> $\cdots$

  • 方框: \boxed{example} -> $\boxed{example}$ (还有一个\fbox与此类似 \fobx{example} -> $\fbox{example}$)

  • 字体加粗: \mathbf{example} -> $\mathbf{example}$

  • 字体斜体且加粗: \boldsymbol{example} -> $\boldsymbol{example}$

  • 插入普通文本(自适应大小): \text{测试} -> $\text{测试}$

    specialsign.png +">

    LaTeX的一些总结

    希腊字母表

    xila.png


    一些技巧和特殊符号

    • 上标:num_i -> $num_i$

    • 下标:e^x -> $e^x$ (如果下标或上标不明显,可嵌套多层来达到目的)

      • 上下标是一串字符的话可用{}括起来表示
    • 根号:\sqrt3{x} -> $\sqrt3{x}$

    • 省略号: 在下面\dots -> $\dots$ 在中间\cdots -> $\cdots$

    • 方框: \boxed{example} -> $\boxed{example}$ (还有一个\fbox与此类似 \fobx{example} -> $\fbox{example}$)

    • 字体加粗: \mathbf{example} -> $\mathbf{example}$

    • 字体斜体且加粗: \boldsymbol{example} -> $\boldsymbol{example}$

    • 插入普通文本(自适应大小): \text{测试} -> $\text{测试}$

      specialsign.png specialsign2.png


    一些基本符号

    • 求和: \sum_1^n -> $\sum_1^n$

    • 积分: \int_1^n -> $\int_1^n$ \iint -> $\iint$ 以此类推$\cdots$

    • 极限: \lim_{x \to +\infty} -> $\lim_{x \to +\infty}$

    • 分数: \frac{1}{2} -> $\frac{1}{2}$ 如果要写多层分数可以用\cfrac (可以避免字母逐层缩小的限制)

    • 组合数: \binom{5}{2} -> $\binom{5}{2}$

    • 下取整: \lfloor{x}\rfloor -> $\lfloor{x}\rfloor$

    • 下取整: \lceil{x}\rceil -> $\lceil{x}\rceil$

      qita.png

      qita2.png


    关于矩阵和行列式

    • 矩阵:用法如下,元素中间使用&来分割同行元素,用\\来换行
    \begin{matrix}
     	1 & 2 & 3\\
     	4 & 5 & 6\\
    @@ -64,5 +64,5 @@
     
    + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/posts/107/index.html b/posts/107/index.html index 27e5fbbf..8c582268 100644 --- a/posts/107/index.html +++ b/posts/107/index.html @@ -1,110 +1,269 @@ 数据库的一些基础知识总结 | Zs's Blog -

    数据库的一些基础知识总结

    了解SQL

    一.什么是SQL

    SQL是结构化查询语言(Structured Query Language)的缩写。是一种专门用来与数据库通信的语言。

    二.什么是数据库?

    数据库(Database):保存有组织的数据的容器(通常是一个文件或一组文件)。 + + + +参考链接 + +数据库设计三大范式_dosthing +数据库设计三大范式_张龙豪 +mysql必知必会 +">

    数据库的一些基础知识总结

    了解SQL

    一.什么是SQL

    SQL是结构化查询语言(Structured Query Language)的缩写。是一种专门用来与数据库通信的语言。

    二.什么是数据库?

    数据库(Database):保存有组织的数据的容器(通常是一个文件或一组文件)。 ​[scode type = “yellow”]需要注意的是,有时候我们把数据库软件也简称为数据库,但是数据库软件和数据库有本质区别,数据库软件应称为DBMS(数据库管理系统),我们通过数据库软件对数据库进行删减等操作,他代替你操作和访问数据库。[/scode]

    三.数据库的组成

    • 数据库中通常有多张表,这类似于一个清单。就好像我们管理两个班级就可以用两个表单。

      表单之间用表名区分,在同一个数据库中不能有两个具有相同表名的表单。

    • 行(又称记录)

      在表中可以有很多行,我们可以把表看成一个二维数组。每一行代表了一个成员。

    • 每一行有好多列,一列可以代表着成员的一个属性,例如id,班级,姓名等等······

    • 数据类型

      每一列都有着特定的数据类型,例如字符串和数字就是两种不同的数据类型。

    • 主键(primary key)

      对于表中的每一行,我们都有一个唯一标识他的记号,这称作他的主键。

      可以发现,主键有以下特征:1.每一行都必须有一个主键,不能为空。2.不同行的主键不同。

      我们可以用多列作为主键,这样只需要确保多列组合起来的标识是唯一的。

    • 外键(foreign key)

      外键为某个表中的一列,它包含另一个表的主键值,定义了两个表之间的值,通过DBMS的操作可以将两个表联结起来。

      通俗点讲,好比有两张表,分别存储了所有供应商的信息,和所有产品的信息,在前面那张表定义了每个供应商的id,作为其主键。然后我们为每个产品定义外键的id,填上对应供应商的id,然后通过连结,我们就能知道每个产品供应商的详细信息了。

    • 可伸缩性(scale)

      能够适应不断增加的工作量而不失败。设计良好的数据库或应用程序称之为可伸缩性好(scale well)

    四.数据库的连结

    ​在上面我们讲外键的时候有讲到联结,连结的意思大概就是把多个表,根据一些命令串在一起。

    • 等值连结(内部连结)

      顾名思义,等值连结就是通过两个表之间元素值的相同来把两个表连结起来。

    • 自联结

      这个用于查找在同一表中某一特性相同的所有成员。有的时候自联结要比子查询快很多。

    • 自然联结

      在自然联结中,排除相同的列多次出现,使每个列只返回一次。

    • 外部联结

      联结包含了那些在相关表中没有关联行的行。这种类型的联结称为外部连结。

    五.数据库设计范式

    范式:当一个关系中的所有分类都是不可再分的数据项时,该关系是规范化的。不可再分的数据项,即不存在组合数据项和多项数据项。一个低一级的关系模式,通过模式分解可以转换为若干高一级范式的关系模式的集合,这个过程就叫规范化。

    1. 第一范式:当关系模式R的所有属性都不能在分解为更基本的数据单位时,称R是满足第一范式的,简记为1NF。满足第一范式是关系模式规范化的最低要求,否则,将有很多基本操作在这样的关系模式中实现不了。

    2. 第二范式:如果关系模式R满足第一范式,并且R得所有非主属性都完全依赖于R的每一个候选关键属性,称R满足第二范式,简记为2NF。

    3. 第三范式:设R是一个满足第一范式条件的关系模式,X是R的任意属性集,如果X非传递依赖于R的任意一个候选关键字,称R满足第三范式,简记为3NF。

      用我们学长的一句话,范式不是必须满足的,但是我们尽量按照范式来设计数据库,毕竟这是这么多程序员实战经验总结出来的。


    参考链接

    + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/posts/114/index.html b/posts/114/index.html index 59845df1..ab4c778f 100644 --- a/posts/114/index.html +++ b/posts/114/index.html @@ -8,7 +8,7 @@ 只有一个地方是和版本有关系的,在配置链接器的 opencv_wordxyzd.lib 时,大家一定要注意!!">

    Visual Studio 2019 中 OpenCV 配置教程

    Windows 平台 Visual Studio 2019 中 OpenCV 配置教程

    前言

    我这里配置用的是4.5.0版本,但实际配置过程中需要的大部分时间只是路径,因此和版本基本无关。

    只有一个地方是和版本有关系的,在配置链接器的 opencv_wordxyzd.lib 时,大家一定要注意!!

    1.下载OpenCV

    首先我们进入 https://opencv.org/releases/ 在这其中下载OpenCV ,我这里下载的4.5.0 ,选择Windows下载即可。

    下载结束后我们双击安装包,指定解压目录,我这里解压在了我的G盘,具体路径为 G:\Opencv450

    2.设置OpenCV的环境变量

    我们在 此电脑右键 -> 属性 -> 高级系统设置 -> 环境变量 -> 系统变量 -> 双击Path ->添加如下的环境

    G:\Opencv450\build\x64\vc15\bin ,这里的路径是根据上面那个路径来看的,如果你上面那个跟我不同,也请看请自己的路径。

    此电脑属性中的高级系统设置

    高级系统设置中的环境变量

    双击系统环境变量中的Path

    新建并加入我们的bin路径

    配置Visual Studio

    1. 新建一个C++类型的空项目,随便你如何命名,将模式调节为 Debug x64

    新建空项目并将模式调节为Debug x64

    1. 依次点击 视图 -> 其他窗口 -> 属性管理器

      在打开的 属性管理器 中添加新项目属性表,我是4.5.0的版本,为了好记,新建属性表命名为OpenCV450Debug

    新建一个属性表

    1. 建好以后在其上右键,选择属性 ,然后依次选择 VC++ 目录 -> 包含目录 -> 编辑

      添加下面两个路径,当然,这两个路径也是取决于你安装OpenCV的路径的。

      G:\Opencv450\build\include

      G:\Opencv450\build\include\opencv2

      更改VC++中的包含目录

      更改包含目录中的内容

    2. 接下来选择 VC++ 目录 中的 库目录 -> 编辑 ,然后添加(与你OpenCV路径对应)

      G:\Opencv450\build\x64\vc15\lib

      编辑VC++目录中库目录

    3. 接下来选择 链接器 -> 输入 -> 附加依赖项 -> 编辑

      在其中加入 opencv_world450d.lib ! 大家这里请注意,不同的版本这里的添加名称不同,通常来说如果你的版本是 x.y.z 那么就是 opencv_worldxyzd.lib

      附加依赖项

    4. 最后我们点击确定,然后退出属性编辑器

    测试OpenCV的配置

    • 在源文件中添加一个 C++ 源程序,我添加的为 main.cpp

      在其中输入如下测试代码

      #include <iostream>
      +只有一个地方是和版本有关系的,在配置链接器的 opencv_wordxyzd.lib 时,大家一定要注意!!">

      Visual Studio 2019 中 OpenCV 配置教程

      Windows 平台 Visual Studio 2019 中 OpenCV 配置教程

      前言

      我这里配置用的是4.5.0版本,但实际配置过程中需要的大部分时间只是路径,因此和版本基本无关。

      只有一个地方是和版本有关系的,在配置链接器的 opencv_wordxyzd.lib 时,大家一定要注意!!

      1.下载OpenCV

      首先我们进入 https://opencv.org/releases/ 在这其中下载OpenCV ,我这里下载的4.5.0 ,选择Windows下载即可。

      下载结束后我们双击安装包,指定解压目录,我这里解压在了我的G盘,具体路径为 G:\Opencv450

      2.设置OpenCV的环境变量

      我们在 此电脑右键 -> 属性 -> 高级系统设置 -> 环境变量 -> 系统变量 -> 双击Path ->添加如下的环境

      G:\Opencv450\build\x64\vc15\bin ,这里的路径是根据上面那个路径来看的,如果你上面那个跟我不同,也请看请自己的路径。

      此电脑属性中的高级系统设置

      高级系统设置中的环境变量

      双击系统环境变量中的Path

      新建并加入我们的bin路径

      配置Visual Studio

      1. 新建一个C++类型的空项目,随便你如何命名,将模式调节为 Debug x64

      新建空项目并将模式调节为Debug x64

      1. 依次点击 视图 -> 其他窗口 -> 属性管理器

        在打开的 属性管理器 中添加新项目属性表,我是4.5.0的版本,为了好记,新建属性表命名为OpenCV450Debug

      新建一个属性表

      1. 建好以后在其上右键,选择属性 ,然后依次选择 VC++ 目录 -> 包含目录 -> 编辑

        添加下面两个路径,当然,这两个路径也是取决于你安装OpenCV的路径的。

        G:\Opencv450\build\include

        G:\Opencv450\build\include\opencv2

        更改VC++中的包含目录

        更改包含目录中的内容

      2. 接下来选择 VC++ 目录 中的 库目录 -> 编辑 ,然后添加(与你OpenCV路径对应)

        G:\Opencv450\build\x64\vc15\lib

        编辑VC++目录中库目录

      3. 接下来选择 链接器 -> 输入 -> 附加依赖项 -> 编辑

        在其中加入 opencv_world450d.lib ! 大家这里请注意,不同的版本这里的添加名称不同,通常来说如果你的版本是 x.y.z 那么就是 opencv_worldxyzd.lib

        附加依赖项

      4. 最后我们点击确定,然后退出属性编辑器

      测试OpenCV的配置

      • 在源文件中添加一个 C++ 源程序,我添加的为 main.cpp

        在其中输入如下测试代码

        #include <iostream>
         #include <opencv2/core.hpp>
         #include <opencv2/imgcodecs.hpp>
         #include <opencv2/highgui.hpp>
        @@ -37,5 +37,5 @@
         
      + PaperMod | 鲁ICP备2020034310号
      \ No newline at end of file diff --git a/posts/136/index.html b/posts/136/index.html index 7880ea95..2523aca6 100644 --- a/posts/136/index.html +++ b/posts/136/index.html @@ -1,26 +1,170 @@ “程序星编程之路”第二次作业题解 | Zs's Blog - #include //我们需要用到sqrt函数,因此需要引入数学库 int main() { int n; bool flag = false; // 标记 i 是否满足条件 scanf("%d",&n); for(int i=1;i<=n;i++) { flag = true; int p=i,j=0; while(p) // 将 p 反转为 j { j=j*10+p%10; p/=10; } if(j==i) { if(j==1) continue; // 特判 1 if(j==2) // 特判 2 { printf("2\n"); continue; } int sqrtj = sqrt(j); for(int k=2;k<=sqrtj;k++) // 枚举 [2,sqrt(n)] { if(j%k==0) // 如果能够整除(余数为0),那么是 j 的因子 { flag = false; break; } } if(flag) { printf("%d\n",j); } } } } 其他 因为我们讲到这里的时候,我们没讲函数,但是这道题如果我们把判断是否为回文数,判断是否为质数,都另成一个函数模块,将使得程序变得更加简洁。我在这里也将函数版本的贴出来,有兴趣的可以看一下。'>

      “程序星编程之路”第二次作业题解

      “程序星编程之路”第二次作业题解

      A. Zs的回文质数

      题目描述

      读入一个整数 $n$ ,输出 $[1,n]$ 的所有回文质数,我们规定 $1\sim9$ 也是回文数。

      思路

      首先我们需要了解什么是回文数,以及什么是质数

      简单点说,回文数就是正着读反着读都是一样的,也就是对称的,形如 $abcba $ 或者 $123321$ 这样的。

      质数的话,对于一个数 $n$ ,如果他是质数,那它除了 $1$ 和 $n$ 没有其他因子。例如 $2,3,5,7,11$ 这样的。

      那么接下来我们考虑一下解决这个问题应该怎么做,首先我们看一下数据范围,$[1,100000]$ ,还是挺小的,我们可以考虑直接枚举每一个数来判断它是不是回文数,然后再判断一下是不是质数,如果两个都满足,我们就输出它。

      判断回文数,我们可以考虑到 NOJ05 幸运数 一题的解题思路,也就是说我们把一个数倒置过来,好比一个数 $xyz$ 倒置成 $zyx$ ,然后判断是否 $xyz == zyx$ ,如果相等的话就是回文数,如果不相等就不是。

      判断质数,我们可以在 $[2,\lfloor\sqrt{n}\rfloor]$ 枚举它的因子,这个的完备性我上课的时候证明过,不再赘述。这里需要注意 $1,2$ 需要特判一下。

      代码

      #include<stdio.h>
      +代码
      +#include
      +#include  //我们需要用到sqrt函数,因此需要引入数学库
      +
      +int main()
      +{
      +    int n;
      +    bool flag = false;  // 标记 i 是否满足条件
      +    scanf("%d",&n);
      +    for(int i=1;i<=n;i++)
      +    {
      +        flag = true;
      +        int p=i,j=0;
      +        while(p)   // 将 p 反转为 j 
      +        {
      +            j=j*10+p%10;
      +            p/=10;
      +        }
      +        if(j==i)
      +        {
      +            if(j==1) continue; // 特判 1
      +            if(j==2)           // 特判 2
      +            {
      +                printf("2\n");
      +                continue;
      +            }
      +            int sqrtj = sqrt(j);
      +            for(int k=2;k<=sqrtj;k++)  // 枚举 [2,sqrt(n)]
      +            {
      +                if(j%k==0)         // 如果能够整除(余数为0),那么是 j 的因子
      +                {
      +                    flag = false;
      +                    break;
      +                }
      +            }
      +            if(flag)
      +            {
      +                printf("%d\n",j);
      +            }
      +        }
      +        
      +    }
      +}
      +其他
      +因为我们讲到这里的时候,我们没讲函数,但是这道题如果我们把判断是否为回文数,判断是否为质数,都另成一个函数模块,将使得程序变得更加简洁。我在这里也将函数版本的贴出来,有兴趣的可以看一下。'>

      “程序星编程之路”第二次作业题解

      “程序星编程之路”第二次作业题解

      A. Zs的回文质数

      题目描述

      读入一个整数 $n$ ,输出 $[1,n]$ 的所有回文质数,我们规定 $1\sim9$ 也是回文数。

      思路

      首先我们需要了解什么是回文数,以及什么是质数

      简单点说,回文数就是正着读反着读都是一样的,也就是对称的,形如 $abcba $ 或者 $123321$ 这样的。

      质数的话,对于一个数 $n$ ,如果他是质数,那它除了 $1$ 和 $n$ 没有其他因子。例如 $2,3,5,7,11$ 这样的。

      那么接下来我们考虑一下解决这个问题应该怎么做,首先我们看一下数据范围,$[1,100000]$ ,还是挺小的,我们可以考虑直接枚举每一个数来判断它是不是回文数,然后再判断一下是不是质数,如果两个都满足,我们就输出它。

      判断回文数,我们可以考虑到 NOJ05 幸运数 一题的解题思路,也就是说我们把一个数倒置过来,好比一个数 $xyz$ 倒置成 $zyx$ ,然后判断是否 $xyz == zyx$ ,如果相等的话就是回文数,如果不相等就不是。

      判断质数,我们可以在 $[2,\lfloor\sqrt{n}\rfloor]$ 枚举它的因子,这个的完备性我上课的时候证明过,不再赘述。这里需要注意 $1,2$ 需要特判一下。

      代码

      #include<stdio.h>
       #include<math.h>  //我们需要用到sqrt函数,因此需要引入数学库
       
       int main()
      @@ -186,5 +330,5 @@
       
      + PaperMod | 鲁ICP备2020034310号
      \ No newline at end of file diff --git a/posts/141/index.html b/posts/141/index.html index 44ca9002..1179698a 100644 --- a/posts/141/index.html +++ b/posts/141/index.html @@ -1,50 +1,137 @@ Ubuntu18.04优化教程 | Zs's Blog -

      Ubuntu18.04优化教程

      前言

      因为最近Ubuntu用的比较频繁,所以前一阵把Ubuntu16.04换成Ubuntu18.04了,并且囿于机械硬盘那启动速度,我忍痛割爱把我80G的固态硬盘分给了Ubuntu。

      后来,用着用着就觉得这个Ubuntu的原始界面确实不是特别的好看,配色偏基佬紫的感觉。“工欲善其事,必先利其器“,我们只有将自己的工作环境布置的舒心一些才能有做下去的动力!所以我想给Ubuntu换一个看起来舒服点的界面,然后上网找教程乱七八糟的倒腾了一会,感觉换完以后完全不一样了,这个界面真的好看!!用起来也特别的舒心,感觉自己马上就要告别Windows投奔Linux的怀抱了。后续还有一些其他的优化,例如装QQ、微信、配置终端等,一并写在这里吧。

      Ubuntu界面的优化

      具体效果

      先放几张效果图上来,是我改后的界面。大概就是这样(自我感觉挺好看的),当然也有其他的主题可供选择。

      桌面风格

      文件夹风格

      效果图

      1.安装GNOME桌面环境主题配置工具

      如果要改主题,那么首先要有一个利器,这里我用的Ubuntu18.04,桌面环境为 GNOME 3.28.2 ,因为我目前接触的只有GNOME桌面环境的,Ubuntu18.04本来的桌面环境就是GNOME,但是Ubuntu16.04好像没有自带,但是可以安装,这里大家可以自行百度了解。

      然后我们已经有了GNOME桌面环境后,安装主题配置工具 GNOME Tweaks ,在终端中输入如下内容:

      sudo apt-get update
      +5.我自己的配置
      +theme&shell   Canta-light-compact
      +icons 01-McMojave-circle
      +6.界面修改的参考链接
      +
      +Ubuntu18.04美化主题(mac主题)
      +Ubuntu18.04美化主题(完整版)
      +GNOME-LOOK.ORG
      +30个非常不错的Ubuntu主题供你选择
      +ubuntu18.04更换鼠标游标主题
      +
      +配置终端
      +前言
      +唔,终端本来用起来感觉也还行,感觉终端就是linux的灵魂,啥都能干。">

      Ubuntu18.04优化教程

      前言

      因为最近Ubuntu用的比较频繁,所以前一阵把Ubuntu16.04换成Ubuntu18.04了,并且囿于机械硬盘那启动速度,我忍痛割爱把我80G的固态硬盘分给了Ubuntu。

      后来,用着用着就觉得这个Ubuntu的原始界面确实不是特别的好看,配色偏基佬紫的感觉。“工欲善其事,必先利其器“,我们只有将自己的工作环境布置的舒心一些才能有做下去的动力!所以我想给Ubuntu换一个看起来舒服点的界面,然后上网找教程乱七八糟的倒腾了一会,感觉换完以后完全不一样了,这个界面真的好看!!用起来也特别的舒心,感觉自己马上就要告别Windows投奔Linux的怀抱了。后续还有一些其他的优化,例如装QQ、微信、配置终端等,一并写在这里吧。

      Ubuntu界面的优化

      具体效果

      先放几张效果图上来,是我改后的界面。大概就是这样(自我感觉挺好看的),当然也有其他的主题可供选择。

      桌面风格

      文件夹风格

      效果图

      1.安装GNOME桌面环境主题配置工具

      如果要改主题,那么首先要有一个利器,这里我用的Ubuntu18.04,桌面环境为 GNOME 3.28.2 ,因为我目前接触的只有GNOME桌面环境的,Ubuntu18.04本来的桌面环境就是GNOME,但是Ubuntu16.04好像没有自带,但是可以安装,这里大家可以自行百度了解。

      然后我们已经有了GNOME桌面环境后,安装主题配置工具 GNOME Tweaks ,在终端中输入如下内容:

      sudo apt-get update
       sudo apt-get install gnome-tweak-tool 
       

      我们先更新软件源,然后安装后直接打开他就行,在系统软件中中文大概叫 优化

      2.拓展上述工具

      安装完上述工具后,我们可能发现了一个问题,就是外观那一栏目的Shell有一个感叹号,无法更改,这是因为我们没有安装拓展导致的。我们在终端中运行

      sudo apt-get install gnome-shell-extensions
       

      然后重启一下电脑。再打开软件找到左侧的拓展,把 User themes 那一栏目打开。切换回去就可以发现Shell那边的感叹号无了。

      3.寻找自己喜欢的主题

      这里我大家可以去这个网址去找自己喜欢的 GNOME-LOOK.ORG

      这里面包含了图标,主题这些,下面介绍一下如何安装。

      好比我们找到一个自己喜欢的主题,然后我们点击下面的 Files ,可能会有很多文件,但是多是同一个主题的不同风格,好比暗风格和亮风格这样的,还有不同的版本的,我多是安装那个下载量最多的,我们下载那个对应的文件(多是tar.xz安装包)。

      对于主题的安装,我们只需要把解压出来的文件,移动或复制到 /usr/share/themes/ 目录下,如果是光标\图标的安装,那么就把文件夹移动到 /usr/share/icons 目录下。

      然后我们回到 GNOME Tweaks 软件中就可以发现,我们已经可以在主题\图标\光标\Shell清单中找到我们移动到文件夹中的文件了,然后选择就可以切换了。这里需要注意的,很多主题都是自带Shell的,你下了一个主题,那么你可以在Shell和主题这两个栏目中都找到他们,是一个配套的。

      4.一些后续的调整

      我们后续可以改变左边收藏夹的位置,我觉得放在左边有一丢丢的丑,所以我选择把它放在的下面。

      我们去Ubuntu软件中搜索 Dash to dock,然后安装这个拓展,然后打开 GNOME Tweaks 软件在拓展中找到他就可以随心所欲的调我们的收藏夹的位置了。

      5.我自己的配置

      theme&shell   Canta-light-compact
      @@ -61,5 +148,5 @@
       
      + PaperMod | 鲁ICP备2020034310号
      \ No newline at end of file diff --git a/posts/157/index.html b/posts/157/index.html index 77f30403..b59f29b4 100644 --- a/posts/157/index.html +++ b/posts/157/index.html @@ -1,74 +1,158 @@ Git的简易教程 | Zs's Blog -

      Git的简易教程

      前言

      最近在复习Git,因此顺手做个笔记分享出来,方便大家学习和查阅。相信无论是以后的课程作业还是工作,我们都会或多或少的接触/用到Git。

      什么是Git?

      Git你可能没听说过,但是我相信你应该听说过Github,毕竟是全球最大的同性交友网站。他和Git有着密不可分的联系,我们后续再详细介绍。

      Git的中文全称叫 分布式版本控制系统 ,版本控制系统是什么意思呢?我们举一个简单的例子,你在做一个大作业,很可能要写上千行的代码,但是你可能写完一个功能以后,对他不够满意,但是又害怕改了以后后悔了,又找不回来了,所以你可能就有很多版本,版本1,版本2,版本3等等等。Git就是解决这个问题的,让你文件能够保持最新,但是又能恢复到之前的版本。

      那么既然有分布式版本控制系统,就有 集中式版本控制系统,前者的代表是 Git ,后者的代表有 SVN、CVS 等。

      关于两者的区别,对于集中式版本控制系统,如果你想要对做一个项目的内容做修改,那么你要先从中央服务器把最近的版本拉取(Pull)下来,然后修改完以后,把修改后的版本推送(Push)上去,你本地只有最新的版本,而没有完整的版本库,分布式版本控制系统所作的工作与集中式的相差不大,只是它的本地会有一个完整的版本库,因此它十分的安全。

      这里贴一个他人总结的区别,供大家参考。

      集中式与分布式版本控制系统的区别

      Git的安装

      • Linux系统

        因为我只用过Ubuntu,所以我只会Ubuntu的QAQ..

        Ubuntu中安装Git只需要在终端中输入 sudo apt-get install git 即可。

        如果是其他的linux系统,我猜你在终端中输入git即可获得安装提示,不然的话借助搜索引擎也可以。

      • Windows系统

        直接去 Git官网 下载安装程序然后安装即可。关于安装时候的选项,我都是用的默认的。

      • Mac OS

        太穷了,没用过Mac,但是参考链接中给出了方法,大家有需求可以参考。

      Git的基本使用

      Git可以做许多事情,好比版本更新,版本修改,提交到远程仓库等等,这里我们只写一写大概以后用的会比较多的。

      需要注意的是,我们安装以后大概会有一个 Git GUI 还有一个 Git Bash ,开发中多用 Git Bash,下面的教程也是基于Git Bash的。

      • 表明身份

        在Git所有仓库中我们都要有一个所有者的身份,用于标识是谁的仓库,用如下方式标识

        git config --global user.name "Your Name"
        +
        +一个是 工作区 ,这个就是我们本地的文件夹。
        +一个是 暂存区 ,这是我们把文件暂时放到暂存区里,没有决定更新我们的版本。
        +一个是 最终分支,这就是我们最终的版本存放的位置。
        +
        +贴一张廖雪峰老师教程中的一张图,我觉得还挺形象的。'>

        Git的简易教程

        前言

        最近在复习Git,因此顺手做个笔记分享出来,方便大家学习和查阅。相信无论是以后的课程作业还是工作,我们都会或多或少的接触/用到Git。

        什么是Git?

        Git你可能没听说过,但是我相信你应该听说过Github,毕竟是全球最大的同性交友网站。他和Git有着密不可分的联系,我们后续再详细介绍。

        Git的中文全称叫 分布式版本控制系统 ,版本控制系统是什么意思呢?我们举一个简单的例子,你在做一个大作业,很可能要写上千行的代码,但是你可能写完一个功能以后,对他不够满意,但是又害怕改了以后后悔了,又找不回来了,所以你可能就有很多版本,版本1,版本2,版本3等等等。Git就是解决这个问题的,让你文件能够保持最新,但是又能恢复到之前的版本。

        那么既然有分布式版本控制系统,就有 集中式版本控制系统,前者的代表是 Git ,后者的代表有 SVN、CVS 等。

        关于两者的区别,对于集中式版本控制系统,如果你想要对做一个项目的内容做修改,那么你要先从中央服务器把最近的版本拉取(Pull)下来,然后修改完以后,把修改后的版本推送(Push)上去,你本地只有最新的版本,而没有完整的版本库,分布式版本控制系统所作的工作与集中式的相差不大,只是它的本地会有一个完整的版本库,因此它十分的安全。

        这里贴一个他人总结的区别,供大家参考。

        集中式与分布式版本控制系统的区别

        Git的安装

        • Linux系统

          因为我只用过Ubuntu,所以我只会Ubuntu的QAQ..

          Ubuntu中安装Git只需要在终端中输入 sudo apt-get install git 即可。

          如果是其他的linux系统,我猜你在终端中输入git即可获得安装提示,不然的话借助搜索引擎也可以。

        • Windows系统

          直接去 Git官网 下载安装程序然后安装即可。关于安装时候的选项,我都是用的默认的。

        • Mac OS

          太穷了,没用过Mac,但是参考链接中给出了方法,大家有需求可以参考。

        Git的基本使用

        Git可以做许多事情,好比版本更新,版本修改,提交到远程仓库等等,这里我们只写一写大概以后用的会比较多的。

        需要注意的是,我们安装以后大概会有一个 Git GUI 还有一个 Git Bash ,开发中多用 Git Bash,下面的教程也是基于Git Bash的。

        • 表明身份

          在Git所有仓库中我们都要有一个所有者的身份,用于标识是谁的仓库,用如下方式标识

          git config --global user.name "Your Name"
           git config --global user.email "Your email"
           
        • 创建版本库

          我们想要把一个文件夹的内容用git来管理,只需要在文件夹目录运行

          git init
           

          顾名思义这就是一个初始化的过程,运行以后在当前目录生成一个 .git 文件夹,里面是我们版本控制的数据,一般不要修改。

        • 把文件添加到Git的暂存区

          这里出现了 暂存区 这个名词,Git内部的逻辑大概把我们工作的过程分为了三部分

          1. 一个是 工作区 ,这个就是我们本地的文件夹。
          2. 一个是 暂存区 ,这是我们把文件暂时放到暂存区里,没有决定更新我们的版本。
          3. 一个是 最终分支,这就是我们最终的版本存放的位置。

          贴一张廖雪峰老师教程中的一张图,我觉得还挺形象的。

          git-repo

          我们清楚了上面的三个分区,那么考虑一下如何把文件夹中的文件从工作区推到暂存区,通过如下命令

          git add filepath
          @@ -88,5 +172,5 @@
           
        + PaperMod | 鲁ICP备2020034310号
        \ No newline at end of file diff --git a/posts/16/index.html b/posts/16/index.html index 1c5f2e1e..a9c88236 100644 --- a/posts/16/index.html +++ b/posts/16/index.html @@ -8,7 +8,7 @@ 在长方形框中,最多有 n ($0\le{n}\le6$)个相异点,在框中点上依次放置可扩展的油滴,当碰到其他油滴边界或者长方形边框时会停止,扩展呈圆形展开。放置下一个时会确保上一个已经扩展完成。问通过变换放置顺序可使得最终框中剩下的面积最小为多少。">

        洛谷的一些搜索题

        1. P1378 油滴扩展


        题意

        在长方形框中,最多有 n ($0\le{n}\le6$)个相异点,在框中点上依次放置可扩展的油滴,当碰到其他油滴边界或者长方形边框时会停止,扩展呈圆形展开。放置下一个时会确保上一个已经扩展完成。问通过变换放置顺序可使得最终框中剩下的面积最小为多少。


        思路

        这是个裸的dfs,情况最多也就 $6! = 720$ 种,所以我们可以只需要设置一个vis数组来记录是否已经放置过这个油滴,计算已扩展油滴和将要放的油滴之间的距离可以用 两点距离-扩展油滴的半径来实现 ,但是有个坑需要注意,就是当一个油滴已经放在已经有扩展油滴覆盖的区域,那么他俩的距离是0,而不是负数,因此在计算半径的时候需要优化一下。


        代码实现

        #include<cstdio>
        +在长方形框中,最多有 n ($0\le{n}\le6$)个相异点,在框中点上依次放置可扩展的油滴,当碰到其他油滴边界或者长方形边框时会停止,扩展呈圆形展开。放置下一个时会确保上一个已经扩展完成。问通过变换放置顺序可使得最终框中剩下的面积最小为多少。">

        洛谷的一些搜索题

        1. P1378 油滴扩展


        题意

        在长方形框中,最多有 n ($0\le{n}\le6$)个相异点,在框中点上依次放置可扩展的油滴,当碰到其他油滴边界或者长方形边框时会停止,扩展呈圆形展开。放置下一个时会确保上一个已经扩展完成。问通过变换放置顺序可使得最终框中剩下的面积最小为多少。


        思路

        这是个裸的dfs,情况最多也就 $6! = 720$ 种,所以我们可以只需要设置一个vis数组来记录是否已经放置过这个油滴,计算已扩展油滴和将要放的油滴之间的距离可以用 两点距离-扩展油滴的半径来实现 ,但是有个坑需要注意,就是当一个油滴已经放在已经有扩展油滴覆盖的区域,那么他俩的距离是0,而不是负数,因此在计算半径的时候需要优化一下。


        代码实现

        #include<cstdio>
         #include<cstring>
         #include<algorithm>
         #include<cmath>
        @@ -197,5 +197,5 @@
         
        + PaperMod | 鲁ICP备2020034310号
        \ No newline at end of file diff --git a/posts/164/index.html b/posts/164/index.html index f1dc7258..0fc5d2b0 100644 --- a/posts/164/index.html +++ b/posts/164/index.html @@ -1,44 +1,155 @@ 如何使用CenterNet做3D目标检测测试 | Zs's Blog -

        如何使用CenterNet做3D目标检测测试

        CenterNet—Objects as Points介绍

        CenterNet是一个anchor-free的目标检测网络,与YOLOv3相比,精度有所提升,此外他不仅能够用于2D目标检测,也能够用于人体姿态识别,3D目标检测等···

        安装CenterNet

        ​其实安装CenterNet的过程就是一个配置环境的问题,直接跟着官方给出的这里Install.md配置一下即可,十分推荐使用Conda来管理环境,这里给出我的环境给大家参考一下:

        Ubuntu = 18.04 LTS

        pytorch = 1.2.0

        python = 3.6.12

        torchvision = 0.4.0

        cuda = 10.2

        ​需要注意的是:

        • 官方给出的教程里面使用的是 pytorch 0.4.1,但是我个人在实测过程中遇到了一些问题,遂安装网上的教程更改为 pytorch 1.2.0,并且需要把 ${CenterNet_Root}/src/lib/models/networks/DCNv2 中的这个DCNv2网络更改为官方的最新版。
        • 这里使用的cuda版本最好和你的显卡匹配,之前因为显卡驱动的一些问题导致重装了电脑,根据我们学长学姐的建议,最好直接去cuda官网那边去下载deb包直接安装。
        • 遇到环境配置问题可以先去Google一下,一般作者都在CenterNet’s Issues中给出了回复,如果没有,可以发邮件给作者询问,当然也可以发消息/邮箱给我,大家一起探讨一下~

        运行CenterNet的demo

        ​想要运行demo,首先要去 Model zoo 中下载一下我们需要使用的model,2D目标检测使用的是 ctdet_coco_dla_2x.pth ,人体姿态评估使用的是 multi_pose_dla_3x.pth ,下载后统一将他们放在CenterNet根目录中的model文件夹中。

        ​然后使用conda切换到CenterNet的环境,在终端中运行:

        python demo.py ctdet --demo ${CenterNet_Root}/images/17790319373_bd19b24cfc_k.jpg --load_model ../models/ctdet_coco_dla_2x.pth 
        +
        +
        +运行CenterNet的3D目标检测
        +配置数据集和模型
        +​我们可以直接参考官方的 DATA.md 来配置我们的数据集。
        +​然后到 Model zoo 下载3D检测使用的模型 ddd_3dop.pth 。
        +​这里说一下遇到的几个坑:
        +
        +
        +首先是配置数据集的过程中,我们需要配置的目录结构如图所示(官方给出的结构树有点模糊不清的感觉)
        +.
        +├── ImageSets_3dop
        +│   ├── test.txt
        +│   ├── train.txt
        +│   ├── trainval.txt
        +│   └── val.txt
        +├── ImageSets_subcnn
        +│   ├── test.txt
        +│   ├── train.txt
        +│   ├── trainval.txt
        +│   └── val.txt
        +└── training
        +       ├── calib
        +       ├── image_2
        +       └── label_2
        +
        +
        +然后去到 ${CenterNet_ROOT}/src/tools目录下,运行 python convert_kitti_to_coco.py  将 kitti 数据集转换为 coco 数据集的格式,不出意外应该会报错如下:">

        如何使用CenterNet做3D目标检测测试

        CenterNet—Objects as Points介绍

        CenterNet是一个anchor-free的目标检测网络,与YOLOv3相比,精度有所提升,此外他不仅能够用于2D目标检测,也能够用于人体姿态识别,3D目标检测等···

        安装CenterNet

        ​其实安装CenterNet的过程就是一个配置环境的问题,直接跟着官方给出的这里Install.md配置一下即可,十分推荐使用Conda来管理环境,这里给出我的环境给大家参考一下:

        Ubuntu = 18.04 LTS

        pytorch = 1.2.0

        python = 3.6.12

        torchvision = 0.4.0

        cuda = 10.2

        ​需要注意的是:

        • 官方给出的教程里面使用的是 pytorch 0.4.1,但是我个人在实测过程中遇到了一些问题,遂安装网上的教程更改为 pytorch 1.2.0,并且需要把 ${CenterNet_Root}/src/lib/models/networks/DCNv2 中的这个DCNv2网络更改为官方的最新版。
        • 这里使用的cuda版本最好和你的显卡匹配,之前因为显卡驱动的一些问题导致重装了电脑,根据我们学长学姐的建议,最好直接去cuda官网那边去下载deb包直接安装。
        • 遇到环境配置问题可以先去Google一下,一般作者都在CenterNet’s Issues中给出了回复,如果没有,可以发邮件给作者询问,当然也可以发消息/邮箱给我,大家一起探讨一下~

        运行CenterNet的demo

        ​想要运行demo,首先要去 Model zoo 中下载一下我们需要使用的model,2D目标检测使用的是 ctdet_coco_dla_2x.pth ,人体姿态评估使用的是 multi_pose_dla_3x.pth ,下载后统一将他们放在CenterNet根目录中的model文件夹中。

        ​然后使用conda切换到CenterNet的环境,在终端中运行:

        python demo.py ctdet --demo ${CenterNet_Root}/images/17790319373_bd19b24cfc_k.jpg --load_model ../models/ctdet_coco_dla_2x.pth 
         

        ​这里需要注意的是 --demo 后面的 ${CenterNet_Root}/images/17790319373_bd19b24cfc_k.jpg ,这里我使用的是官方给出的实例图片,它位于CenterNet根目录的images文件夹中,前面的 ${CenterNet_Root} 代表的是 CenterNet根目录,好比我的就位于 /home/zs/CenterNet

        ​如果不出意外的话效果应该如下图所示:

        2D目标检测效果

        运行CenterNet的3D目标检测

        配置数据集和模型

        ​我们可以直接参考官方的 DATA.md 来配置我们的数据集。

        ​然后到 Model zoo 下载3D检测使用的模型 ddd_3dop.pth

        ​这里说一下遇到的几个坑:

        • 首先是配置数据集的过程中,我们需要配置的目录结构如图所示(官方给出的结构树有点模糊不清的感觉)

          .
           ├── ImageSets_3dop
           │   ├── test.txt
          @@ -80,5 +191,5 @@
           
        + PaperMod | 鲁ICP备2020034310号
        \ No newline at end of file diff --git a/posts/169/index.html b/posts/169/index.html index 942714e7..c051db92 100644 --- a/posts/169/index.html +++ b/posts/169/index.html @@ -1,22 +1,37 @@ 关于Anaconda中pip路径指向问题 | Zs's Blog -

        关于Anaconda中pip路径指向问题

        前言

        最近使用Anaconda的时候遇到了一个很奇怪的问题,如当我新建环境 condatest 后,使用 pip -V 查看pip的路径指向,会发现pip指向的是另一个环境 CenterNet 的路径。搜索了很久得到一个有一些用的解决方法

        解决方案

        设有问题的环境为 condatest ,python版本为 3.6

        然后进入 ~/anaconda3/envs/condatest/lib/python3.6

        编辑目录下的 site.py 文件,将其中的 USER_SITE 的值修改为 /home/zs/anaconda3/envs/condatest ,注意这里路径里面的 zs 是你的当前用户名, USER_BASE 的值修改为 /home/zs/anaconda3/envs/condatest/lib/python3.6/site.py,然后问题应该就解决了。

        因为如果环境问题的话,上面两个字符串都为空,猜测的原因是因为有同python版本的环境导致默认指向错误,此方式为修改conda中pip的指向。

        参考链接

        \ No newline at end of file diff --git a/posts/17/index.html b/posts/17/index.html index 5d136660..cda0f0e9 100644 --- a/posts/17/index.html +++ b/posts/17/index.html @@ -17,7 +17,7 @@ 给出包含 n 个正整数的序列 a ,你可以把任何一个元素 $a_i$ ,赋值给另一个元素 $a_j$ ($i\neq j$) ,问通过任意此操作能否将序列 a 的和变为奇数。可以输出 YES ,不可以输入 NO. 思路 -首先当起始和为奇数的时候,就直接可输出 YES 了,如果是偶数的话,我们可以发现,如果序列元素中同时包含奇数和偶数,那么就是可以的,否则不可以。">

        Codeforces#617(Div.3)

        A. Array with Odd Sum


        题意

        给出包含 n 个正整数的序列 a ,你可以把任何一个元素 $a_i$ ,赋值给另一个元素 $a_j$ ($i\neq j$) ,问通过任意此操作能否将序列 a 的和变为奇数。可以输出 YES ,不可以输入 NO.


        思路

        首先当起始和为奇数的时候,就直接可输出 YES 了,如果是偶数的话,我们可以发现,如果序列元素中同时包含奇数和偶数,那么就是可以的,否则不可以。


        代码实现

        #include<cstdio>
        +首先当起始和为奇数的时候,就直接可输出 YES 了,如果是偶数的话,我们可以发现,如果序列元素中同时包含奇数和偶数,那么就是可以的,否则不可以。">

        Codeforces#617(Div.3)

        A. Array with Odd Sum


        题意

        给出包含 n 个正整数的序列 a ,你可以把任何一个元素 $a_i$ ,赋值给另一个元素 $a_j$ ($i\neq j$) ,问通过任意此操作能否将序列 a 的和变为奇数。可以输出 YES ,不可以输入 NO.


        思路

        首先当起始和为奇数的时候,就直接可输出 YES 了,如果是偶数的话,我们可以发现,如果序列元素中同时包含奇数和偶数,那么就是可以的,否则不可以。


        代码实现

        #include<cstdio>
         #include<cstring>
         #include<algorithm>
         #include<cmath>
        @@ -183,5 +183,5 @@
         
        + PaperMod | 鲁ICP备2020034310号
        \ No newline at end of file diff --git a/posts/173/index.html b/posts/173/index.html index c7a4649b..13a04785 100644 --- a/posts/173/index.html +++ b/posts/173/index.html @@ -1,43 +1,61 @@ 2021RoboMaster中国赛比赛记录 | Zs's Blog -

        2021RoboMaster中国赛比赛记录

        前言

        ​说起来的话今天距离比赛已经过去近一个月了,比赛结束一直想要记录一下and总结一下经验,但是实在是太懒了,临近五一假期,在四月的末尾为这次中国赛画一个句号吧。

        比赛过程

        ​如果没记错的话比赛是3.30号(周二)去,4.1号(周四)结束,共三天。但是因为第三天没做什么有意义的事情,就只记录两天了。

        第一天

        ​第一天大概中午十点到的吧,去的时候登记完领了牌,就在当地布置场地了。到了场地上才发现,我们好像是拿的东西最多的,包括外接显示屏和集成主机,好像都基本没人带过去····集成主机拿了过去也没怎么用到,本来预想用到的哨岗相机因为 ROS 的通信问题也没能跑成,最后两个机器人还是各跑各的策略了。

        ​调试的时候出了一点问题,两个哨岗相机通过20m的USB延长线后,只有一个能连接,后来排查了一下,好像是因为有一条线是光纤USB3.0的线,跟相机的接口不兼容···这个问题还没想好怎么解决,可能会考虑到时候自己带一根USB延长线过去。

        ​犹记得调试的时候是和青海大学一起调的,有点可惜的是调试中的我方机器人一直在一个地方鬼畜。那晚上我记得大家熬到了很晚···很可惜的视觉因为用的是学习的框架可调性很差,并没有帮上太大的忙。

        第二天

        ​第二天记得一共有三场比赛,分别是打哈工大,哈工大深圳,以及青海大学。

        ​在比赛过程中其实对视觉,我没有做太多的调整,主要还是大家在写导航和策略相关的东西吧。

        ​跟哈工大打的那一场二车因为没有写好启动判定被罚下了,一车因为点位有问题一直卡在障碍物上。

        ​跟哈工深和哈工大两场之间还隔了挺长时间,一个上午是一个下午,中间大家调试了很久,幸好在下午和哈工深打的时候基本没有鬼畜,可以正常的对局,只是因为实力不够强,很明显的一个问题就是视觉做的有问题吧,很多时间在朝着自己的队友打,还有就是会朝着场外的人员打,这是需要改进的点。

        ​跟青海大学打的那场,距和哈工深比赛结束只有十几分钟的间隔时间,大家调了一个小bug就又重新赶去检录了,虽然当时已知青海大学的战术是站在原地不动的,但是由于不知道哪里出问题了,比赛中前一分钟两车都没动,后一分钟二车虽然动起来了去吃了加成区,但是因为定位的一些问题,没有看到敌方机器人并且撞墙了··自己撞掉了60血,最后还是败了QAQ。

        ​所以就很耻辱的被3:0送走了,这样就结束了比赛日程。

        ​值得反思的事情很多吧,赛前虽然基本熬了一个多星期来调车,还是只在最后一天才开始连裁判系统联调,包括暑假效率不高等问题都是值得反思的···打完比赛心中大概已经有了一些改进点,也想把自己的一些调车心得等记录下来,但是因为时间以及学业上的一些事情等一直没去做,本来计划的五月初做好改进的视觉也一直没兑现,希望这个五一假期会有较大的突破吧,不过还要打数模···好累,不想动。

        最后,这一天还拿到了和Charm young的合照,还挺动容的,之前看Robomaster的一个宣传标语就是让工程师们成为明星,给他们一个展示的舞台,看到大家对Charm young的热情,深深的感受到了这一点。

        与Charmyoung的合影

        \ No newline at end of file diff --git a/posts/18/index.html b/posts/18/index.html index 5d7294ee..9b1b564c 100644 --- a/posts/18/index.html +++ b/posts/18/index.html @@ -20,7 +20,7 @@ 题意 已知序列 $a$ 有 $n$ 个数,通过取出其中一些数可以使他满足严格的先增再减序列,问最少取出几个。 -">

        基础线性dp例题

        前言


        某位大佬曾经说过,dp不会没问题,想不到状态转移方程没问题,多做题就会了。所以,我打算多刷点dp题。那么,先从基础刷起吧。

        1. P1091 合唱队形


        题意

        已知序列 $a$ 有 $n$ 个数,通过取出其中一些数可以使他满足严格的先增再减序列,问最少取出几个。


        思路

        很显然想要求最少取出几个,我们就看严格先增再减的序列的最长长度即可。我们可以用 $g[i]$ 来存储到 $a[i]$ 为止的最长递增子序列的长度,然后用 $l[i]$ 来存储从 $a[i]$ 到序列末尾最长的递减子序列的长度。处理 $g[i]$ 从前往后扫,处理 $l[i]$ 需要从后往前扫。处理完 $f$ 和 $g$ 数组那么就从左到右扫一遍,$ans=max(ans,g[i]+l[i]-1)$ 。答案即是 $n-ans$ 。


        代码实现

        #include<cstdio>
        +">

        基础线性dp例题

        前言


        某位大佬曾经说过,dp不会没问题,想不到状态转移方程没问题,多做题就会了。所以,我打算多刷点dp题。那么,先从基础刷起吧。

        1. P1091 合唱队形


        题意

        已知序列 $a$ 有 $n$ 个数,通过取出其中一些数可以使他满足严格的先增再减序列,问最少取出几个。


        思路

        很显然想要求最少取出几个,我们就看严格先增再减的序列的最长长度即可。我们可以用 $g[i]$ 来存储到 $a[i]$ 为止的最长递增子序列的长度,然后用 $l[i]$ 来存储从 $a[i]$ 到序列末尾最长的递减子序列的长度。处理 $g[i]$ 从前往后扫,处理 $l[i]$ 需要从后往前扫。处理完 $f$ 和 $g$ 数组那么就从左到右扫一遍,$ans=max(ans,g[i]+l[i]-1)$ 。答案即是 $n-ans$ 。


        代码实现

        #include<cstdio>
         #include<algorithm>
         #include<cmath>
         #include<iostream>
        @@ -111,5 +111,5 @@
         
        + PaperMod | 鲁ICP备2020034310号
        \ No newline at end of file diff --git a/posts/182/index.html b/posts/182/index.html index 61da3337..8238f529 100644 --- a/posts/182/index.html +++ b/posts/182/index.html @@ -1,39 +1,285 @@ 利用神经网络进行波士顿房价预测 | Zs's Blog -

        利用神经网络进行波士顿房价预测

        前言

        前一阵学校有五一数模节校赛,和朋友一起参加做B题,波士顿房价预测,算是第一次自己动手实现一个简单的小网络吧,虽然很简单,但还是想记录一下。

        题目介绍

        波士顿住房数据由哈里森和鲁宾菲尔德于1978年Harrison and Rubinfeld1收集。它包括了波士顿大区每个调查行政区的506个观察值。1980年Belsley et al.2曾对此数据做过分析。

        数据一共14列,每一列的含义分别如下:

        英文简称详细含义
        CRIM城镇的人均犯罪率
        ZN大于25,000平方英尺的地块的住宅用地比例。
        INDUS每个镇的非零售业务英亩的比例。
        CHAS查尔斯河虚拟变量(如果环河,则等于1;否则等于0)
        NOX一氧化氮的浓度(百万分之几)
        RM每个住宅的平均房间数
        AGE1940年之前建造的自有住房的比例
        DIS到五个波士顿就业中心的加权距离
        RAD径向公路通达性的指标
        TAX每一万美元的全值财产税率
        PTRATIO各镇的师生比率
        B计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例
        LSTAT底层人口的百分比(%)
        price自有住房数的中位数,单位(千美元)

        基于上述数据,请完成以下问题:

        建立波士顿房价预测模型并对预测结果进行评价。

        问题分析

        首先这道题目的很明确,数据一共是 $506×14$ 的一个矩阵,有十三维的自变量,通过建立一个模型来拟合回归出最终的因变量 price,即户主拥有住房价值的中位数。这是一个回归问题,综合考虑有以下两个思路

        1. 通过各种回归算法(GradientBoostingRegressor,RandomForestRegressor,ExtraTreesRegressor,LinearRegressor等)结合全部或部分自变量来回归最终的price

        2. 建立前馈神经网络模型,根据通用逼近定理,我们可以拟合此回归模型。

        我们对上述模型来进行实现并确定评估标准来对他们进行比较,选择最优的模型作为预测模型。

        算法流程

        传统的回归算法

        自变量的选择

        首先,考虑到数据集中13列自变量其中某一些可能和最终的房价并无强相关性,如果全部使用进行预测可能会对模型引入噪声,因此我们首先计算了房价price与各个自变量之间的相关系数 $r$ ,其中 $r$ 计算公式如下: +算法流程 +传统的回归算法 +自变量的选择 +首先,考虑到数据集中13列自变量其中某一些可能和最终的房价并无强相关性,如果全部使用进行预测可能会对模型引入噪声,因此我们首先计算了房价price与各个自变量之间的相关系数 $r$ ,其中 $r$ 计算公式如下: +$$ +r = \frac{\sum(x_i-\bar{x})(y_i-\bar{y})}{\sqrt{\sum(x_i-\bar{x})^2\sum(y_i-\bar{y})^2}} +$$ +其中 $x_i,y_i$ 为数据的每个分量,$\bar{x},\bar{y}$ 为数据的均值 +该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下:">

        利用神经网络进行波士顿房价预测

        前言

        前一阵学校有五一数模节校赛,和朋友一起参加做B题,波士顿房价预测,算是第一次自己动手实现一个简单的小网络吧,虽然很简单,但还是想记录一下。

        题目介绍

        波士顿住房数据由哈里森和鲁宾菲尔德于1978年Harrison and Rubinfeld1收集。它包括了波士顿大区每个调查行政区的506个观察值。1980年Belsley et al.2曾对此数据做过分析。

        数据一共14列,每一列的含义分别如下:

        英文简称详细含义
        CRIM城镇的人均犯罪率
        ZN大于25,000平方英尺的地块的住宅用地比例。
        INDUS每个镇的非零售业务英亩的比例。
        CHAS查尔斯河虚拟变量(如果环河,则等于1;否则等于0)
        NOX一氧化氮的浓度(百万分之几)
        RM每个住宅的平均房间数
        AGE1940年之前建造的自有住房的比例
        DIS到五个波士顿就业中心的加权距离
        RAD径向公路通达性的指标
        TAX每一万美元的全值财产税率
        PTRATIO各镇的师生比率
        B计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例
        LSTAT底层人口的百分比(%)
        price自有住房数的中位数,单位(千美元)

        基于上述数据,请完成以下问题:

        建立波士顿房价预测模型并对预测结果进行评价。

        问题分析

        首先这道题目的很明确,数据一共是 $506×14$ 的一个矩阵,有十三维的自变量,通过建立一个模型来拟合回归出最终的因变量 price,即户主拥有住房价值的中位数。这是一个回归问题,综合考虑有以下两个思路

        1. 通过各种回归算法(GradientBoostingRegressor,RandomForestRegressor,ExtraTreesRegressor,LinearRegressor等)结合全部或部分自变量来回归最终的price

        2. 建立前馈神经网络模型,根据通用逼近定理,我们可以拟合此回归模型。

        我们对上述模型来进行实现并确定评估标准来对他们进行比较,选择最优的模型作为预测模型。

        算法流程

        传统的回归算法

        自变量的选择

        首先,考虑到数据集中13列自变量其中某一些可能和最终的房价并无强相关性,如果全部使用进行预测可能会对模型引入噪声,因此我们首先计算了房价price与各个自变量之间的相关系数 $r$ ,其中 $r$ 计算公式如下: $$ r = \frac{\sum(x_i-\bar{x})(y_i-\bar{y})}{\sqrt{\sum(x_i-\bar{x})^2\sum(y_i-\bar{y})^2}} $$ -其中 $x_i,y_i$ 为数据的每个分量,$\bar{x},\bar{y}$ 为数据的均值

        该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下:

        CRIMZNINDUSCHASNOXRMLSTAT
        -0.3858320.360445-0.4837250.175260-0.4273210.695360-0.737663
        AGEDISRADTAXPTRATIOB
        -0.3769550.249929-0.381626-0.468536-0.5077870.333461

        观察结果可以发现,在给定的十三个变量中,LSTAT price 的相关程度最高$(|r|>0.7)$,其次是 RMPTRATIO $(|r|>0.5)$,再者是 TAX,INDUS,NOX $(|r|>0.4)$,除上述之外的七个变量都与 price 无较强的相关性,因此我们考虑使用六个相关性较强变量和十三个变量分别来对房价进行预测,并对他们进行对比,来寻找最优的回归模型。

        模型的构建
        • 首先我们使用了sklearn中自带的 boston 数据集,并将整体数据集随机划分为了训练集和测试集两部分,所占比例分别为80%和20%。

        • 然后,我们利用Linear,Ridge,Lasso,ElasticNet,DecisionTree,GradientBoosting,RandomForest,ExtraTrees八种模型通过训练集对其进行训练。

        • 接下来,我们利用训练集拟合得到的模型,使用测试集对其进行测试,与 Ground Truth 进行对比,并通过 $R^2$ 来评价该预测结果,其中 $R^2$ 计算公式如下,其是衡量回归模型好坏的常见指标,其值一般处于[0,1]之间,$R^2$ 越接近1,说明模型的性能越好。 +其中 $x_i,y_i$ 为数据的每个分量,$\bar{x},\bar{y}$ 为数据的均值

          该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下:

          CRIMZNINDUSCHASNOXRMLSTAT
          -0.3858320.360445-0.4837250.175260-0.4273210.695360-0.737663
          AGEDISRADTAXPTRATIOB
          -0.3769550.249929-0.381626-0.468536-0.5077870.333461

          观察结果可以发现,在给定的十三个变量中,LSTAT price 的相关程度最高$(|r|>0.7)$,其次是 RMPTRATIO $(|r|>0.5)$,再者是 TAX,INDUS,NOX $(|r|>0.4)$,除上述之外的七个变量都与 price 无较强的相关性,因此我们考虑使用六个相关性较强变量和十三个变量分别来对房价进行预测,并对他们进行对比,来寻找最优的回归模型。

          模型的构建
          • 首先我们使用了sklearn中自带的 boston 数据集,并将整体数据集随机划分为了训练集和测试集两部分,所占比例分别为80%和20%。

          • 然后,我们利用Linear,Ridge,Lasso,ElasticNet,DecisionTree,GradientBoosting,RandomForest,ExtraTrees八种模型通过训练集对其进行训练。

          • 接下来,我们利用训练集拟合得到的模型,使用测试集对其进行测试,与 Ground Truth 进行对比,并通过 $R^2$ 来评价该预测结果,其中 $R^2$ 计算公式如下,其是衡量回归模型好坏的常见指标,其值一般处于[0,1]之间,$R^2$ 越接近1,说明模型的性能越好。 $$ R^2 = 1-\frac{\sum(\hat{y_i}-y_i)^2}{\sum(\bar{y}-y_i)^2} $$

          • 最后,考虑到模型的训练及预测可能具有偶然性,因此我们对于每一个模型进行20次训练及预测,利用20次的结果对其进行综合评价。利用得到的结果绘制 箱线图 所得结果如下:

          使用六变量和十三个变量进行拟合的对比

          分析最终结果可以发现,无论是使用六个相关性较强变量还是十三个变量来进行预测,GradientBoost(梯度提升决策树)回归模型都是最好的,此外,我们可以发现,利用十三个变量要比利用六个主要变量来进行预测比有着更好的效果。

          前馈神经网络

          模型的构建

          近年来,神经网络理论不断发展,前馈神经网络(多层感知机、全连接神经网络)越来越多的被利用到数据分析中,因此考虑使用前馈神经网络来解决此问题。

          前馈神经网络(全连接神经网络)的网络结构一般由三部分构成,输入层,隐藏层,以及输出层,输入层与输出层一般只有一层,隐藏层可有多层。中间利用非线性函数作为激活函数可以使得网络具有拟合非线性函数的能力

          根据通用近似定理:

          通用近似定理

          对于具有线性输出层和至少一个使用“挤压”性质的激活函数的隐藏层组成的前馈神经网络,只要其隐藏层神经元的数量足够,它可以以任意精度来近似任何从一个定义在实数空间中的有界闭集函数。

          只要隐藏层网络维度够高,就可以拟合任意的函数。

          考虑到我们的模型有六维or十三维的数据输入,因此我们建立两层前馈神经网络,中间具有一层隐藏层,维度为1000维,激活函数使用Relu,Relu函数有以下优点:

          • Relu相比于传统的Sigmoid、Tanh,导数更加好求,反向传播就是不断的更新参数的过程,因为其导数不复杂形式简单,可以使得网络训练更快速。

          • 此外,当数值过大或者过小,Sigmoid,Tanh的导数接近于0,Relu为非饱和激活函数则不存在这种现象,可以很好的解决梯度消失的问题

          Relu函数及网络结构图如图所示:

          $$ @@ -50,5 +296,5 @@

        + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/posts/19/index.html b/posts/19/index.html index ab4072a1..b41b4d5e 100644 --- a/posts/19/index.html +++ b/posts/19/index.html @@ -20,7 +20,7 @@ 思路 -很经典的区间dp例题,我们可以用 $dp[i][j]$ 来表示合并 $i\sim j$ 所需的最小代价,通过枚举中间的断点,来通过方程 $dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+cost[i][j])$ ,其中 $cost[i][j]$ 表示从 $i\sim j$ 的石子总数,通过前缀和很容易计算。在进行状态转移时需要前面状态已知,因为是枚举中间断点,所以断开区间的长度一定要小于原区间,因此在转移之前需要确保比他短的区间都已经达到了最小代价,因此我们可以通过枚举区间长度从 $2\sim N$ 来实现。">

        基础线性dp例题 #2

        1. 石子归并


        题意

        $N$ 堆石子摆成一条线。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价。计算将 $N$ 堆石子合并成一堆的最小代价。
        +很经典的区间dp例题,我们可以用 $dp[i][j]$ 来表示合并 $i\sim j$ 所需的最小代价,通过枚举中间的断点,来通过方程 $dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+cost[i][j])$  ,其中 $cost[i][j]$ 表示从 $i\sim j$ 的石子总数,通过前缀和很容易计算。在进行状态转移时需要前面状态已知,因为是枚举中间断点,所以断开区间的长度一定要小于原区间,因此在转移之前需要确保比他短的区间都已经达到了最小代价,因此我们可以通过枚举区间长度从 $2\sim N$ 来实现。">

        基础线性dp例题 #2

        1. 石子归并


        题意

        $N$ 堆石子摆成一条线。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价。计算将 $N$ 堆石子合并成一堆的最小代价。
         

        思路

        很经典的区间dp例题,我们可以用 $dp[i][j]$ 来表示合并 $i\sim j$ 所需的最小代价,通过枚举中间的断点,来通过方程 $dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+cost[i][j])$ ,其中 $cost[i][j]$ 表示从 $i\sim j$ 的石子总数,通过前缀和很容易计算。在进行状态转移时需要前面状态已知,因为是枚举中间断点,所以断开区间的长度一定要小于原区间,因此在转移之前需要确保比他短的区间都已经达到了最小代价,因此我们可以通过枚举区间长度从 $2\sim N$ 来实现。


        代码实现

        #include<cstdio>
         #include<cstring>
         #include<algorithm>
        @@ -156,5 +156,5 @@
         
        + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/posts/195/index.html b/posts/195/index.html index 2ca35e59..1f73c81c 100644 --- a/posts/195/index.html +++ b/posts/195/index.html @@ -1,23 +1,248 @@ deepin-wine-qq-9.1.8版本无法正常启动的解决方案 | Zs's Blog -

        deepin-wine-qq-9.1.8版本无法正常启动的解决方案

        问题描述

        ​Ubuntu下想要使用QQ有一个比较好的解决方案就是deepin-wine的版本,deepin-wine版本的QQ一共有两个版本,分别是 8.9.1 和 9.1.8 ,前者安装后发现无法登陆,登录时会提示版本过低的问题,于是我换到9.1.8版本后,启动初始化后就无任何信息了,于是开始排查问题

        解决方案

        ​首先我们根据上文的启示,因为每一个应用程序对应了一个 xxx.desktop 文件,因此在应用库中的QQ一定也有一个对应的 desktop 文件

        QQ的启动方式

        ​我们进入到 /usr/share/applications ,运行

        $ ls | grep -i qq
        +base ❯ ./run.sh                   
        +Run Deepin-QQ 9.1.8deepin0 c:/Program Files/Tencent/QQ/Bin/QQ.exe
        +run Deepin-QQ progress pid 
        +Gtk-Message: 01:16:58.069: GtkDialog mapped without a transient parent. This is discouraged.
        +total 0
        +lrwxrwxrwx 1 zs zs 10 6月  16 01:16 c: -> ../drive_c
        +lrwxrwxrwx 1 zs zs 10 6月  15 23:36 com1 -> /dev/ttyS0
        +lrwxrwxrwx 1 zs zs 10 6月  15 23:36 com10 -> /dev/ttyS9
        +lrwxrwxrwx 1 zs zs 11 6月  15 23:36 com11 -> /dev/ttyS10
        +lrwxrwxrwx 1 zs zs 11 6月  15 23:36 com12 -> /dev/ttyS11
        +lrwxrwxrwx 1 zs zs 11 6月  15 23:36 com13 -> /dev/ttyS12
        +lrwxrwxrwx 1 zs zs 11 6月  15 23:36 com14 -> /dev/ttyS13
        +lrwxrwxrwx 1 zs zs 11 6月  15 23:36 com15 -> /dev/ttyS14
        +lrwxrwxrwx 1 zs zs 11 6月  15 23:36 com16 -> /dev/ttyS15
        +lrwxrwxrwx 1 zs zs 11 6月  15 23:36 com17 -> /dev/ttyS16
        +lrwxrwxrwx 1 zs zs 11 6月  15 23:36 com18 -> /dev/ttyS17
        +lrwxrwxrwx 1 zs zs 11 6月  15 23:36 com19 -> /dev/ttyS18
        +lrwxrwxrwx 1 zs zs 10 6月  15 23:36 com2 -> /dev/ttyS1
        +lrwxrwxrwx 1 zs zs 11 6月  15 23:36 com20 -> /dev/ttyS19
        +lrwxrwxrwx 1 zs zs 11 6月  15 23:36 com21 -> /dev/ttyS20
        +lrwxrwxrwx 1 zs zs 11 6月  15 23:36 com22 -> /dev/ttyS21
        +lrwxrwxrwx 1 zs zs 11 6月  15 23:36 com23 -> /dev/ttyS22
        +lrwxrwxrwx 1 zs zs 11 6月  15 23:36 com24 -> /dev/ttyS23
        +lrwxrwxrwx 1 zs zs 11 6月  15 23:36 com25 -> /dev/ttyS24
        +lrwxrwxrwx 1 zs zs 11 6月  15 23:36 com26 -> /dev/ttyS25
        +lrwxrwxrwx 1 zs zs 11 6月  15 23:36 com27 -> /dev/ttyS26
        +lrwxrwxrwx 1 zs zs 11 6月  15 23:36 com28 -> /dev/ttyS27
        +lrwxrwxrwx 1 zs zs 11 6月  15 23:36 com29 -> /dev/ttyS28
        +lrwxrwxrwx 1 zs zs 10 6月  15 23:36 com3 -> /dev/ttyS2
        +lrwxrwxrwx 1 zs zs 11 6月  15 23:36 com30 -> /dev/ttyS29
        +lrwxrwxrwx 1 zs zs 11 6月  15 23:36 com31 -> /dev/ttyS30
        +lrwxrwxrwx 1 zs zs 11 6月  15 23:36 com32 -> /dev/ttyS31
        +lrwxrwxrwx 1 zs zs 10 6月  15 23:36 com4 -> /dev/ttyS3
        +lrwxrwxrwx 1 zs zs 10 6月  15 23:36 com5 -> /dev/ttyS4
        +lrwxrwxrwx 1 zs zs 10 6月  15 23:36 com6 -> /dev/ttyS5
        +lrwxrwxrwx 1 zs zs 10 6月  15 23:36 com7 -> /dev/ttyS6
        +lrwxrwxrwx 1 zs zs 10 6月  15 23:36 com8 -> /dev/ttyS7
        +lrwxrwxrwx 1 zs zs 10 6月  15 23:36 com9 -> /dev/ttyS8
        +lrwxrwxrwx 1 zs zs  8 6月  16 01:16 y: -> /home/zs
        +lrwxrwxrwx 1 zs zs  1 6月  16 01:16 z: -> /
        +CallApp Deepin-QQ c:/Program Files/Tencent/QQ/Bin/QQ.exe
        +2021年 06月 16日 星期三 01:16:58 CST:kill QQ.exe block
        +2021年 06月 16日 星期三 01:16:58 CST:No wine process found
        +/home/zs/.deepinwine/Deepin-QQ/drive_c/Program Files/Tencent/QQ/Bin
        +Starting process c:/Program Files/Tencent/QQ/Bin/QQ.exe ...
        +
        +/opt/deepinwine/apps/Deepin-QQ
        +base ❯ wine: cannot find L"C:\\windows\\system32\\winemenubuilder.exe"
        +wine version: 2.18
        +libGL error: No matching fbConfigs or visuals found
        +libGL error: failed to load driver: swrast
        +X Error of failed request:  GLXBadContext
        +  Major opcode of failed request:  152 (GLX)
        +  Minor opcode of failed request:  6 (X_GLXIsDirect)
        +  Serial number of failed request:  207
        +  Current serial number in output stream:  206
        +​可以发现最下面的log信息有一些异常,首先第一行是因为我们是Ubuntu系统,可以暂且不关注'>

        deepin-wine-qq-9.1.8版本无法正常启动的解决方案

        问题描述

        ​Ubuntu下想要使用QQ有一个比较好的解决方案就是deepin-wine的版本,deepin-wine版本的QQ一共有两个版本,分别是 8.9.1 和 9.1.8 ,前者安装后发现无法登陆,登录时会提示版本过低的问题,于是我换到9.1.8版本后,启动初始化后就无任何信息了,于是开始排查问题

        解决方案

        ​首先我们根据上文的启示,因为每一个应用程序对应了一个 xxx.desktop 文件,因此在应用库中的QQ一定也有一个对应的 desktop 文件

        QQ的启动方式

        ​我们进入到 /usr/share/applications ,运行

        $ ls | grep -i qq
         

        ​可以发现其中有一个名为 deepin.com.qq.im.desktop 的文件,我们打开后发现内容如下:

        #!/usr/bin/env xdg-open
         
         [Desktop Entry]
        @@ -99,5 +324,5 @@
         
        + PaperMod | 鲁ICP备2020034310号
        \ No newline at end of file diff --git a/posts/198/index.html b/posts/198/index.html index 23d0d244..4ed70fa4 100644 --- a/posts/198/index.html +++ b/posts/198/index.html @@ -1,47 +1,89 @@ 利用树莓派为HP LaserJet 1020配置无线打印功能 | Zs's Blog -

        利用树莓派为HP LaserJet 1020配置无线打印功能

        前言

        最近基地的打印机突然又好起来了。

        因为基地的打印机型号比较老——HP LaserJet 1020,没有无线打印的功能。所以之前一位学长1 用树莓派配置了打印机的无线打印功能,但是后来发现有一些问题,有时候发送打印请求树莓派无法接收,而且不知道为何,学长之前用的是树莓派自己创建WiFi,连接对应WiFi才能打印,但是这个显然不是最优的解决办法。

        考虑到之间已经配置好基地WiFi,我决定重新配置一下打印功能,使其连接基地WiFi即可实现局域网打印。


        配置过程

        查看树莓派内容

        通过ssh连接树莓派,发现里面除了Github上的一个开源项目create_ap ,就没有什么其他的内容了,连接屏幕后发现没有任何图像信号,无从下手,因此考虑重新刷机。


        对树莓派进行刷机

        把数据备份了一下,看了一下树莓派版本是2015年生产的 Raspberry Pi 3 model B V1.2 ,是老古董了。

        去官网看了一下,因为我对Ubuntu比较熟悉,我计划安装一个 Ubuntu20.04版本的,考虑到版本比较老,就装了server版本的,相比与desktop版本负担更小一些。

        其实就是下一个官方的软件,Raspberry Pi Imager ,直接用读卡器对树莓派的存储卡刷机即可。

        这里是对应的镜像以及教程: 镜像下载 安装教程


        配置网络相关

        Ubuntu的server版本有个比较蛋疼的问题就是上网比较困难,如果是用的学校网线,必须要PPPOE拨号才能上网,但是server版本居然没有 net-toolsnetwork-manager ,连接WiFi啥的试了很多办法但还是没有什么作用。

        解决办法:用网线直接连接树莓派和有网的路由器,安装 net-toolsnetwork-manager ,执行

        $ sudo nmtui
        +
        +
        +在树莓派的利用 nmtui 选择 Edit a connection  ,Add一个Ethernet connect,对IPv4 CONFIGURATION进行设置,首先讲 Automatic 设置为 Manual,设置 Address 为 静态IP 如 192.168.3.2 ,Gateway 设置为 192.168.3.1 。">

        利用树莓派为HP LaserJet 1020配置无线打印功能

        前言

        最近基地的打印机突然又好起来了。

        因为基地的打印机型号比较老——HP LaserJet 1020,没有无线打印的功能。所以之前一位学长1 用树莓派配置了打印机的无线打印功能,但是后来发现有一些问题,有时候发送打印请求树莓派无法接收,而且不知道为何,学长之前用的是树莓派自己创建WiFi,连接对应WiFi才能打印,但是这个显然不是最优的解决办法。

        考虑到之间已经配置好基地WiFi,我决定重新配置一下打印功能,使其连接基地WiFi即可实现局域网打印。


        配置过程

        查看树莓派内容

        通过ssh连接树莓派,发现里面除了Github上的一个开源项目create_ap ,就没有什么其他的内容了,连接屏幕后发现没有任何图像信号,无从下手,因此考虑重新刷机。


        对树莓派进行刷机

        把数据备份了一下,看了一下树莓派版本是2015年生产的 Raspberry Pi 3 model B V1.2 ,是老古董了。

        去官网看了一下,因为我对Ubuntu比较熟悉,我计划安装一个 Ubuntu20.04版本的,考虑到版本比较老,就装了server版本的,相比与desktop版本负担更小一些。

        其实就是下一个官方的软件,Raspberry Pi Imager ,直接用读卡器对树莓派的存储卡刷机即可。

        这里是对应的镜像以及教程: 镜像下载 安装教程


        配置网络相关

        Ubuntu的server版本有个比较蛋疼的问题就是上网比较困难,如果是用的学校网线,必须要PPPOE拨号才能上网,但是server版本居然没有 net-toolsnetwork-manager ,连接WiFi啥的试了很多办法但还是没有什么作用。

        解决办法:用网线直接连接树莓派和有网的路由器,安装 net-toolsnetwork-manager ,执行

        $ sudo nmtui
         

        选择 Activate a connect 连接无线的WiFi,执行

        $ sudo ifconfig
         

        查看WiFi对应的IP,至此,树莓派可以摆脱屏幕,我们可以使用电脑进行使用 ssh 连接。

        这里也可以使用网线进行连接,具体操作如下

        1. 用网线连接树莓派和自己的电脑。

        2. 在树莓派的利用 nmtui 选择 Edit a connection ,Add一个Ethernet connect,对IPv4 CONFIGURATION进行设置,首先讲 Automatic 设置为 Manual,设置 Address静态IP192.168.3.2Gateway 设置为 192.168.3.1

        3. 在自己电脑利用 nmtui 同上不过设置 Address192.168.3.3 ,只要是位于同一网段即可。

        4. 这时候就可以通过网线进行 ssh 连接了。


        配置cups

        以下大多参考:如何正确地用树莓派共享打印机

        大佬言:

        其实,这一步的工作量非常少,因为软件包 CUPS 就是为共享打印机而生。我们要做的只是将打印机用 USB 线缆连接树莓派,然后安装并配置 CUPS。

        然而,事实并非如此。

        换源

        在安装之前需要换源,如果不换源的话,安装会十分缓慢,具体的流程可以看上面的blog,因为我们基地的WiFi自带代理,因此这一步我没有做。

        安装驱动及打印程序

        • 首先更新源并安装Hp的打印机驱动 hplip
        $ sudo apt update
         $ sudo apt install hplip
        @@ -62,5 +104,5 @@
         
        + PaperMod | 鲁ICP备2020034310号
        \ No newline at end of file diff --git a/posts/20/index.html b/posts/20/index.html index 2c832f33..d6c2bbb4 100644 --- a/posts/20/index.html +++ b/posts/20/index.html @@ -17,7 +17,7 @@ 1. 采药(01背包) 题意 -有 $n$ 个价值为 $w_i$ ,体积为 $v_i$ 的物品,装入体积为 $V$ 的背包中,问能获得的最大为多少。">

        一些关于背包的题

        前言

        今天跟着背包九讲把背包再学习一下,dd_engi大佬的背包九讲Github链接: 背包九讲


        1. 采药(01背包)


        题意

        有 $n$ 个价值为 $w_i$ ,体积为 $v_i$ 的物品,装入体积为 $V$ 的背包中,问能获得的最大为多少。


        思路

        首先我们可以用 $f[i][j]$ 来定义前 $i$ 个物品放入体积为 $j$ 的背包中能获得最大体积,对于每一个物品,我们可以分两种情况来讨论,分别是装和不装,然后取他们两个的最大值。已经正确的定义了状态,转移方程就不难写出来了,是 $f[i][j]=max(f[i-1][j],f[i-1][j-v[i]]+w[i])$ ,然后推的话就直接外层循环物品,内层循环体积递推即可。最后 $f[n][V]$ 就是我们需要的答案。

        但是看了大佬们的题解,他们说,空间复杂度还可以再优化,那么我们可以看看如果优化的话,肯定是不能去掉体积那一维的,所以就是去掉第几个物品那一维。所以从 $f[i][j]$ 变成了 $f[j]$ 。那么我们想想,当我们推第 $i$ 个物体的状态的时候,我们需要已知第 $i-1$ 个的状态,我们物体循环是 $1\sim n$ 那么肯定 $f[i][j]$ 一开始对应的是 $f[i-1][j]$ ,那么如果顺推体积 $0\sim V$ 的话我们可以发现,当我们推 $f[i][j]$ 需要状态 $f[i-1][j-v[i]]$ 的时候,这时候如果直接调用 $f[j-v[i]]$ 对应的是 $f[i][j-v[i]]$ 也就是说,这不是我们需要的结果,这时候的状态可能已经取过一次i了,那么我们就可以逆推体积 $V\sim c[i]$ ,这样我们调用 $f[j-v[i]]$ 就刚好对应的是没取过 $i$ 的情况了!最后推出来 $f[V]$ 就是对应的答案了!


        代码实现

        #include<cstdio>
        +有 $n$ 个价值为 $w_i$ ,体积为 $v_i$ 的物品,装入体积为 $V$ 的背包中,问能获得的最大为多少。">

        一些关于背包的题

        前言

        今天跟着背包九讲把背包再学习一下,dd_engi大佬的背包九讲Github链接: 背包九讲


        1. 采药(01背包)


        题意

        有 $n$ 个价值为 $w_i$ ,体积为 $v_i$ 的物品,装入体积为 $V$ 的背包中,问能获得的最大为多少。


        思路

        首先我们可以用 $f[i][j]$ 来定义前 $i$ 个物品放入体积为 $j$ 的背包中能获得最大体积,对于每一个物品,我们可以分两种情况来讨论,分别是装和不装,然后取他们两个的最大值。已经正确的定义了状态,转移方程就不难写出来了,是 $f[i][j]=max(f[i-1][j],f[i-1][j-v[i]]+w[i])$ ,然后推的话就直接外层循环物品,内层循环体积递推即可。最后 $f[n][V]$ 就是我们需要的答案。

        但是看了大佬们的题解,他们说,空间复杂度还可以再优化,那么我们可以看看如果优化的话,肯定是不能去掉体积那一维的,所以就是去掉第几个物品那一维。所以从 $f[i][j]$ 变成了 $f[j]$ 。那么我们想想,当我们推第 $i$ 个物体的状态的时候,我们需要已知第 $i-1$ 个的状态,我们物体循环是 $1\sim n$ 那么肯定 $f[i][j]$ 一开始对应的是 $f[i-1][j]$ ,那么如果顺推体积 $0\sim V$ 的话我们可以发现,当我们推 $f[i][j]$ 需要状态 $f[i-1][j-v[i]]$ 的时候,这时候如果直接调用 $f[j-v[i]]$ 对应的是 $f[i][j-v[i]]$ 也就是说,这不是我们需要的结果,这时候的状态可能已经取过一次i了,那么我们就可以逆推体积 $V\sim c[i]$ ,这样我们调用 $f[j-v[i]]$ 就刚好对应的是没取过 $i$ 的情况了!最后推出来 $f[V]$ 就是对应的答案了!


        代码实现

        #include<cstdio>
         #include<cstring>
         #include<cmath>
         #include<algorithm>
        @@ -116,5 +116,5 @@
         
        + PaperMod | 鲁ICP备2020034310号
        \ No newline at end of file diff --git a/posts/201/index.html b/posts/201/index.html index c7343b8a..1cdbdc46 100644 --- a/posts/201/index.html +++ b/posts/201/index.html @@ -1,29 +1,74 @@ 关于Git的一些理解 | Zs's Blog -..." to unstage) modified: test Changes not staged for commit: (use "git add ..." to update what will be committed) (use "git restore .'>

        关于Git的一些理解

        前言

        前段时间在 Github 学完了关于 git 的小游戏 learnGitBranching ,受益匪浅。

        它通过可视化的方式将分支的关系,每条命令的作用等都明明白白的体现出来,可以很直观的感受到你每条命令对整个分支树,每一个 ref 的作用。

        通过这种学习感觉自己对 Git 的理解更加深入一步,能够理解其中的原理,而不是浅尝辄止,照猫画虎。

        学习中记了一些零零散散的思路,想要写一篇笔记记录出来,之前已经写过一个简单的 Git 教程,这篇教程将会更加深入,希望可以帮助大家更好的掌握 Git。

        窃认为,想要学好 Git ,必须要理解清楚其中的分区以及引用,学会了这两个,各种基本操作就很容易理解了。接下来的笔记也基本以此思路展开。

        Git中的分区

        Git中的三大分区,图片来源自掘金GabrielPanda

        首先,Git中存在三大分区,分别是工作区、暂存区、版本库。其中,

        工作区即我们工作的目录,暂存区是我们执行 git add 后文件存在的区域。

        我们可以通过 git status 对两种状态进行查看,例如:

        ~/test master*
        +~/test master*
        +base ❯ git status  
        +On branch master
        +Changes to be committed:
        +  (use "git restore --staged ..." to unstage)
        +	modified:   test
        +
        +Changes not staged for commit:
        +  (use "git add ..." to update what will be committed)
        +  (use "git restore ..." to discard changes in working directory)
        +	modified:   test
        +上图中存在两部分, 分别为 Changes to be committed 这里是表示的版本库与暂存区的区别,还有Changes not staged for commit ,它表示的是工作区与暂存区的区别。'>

        关于Git的一些理解

        前言

        前段时间在 Github 学完了关于 git 的小游戏 learnGitBranching ,受益匪浅。

        它通过可视化的方式将分支的关系,每条命令的作用等都明明白白的体现出来,可以很直观的感受到你每条命令对整个分支树,每一个 ref 的作用。

        通过这种学习感觉自己对 Git 的理解更加深入一步,能够理解其中的原理,而不是浅尝辄止,照猫画虎。

        学习中记了一些零零散散的思路,想要写一篇笔记记录出来,之前已经写过一个简单的 Git 教程,这篇教程将会更加深入,希望可以帮助大家更好的掌握 Git。

        窃认为,想要学好 Git ,必须要理解清楚其中的分区以及引用,学会了这两个,各种基本操作就很容易理解了。接下来的笔记也基本以此思路展开。

        Git中的分区

        Git中的三大分区,图片来源自掘金GabrielPanda

        首先,Git中存在三大分区,分别是工作区、暂存区、版本库。其中,

        工作区即我们工作的目录,暂存区是我们执行 git add 后文件存在的区域。

        我们可以通过 git status 对两种状态进行查看,例如:

        ~/test master*
         base ❯ git status  
         On branch master
         Changes to be committed:
        @@ -77,5 +122,5 @@
         
        + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/posts/21/index.html b/posts/21/index.html index be41da38..d31e4f0f 100644 --- a/posts/21/index.html +++ b/posts/21/index.html @@ -8,7 +8,7 @@ 在01背包基础上,将其中的物体分成 $k$ 组,每组内的物品相互冲突,即只能取其中一个,问最大价值。">

        背包进阶

        1. 分组背包


        题意

        在01背包基础上,将其中的物体分成 $k$ 组,每组内的物品相互冲突,即只能取其中一个,问最大价值。


        思路

        同一组中各个物品是相互排斥的,那么我们对于处理可以外层循环组别,然后循环体积,最后循环组内的物品,然后套用01背包的转移方程 $dp[i]=max(dp[i],dp[i-v[k]]+w[k])$ 即可。我们来思考一下他的正确性,为什么只要这样循环就能确保每个组最多只取用一种呢?很明显组内的我们对于同一个体积 $V$ ,求体积 $V$ 对应的最大价值的时候,是从这个组内所有物品中取了能获得最大价值的策略,很明显当我们转移任何一个 $dp[i-v[k]]$ 的状态的时候,他们其中都不包含第 $i$ 组的物品,都是只包含了前 $i-1$ 组的物品,因为我们最终取得最大价值的路径是确定的,因此通过这个方式我们就可以确保每个组内只取一种,但是如果体积和组内物品的循环调换过来,就不行了,因为之前的状态就会包含当前组内的其他物品。


        代码实现

        #include<cstdio>
        +在01背包基础上,将其中的物体分成 $k$ 组,每组内的物品相互冲突,即只能取其中一个,问最大价值。">

        背包进阶

        1. 分组背包


        题意

        在01背包基础上,将其中的物体分成 $k$ 组,每组内的物品相互冲突,即只能取其中一个,问最大价值。


        思路

        同一组中各个物品是相互排斥的,那么我们对于处理可以外层循环组别,然后循环体积,最后循环组内的物品,然后套用01背包的转移方程 $dp[i]=max(dp[i],dp[i-v[k]]+w[k])$ 即可。我们来思考一下他的正确性,为什么只要这样循环就能确保每个组最多只取用一种呢?很明显组内的我们对于同一个体积 $V$ ,求体积 $V$ 对应的最大价值的时候,是从这个组内所有物品中取了能获得最大价值的策略,很明显当我们转移任何一个 $dp[i-v[k]]$ 的状态的时候,他们其中都不包含第 $i$ 组的物品,都是只包含了前 $i-1$ 组的物品,因为我们最终取得最大价值的路径是确定的,因此通过这个方式我们就可以确保每个组内只取一种,但是如果体积和组内物品的循环调换过来,就不行了,因为之前的状态就会包含当前组内的其他物品。


        代码实现

        #include<cstdio>
         #include<cstring>
         #include<algorithm>
         #include<cmath>
        @@ -194,5 +194,5 @@
         
        + PaperMod | 鲁ICP备2020034310号
        \ No newline at end of file diff --git a/posts/215/index.html b/posts/215/index.html index d86c7d1f..6e81f3cc 100644 --- a/posts/215/index.html +++ b/posts/215/index.html @@ -1,29 +1,116 @@ 2021版小新Pro14 Ubuntu 20.04 配置指南 | Zs's Blog -

        2021版小新Pro14 Ubuntu 20.04 配置指南

        2021版小新Pro14 Ubuntu 20.04 配置指南

        补充

        最近重装了 Ubuntu 20.04,又找了相关的一些帖子,发现 聯想Yoga 14s 2021款裝機小記 中提到了下文中提到的屏幕闪烁的问题,解决办法是:只需要在内核参数中加入 i915.enable_psr=0 即可。

        具体操作步骤如下:

        $ sudo vim /etc/default/grub
        +问题列表
        +如果你遇到了以下问题,那么这篇文章的方法可能会对你有益处:
        +Ubuntu 18.04 相关
        +
        +Ubuntu 18.04 无法使用触摸板
        +Ubuntu 18.04 无法使用内置键盘
        +Ubuntu 18.04 无法调节亮
        +Ubuntu 18.04 查看GPU发现是llvm,而不是Iris Xe
        +
        +Ubuntu 20.04 相关
        +
        +Ubuntu 20.04 进入后屏幕花屏、黑屏
        +Ubuntu 20.04 查看GPU发现是llvm,而不是Iris Xe
        +
        +现在达成的效果
        +Ubuntu 20.04 能够正常使用,触摸板以及外界屏幕,亮度调节均无问题。">

        2021版小新Pro14 Ubuntu 20.04 配置指南

        2021版小新Pro14 Ubuntu 20.04 配置指南

        补充

        最近重装了 Ubuntu 20.04,又找了相关的一些帖子,发现 聯想Yoga 14s 2021款裝機小記 中提到了下文中提到的屏幕闪烁的问题,解决办法是:只需要在内核参数中加入 i915.enable_psr=0 即可。

        具体操作步骤如下:

        $ sudo vim /etc/default/grub
         

        在 GRUB_CMDLINE_LINUX_DEFAULT 这一行的最后添加 i915.enable_psr=0,保存后终端运行:

        $ sudo update-grub
         

        然后重启即可。


        前言

        苦于沉重游戏本的迫害,新买了一台小新Pro14 2021款,上手感觉还挺不错的。如下是配置:

        • CPU:酷睿 i5-11300H
        • 显卡:集成显卡 Intel 锐炬Iris Xe
        • 内存:16G
        • 外存:512 SSD
        • 屏幕:分辨率 2880x1800、400nits、100%sRGB

        电脑配置信息

        这里需要注意的是,不同时间出的小新Pro14配置是不太一样的,所以我这里列了一下配置。主要区别在于有一部分是2.2K分辨率+MX450显卡,而我这个是2.8K分辨率+锐炬Iris Xe显卡。

        为了工作的需要,要装一个Ubuntu,先是装了之前用过的 Ubuntu 18.04,安装后发现触摸板无法使用,一系列探索后无果,在朋友的推荐下,还是决定安装 Ubuntu 20.04 试一下,踩了一些坑,在这里记录一下。

        问题列表

        如果你遇到了以下问题,那么这篇文章的方法可能会对你有益处:

        Ubuntu 18.04 相关

        1. Ubuntu 18.04 无法使用触摸板
        2. Ubuntu 18.04 无法使用内置键盘
        3. Ubuntu 18.04 无法调节亮
        4. Ubuntu 18.04 查看GPU发现是llvm,而不是Iris Xe

        Ubuntu 20.04 相关

        1. Ubuntu 20.04 进入后屏幕花屏、黑屏
        2. Ubuntu 20.04 查看GPU发现是llvm,而不是Iris Xe

        现在达成的效果

        Ubuntu 20.04 能够正常使用,触摸板以及外界屏幕,亮度调节均无问题。

        开机时也能够使用键盘。

        但是开机登录界面还是存在花屏、闪屏的问题,我通过自动登录解决。BIOS界面仍旧会闪屏。

        安装 Ubuntu 18.04 的问题

        首先安装Ubuntu 18.04 还是比较顺利,没有什么坑。

        安装的话就是按流程来一遍——压缩卷、进入BIOS关闭安全启动模式(这里网上有部分同学说也需要关闭 Intel Platform Trust Technology 、但是我不关闭也是可以的)、然后Try Ubuntu看一下效果(这里Try Ubuntu我没法使用鼠标,不过安装的时候可以)、开始安装。

        安装过程一般没啥问题,进入系统后我们就会发现一些问题,首先是你的**触摸板用不了,然后键盘也用不了。**再就是屏幕没法调节亮度(这个是小问题我觉得,好像也可以通过安装插件解决,大家可以自行搜索。)

        经过查询资料,这里有同学已经提出很好的解决方案:https://zhuanlan.zhihu.com/p/322377515

        简而言之,键盘用不了需要在 grub 启动项中加入 i8042.dumbkbd 参数,然后运行

        sudo update-grub2
         

        即可在每次启动后保证键盘可用。

        关于没法使用触摸板和调节亮度,办法就是升级内核,据说是内核升级到5.9.8以上可用,Ubuntu 18.04内置版本是5.4.0.84好像是,但是我在更新后会花屏、黑屏等来回鬼畜,试了好多四五个内核依旧不管用,我猜想是因为我是2.8K的屏幕而网上的教程多是基于2.2K屏幕的,锐炬显卡对于高分辨率的屏幕支持并没有那么优秀。

        于是一直被这个问题折磨,搜了很多的教程也没有解决办法,最后决定换Ubuntu 20.04 尝试一下,之前一直觉得系统版本是个不可逾越的鸿沟,但是随着实践的越来越多,发现很多版本不兼容的问题都是有可解决办法的,因此也下定决心尝试一下未曾试过的 20.04。

        安装Ubuntu 20.04 的问题

        首先是关于安装的问题

        在安装Ubuntu 18.04 的时候只有四个选项,应该是一个 Try Ubuntu、一个直接安装,一个高级模式,一个进BIOS

        而安装Ubuntu 20.04 的时候却有五个选项,分别是Ubuntu、Ubuntu(safe graphics)、OEM install(for manufacturers)、还有就是一个是高级模式、一个是进BIOS

        说一下三个安装方式的区别

        第一个模式与第二个模式的区别就是,第二个模式对于grub启动项目中添加了一个 nomodeset 选项,那么这个选项是做什么的?以下是他的解释:

        The newest kernels have moved the video mode setting into the kernel. So all the programming of the hardware specific clock rates and registers on the video card happen in the kernel rather than in the X driver when the X server starts.. This makes it possible to have high resolution nice looking splash (boot) screens and flicker free transitions from boot splash to login screen. Unfortunately, on some cards this doesn’t work properly and you end up with a black screen. Adding the nomodeset parameter instructs the kernel to not load video drivers and use BIOS modes instead until X is loaded.

        大概意思是在最新的内核中,已经能够在BIOS引导阶段启用显卡,这样做的目的是很好的适应高分辨率屏,但是很遗憾的是某些显卡并不能很好的适配,通过 nomodeset 参数可以防止以不支持的显卡驱动视频流。

        很遗憾,锐炬显卡刚好没有被适配,所以选第一个选项(Ubuntu)来安装也会屏幕一闪一闪的,因此我们安装选择Ubuntu(safe graphics)选项来进行安装然后流程是一样的,蛮顺利。

        这里装完就没有触摸板的问题,屏幕亮度调节也没有问题。不过键盘依旧有问题,可以根据上面描述进行更改。

        然后更鬼畜的问题来了,只要这么一搞,从BIOS引导阶段开始,就会一直闪屏,尤其是输入密码进行登录的时候,会卡个好长时间,几乎无法使用,不过很有意思的是,只要外接屏幕,外接的屏幕显示不会有问题。

        因此求助于搜索引擎,因为怀疑是显卡的问题,所以搜索了关键词 Ubuntu Iris Xe,找到了以下两个比较有用的答案:

        StackOverflow:Ubuntu 20.04 no driver loaded for Intel Iris Xe Graphics

        Intel:Intel Iris Xe MAX Graphics with Linux

        这两个帖子都说了一个问题吧,就是如何在 Ubuntu 20.04 上更好的使用锐炬显卡

        这个问题实质解决的是没有在Ubuntu 20.04 上启动起来显卡,所以你会在你的 Ubuntu->Settings->About 页面看到的是 llvm 有关的字眼,而不是上面我截图所示的 Mesa Intel® Xe Graphics (TGL GT2)

        解决这个问题比较关键的步骤是

        sudo apt update
        @@ -33,5 +120,5 @@
         
        + PaperMod | 鲁ICP备2020034310号
        \ No newline at end of file diff --git a/posts/22/index.html b/posts/22/index.html index 618ff97a..9b6d34fe 100644 --- a/posts/22/index.html +++ b/posts/22/index.html @@ -5,7 +5,7 @@ 题意 给出一段含有 $n$ 个数的序列 $a$ ,可以对其中任何数加一,问最少操作多少次让每一个数和序列和都不为0。">

        Codeforces #618 (Div.2)

        A. Non-zero

        题意

        给出一段含有 $n$ 个数的序列 $a$ ,可以对其中任何数加一,问最少操作多少次让每一个数和序列和都不为0。


        思路

        输入的时候如果输入的是 $0$ 就将答案加一,最后如果序列和为 $0$ 的话答案加一。


        代码实现

        #include<cstdio>
        +给出一段含有 $n$ 个数的序列 $a$ ,可以对其中任何数加一,问最少操作多少次让每一个数和序列和都不为0。">

        Codeforces #618 (Div.2)

        A. Non-zero

        题意

        给出一段含有 $n$ 个数的序列 $a$ ,可以对其中任何数加一,问最少操作多少次让每一个数和序列和都不为0。


        思路

        输入的时候如果输入的是 $0$ 就将答案加一,最后如果序列和为 $0$ 的话答案加一。


        代码实现

        #include<cstdio>
         #include<cstring>
         #include<algorithm>
         #include<cmath>
        @@ -230,5 +230,5 @@
         
        + PaperMod | 鲁ICP备2020034310号
        \ No newline at end of file diff --git a/posts/220/index.html b/posts/220/index.html index 8a2c33fc..93e71cd1 100644 --- a/posts/220/index.html +++ b/posts/220/index.html @@ -1,52 +1,133 @@ Markdown 编辑器推荐 | Zs's Blog -

        Markdown 编辑器推荐

        前言

        近期著名 Markdown 编辑器 Typora 宣布收费了,起初感觉很难受,后来感慨之余也觉得算是合理,毕竟 Typora 用起来感觉是真的很良心,也在考虑是否买一份支持一下。

        已于2021/12/10购入,还是选择回归了 Typora 了哈哈哈

        虽说左右分屏的设计可能更符合 Markdown 的初衷,但是像 Typora 这种所见即所得(WYSIWYG) 的书写体验确实是感觉习惯了就回不去了。

        因此近期也搜集了 Markdown 编辑器作为 Typora 的替代品,在这里给大家分享一下。

        特别声明,下面的分享多是我日常体验中的一些感受,可能不够客观,比较片面,大家可以自己使用体验一下!

        一、Obsidian

        界面预览

        Obsidian

        特点

        • 具有文档的双向链接

        • 支持行级和块级公式

        • 官网可以购买 sync 套餐保持各个客户端同步

        • 可以购买 publish 服务将 markdown 发布为排版美观的界面

        • 有丰富的插件,例如日历、待办清单、Git同步等等。

        • 有Linux,Windows,iPad等多平台支持。

        使用体验

        Obsidian 中文为黑曜石。我觉得它的图标很好看。

        在我使用的一段时间内,他给我的感觉是,功能十分丰富的一个 Markdown 文件管理工具。如果你购买了他的同步服务,那你可以很轻松的在各平台同步你的 Markdown 文件夹,并且基于他强大的插件,可以很完成很多 Markdown 文件份外的事,例如待办清单、日历等等。

        他虽没有所见即所得的模式,但是依靠其一款第三方插件,可以达成类似的效果,不过还是用起来不如 Typora 这种顺手。同时,它的各端同步如果不开启官方的服务,用起来还是挺麻烦的,经过我的一阵倒腾,我总结了如下几个方案:

        1. 使用第三方Git管理插件,可以定时推送文件夹中的内容到仓库,这样可以完成 linux 与 Windwos 平台的同步,只需要在某一方推送某一方拉取即可。而 Windows 平台与 iPad 平台的同步,可以借助 Apple 的 iCloud,Windows上有对应的客户端,这也是 Obsidian 官方支持的。不过在我使用的过程中我发现,这样异常的麻烦,使用 Git 来管理很可能会产生冲突,导致需要手动处理冲突,久而久之就会觉得很烦。

        2. 使用自建云盘如 NextCloud + Obsidian,或者 Seafile + Obsidian。 这个是我觉得目前非常可行的一个方案,最近我也有在尝试 NextCloud,它的多端同步做的非常不错,依靠此可以在各个平台同步文件夹,加上 Obsidian 强悍的能力,是不错的组合!

        二、Mark Text

        界面预览

        Mark Text

        特点

        • 开源!!

        • 所见即所得(WYSIWYG)

        • 支持行级和块级公式

        • 界面简洁且美观

        • Windows,Linux 等多平台支持,不支持 iPad

        • 缺点:目前仍不支持中文

        使用体验

        Mark Text 是 Github 上一个开源的项目

        个人认为他是在对标 Typora 的一个软件,有着和 Typora 非常相近的写作手感,并且界面简洁美观,我个人真的是非常喜欢,也是我目前在用的一款编辑器,本篇文章就是使用此编辑器书写。

        它的可配置程度虽然没有 Typora 那么高,但是平常的使用已经足够。不过值得说道的是,他不支持导出 Word 文档,而且对用公式的补全做的不够完美。

        可能还是有一些 bug 的,软件的最后一次 release 还是在 2020 年了(说明非常的稳定啊哈哈)。不过贵在他是个开源的软件,有很多大佬愿意为之奉献,期待后续的更新!

        三、Zettlr

        界面预览

        Zettlr

        特点

        • 开源!!

        • 可导出的格式非常的多,如 Latex、Word 等都可以。

        • 可以说是所见即所得,不过和 Typora 的理念略有不同。

        • 支持 Windows、Linux 等平台。

        • 支持语言的种类要比 Mark Text 多很多。

        • 缺点:自认为界面没有 Mark Text 和 Typora 这种好看。

        使用体验

        上面的有个特点我描述的是 “可以说是所见即所得,不过和 Typora 的理念略有不同”

        我感觉它的所见即所得不是纯正的所见即所得,还是会保留部分源代码的元素在上面。不过他支持导出的格式要比 Mark Text 多不少。

        同时他也支持任务清单这种小功能,但是我认为它没有 Mark Text 美观和好用。使用的也不算太多,就不过多的评价了~

        四、VSCode + 插件

        界面预览

        其中一个插件(vscode all markdown)

        特点

        • 基于 VSCode 这个宇宙第一编辑器,不需要装别的软件

        • 可选的插件很多,不差这个一个

        • 多是基于 vditor,对 vditor 有钟爱的同学不要错过!

        • 所见即所得

        使用体验

        因为我自己没有深度体验这个东西,但是我认为功能还是很强大的~

        虽然说,他可能没有一个单独的软件配置项那么多,但是贵在他只是一个集成于 VSCode 的插件,不要安装一个那么大体量的软件。

        同时可以很快的在代码与文档之间切换,这应该也算是一个优势了。

        后记

        本来想把这个博文做成一个各类软件推荐文的,但是写着写着发现光是 Markdown 类的已经可以写很多了,为了防止篇幅过长,就单做一个 Markdown 编辑器的推荐文吧~

        如果大家有更好的 Markdown 编辑器推荐,欢迎在下面留言!

        \ No newline at end of file diff --git a/posts/221/index.html b/posts/221/index.html index 05a5e180..792aa41e 100644 --- a/posts/221/index.html +++ b/posts/221/index.html @@ -1,38 +1,74 @@ 记一次博客迁移记录 | Zs's Blog -

        记一次博客迁移记录

        前言

        更换博客系统的想法已经萌生很久了,一个是感觉 Handsome 这个主题有点看腻了,但是在 Typecho 中好似已经没有更好的博客主题可选择了。

        有一个看起来貌似很不错,主题名叫 maupassant。效果如下图所示,顺附链接

        pagecho/maupassant(github.com)

        maupassant

        不过一直没有下定决心更换,后来也尝试过使用 WordPress,又觉得 WordPress 体量有点太大了。

        每天逛 Github 的时候看到了很多很不错的静态博客主题,那天看到一个学长分析学校校园网的博客,第一眼就感觉很不错,找寻了一下发现博客基于 Hugo,主题是 hugo-PaperMod

        于是顺着寻找了一下,发现 Hugo 中很多博客主题非常的不错。此外,Hugo 相比于 Hexo 也有很多优点:博客构建速度快,基于模板的概念组织内容,环境配置容易,在 Ubuntu 下一行命令即可,而 Hexo 依赖于 Node.js,体量稍微有点大。

        于是决定把博客迁移到 Hugo,并且采用主题 Coder

        过程

        Typecho 文章导出

        这里采用了 lizheming 大大的迁移插件:lizheming/typecho-export-hugo

        具体导出为 zip 的时候可能会提示损坏,这样的话可以直接去服务器 \tmp\Export2Hugo 下面打包。

        安装 hugo

        过程基于 Windows 平台,很简单,在 这里 下载 hugo 最新的 release 版本,找到对应自己系统的即可。下载后解压到某个目录下,设置一下环境变量即可。这里牵扯到 hugo 和 hugo_extended 两个版本的区别,以下是某个 issue 中的解释:

        I agree.

        • The only functional difference is SASS/SCSS
        • The technical build time difference is that it requires a C++ build chain for the target platform to build, the reason why we currently only build the extended for 3 platforms (Windows, Linux, MacOS)
        • Binaries are slightly less portable as you need a compatible Libc version on your computer (for Windows we build a fully static version as Libc is rather uncommon unless you have Visual Studio or something installed).

        via: Please document the difference between the “extended” and non-“extended” versions

        我认为,直接使用 extended 版本就完事了。使用了 extended 不会报错,而不用 extended 版本可能会报错。

        构建网站

        首先在合适的目录下生成一个新的网站

        $ hugo new site zsblog
        +
        +The only functional difference is SASS/SCSS
        +The technical build time difference is that it requires a C++ build chain for the target platform to build, the reason why we currently only build the extended for 3 platforms (Windows, Linux, MacOS)
        +Binaries are slightly less portable as you need a compatible Libc version on your computer (for Windows we build a fully static version as Libc is rather uncommon unless you have Visual Studio or something installed).
        +
        +via: Please document the difference between the “extended” and non-“extended” versions">

        记一次博客迁移记录

        前言

        更换博客系统的想法已经萌生很久了,一个是感觉 Handsome 这个主题有点看腻了,但是在 Typecho 中好似已经没有更好的博客主题可选择了。

        有一个看起来貌似很不错,主题名叫 maupassant。效果如下图所示,顺附链接

        pagecho/maupassant(github.com)

        maupassant

        不过一直没有下定决心更换,后来也尝试过使用 WordPress,又觉得 WordPress 体量有点太大了。

        每天逛 Github 的时候看到了很多很不错的静态博客主题,那天看到一个学长分析学校校园网的博客,第一眼就感觉很不错,找寻了一下发现博客基于 Hugo,主题是 hugo-PaperMod

        于是顺着寻找了一下,发现 Hugo 中很多博客主题非常的不错。此外,Hugo 相比于 Hexo 也有很多优点:博客构建速度快,基于模板的概念组织内容,环境配置容易,在 Ubuntu 下一行命令即可,而 Hexo 依赖于 Node.js,体量稍微有点大。

        于是决定把博客迁移到 Hugo,并且采用主题 Coder

        过程

        Typecho 文章导出

        这里采用了 lizheming 大大的迁移插件:lizheming/typecho-export-hugo

        具体导出为 zip 的时候可能会提示损坏,这样的话可以直接去服务器 \tmp\Export2Hugo 下面打包。

        安装 hugo

        过程基于 Windows 平台,很简单,在 这里 下载 hugo 最新的 release 版本,找到对应自己系统的即可。下载后解压到某个目录下,设置一下环境变量即可。这里牵扯到 hugo 和 hugo_extended 两个版本的区别,以下是某个 issue 中的解释:

        I agree.

        • The only functional difference is SASS/SCSS
        • The technical build time difference is that it requires a C++ build chain for the target platform to build, the reason why we currently only build the extended for 3 platforms (Windows, Linux, MacOS)
        • Binaries are slightly less portable as you need a compatible Libc version on your computer (for Windows we build a fully static version as Libc is rather uncommon unless you have Visual Studio or something installed).

        via: Please document the difference between the “extended” and non-“extended” versions

        我认为,直接使用 extended 版本就完事了。使用了 extended 不会报错,而不用 extended 版本可能会报错。

        构建网站

        首先在合适的目录下生成一个新的网站

        $ hugo new site zsblog
         

        然后进入目录后,初始化一个 git 仓库

        $ git init
         

        [可选]将自己心仪的目录设置为 git 的 submodule ,需要注意的是,hugo 中的主题配置多是基于 submodule 的,这种方式很灵活,也便于更新,当然,需要先学习一下 submodule 的用法:) ,这里以 coder 主题为例:

        $ git submodule add https://github.com/luizdepra/hugo-coder.git themes/hugo-coder
         

        然后基于对应主题的 exampleSite 来设定对应的配置文件 config.toml,这里很蛋疼的是 coder 主题居然偏爱 toml 配置格式,为什么不是 yaml/json 呢?

        补充:hugo 支持三种格式的配置文件 yaml, toml, json.

        然后启动博客即可

        $ hugo server
        @@ -91,5 +127,5 @@
         
        + PaperMod | 鲁ICP备2020034310号
        \ No newline at end of file diff --git a/posts/223/index.html b/posts/223/index.html index a2153c73..4e0986b5 100644 --- a/posts/223/index.html +++ b/posts/223/index.html @@ -1,50 +1,122 @@ 一个 Javascript 中异步的小技巧 | Zs's Blog -

        一个 Javascript 中异步的小技巧

        Table of Contents

        前言

        最近看了一些 js 有关的知识,其中令我这种初学者感到很头疼的一个问题就是异步问题。

        今天就我碰到的一个小问题详解一个关于异步的小技巧。

        背景

        我在程序中需要鉴权,来判断一个用户是普通用户还是管理员,针对不同的用户渲染不同的页面。

        每个用户具有唯一的 ID,因此我只需要将管理员的 ID 放到数据库,然后加载程序的时候一一比对即可。

        但是我的主程序初始化与页面的初始化是异步的,管理员的判断逻辑我放在了主程序初始化中,这也就意味着很可能我页面在加载时,主程序还没有判断完用户的身份。

        每个人默认不是管理员,因此这就会导致一个问题——管理员可能也会显示成普通用户的页面,因为渲染页面的时候程序还不知道这个用户是管理员。

        方案

        这个方案其实是我从官方的代码上学到的,其实就结合代码给大家讲一下。

        官方这里是在获取用户的 userInfo 时用到的。

        主程序初始化部分代码

        这里主程序的逻辑就是在 getSetting 调用成功后,判断是否已经获得过 userInfo ,如果已经获得过,则可以直接调用 getUserInfo 函数获取值,赋值成一个主程序的全局变量,所有页面都可以用。

        接下来就是一个比较奇怪的点了

        可以看到官方的注释为

        由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回

        所以此处加入 callback 以防止这种情况

        这里判断了主程序内是否含有 userInfoReadyCallback 这个函数,如果有的话就执行。

        qq.getSetting({
        +qq.getSetting({
        +            success: res => {
        +                if (res.authSetting['scope.userInfo']) {
        +                    // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
        +                    qq.getUserInfo({
        +                        success: res => {
        +                            // 可以将 res 发送给后台解码出 unionId
        +                            this.globalData.userInfo = res.userInfo
        +
        +                            // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
        +                            // 所以此处加入 callback 以防止这种情况
        +                            if (this.userInfoReadyCallback) {
        +                                this.userInfoReadyCallback(res)
        +                            }
        +                        }
        +                    })
        +                }
        +            }
        +        })
        +页面初始化部分代码:">

        一个 Javascript 中异步的小技巧

        Table of Contents

        前言

        最近看了一些 js 有关的知识,其中令我这种初学者感到很头疼的一个问题就是异步问题。

        今天就我碰到的一个小问题详解一个关于异步的小技巧。

        背景

        我在程序中需要鉴权,来判断一个用户是普通用户还是管理员,针对不同的用户渲染不同的页面。

        每个用户具有唯一的 ID,因此我只需要将管理员的 ID 放到数据库,然后加载程序的时候一一比对即可。

        但是我的主程序初始化与页面的初始化是异步的,管理员的判断逻辑我放在了主程序初始化中,这也就意味着很可能我页面在加载时,主程序还没有判断完用户的身份。

        每个人默认不是管理员,因此这就会导致一个问题——管理员可能也会显示成普通用户的页面,因为渲染页面的时候程序还不知道这个用户是管理员。

        方案

        这个方案其实是我从官方的代码上学到的,其实就结合代码给大家讲一下。

        官方这里是在获取用户的 userInfo 时用到的。

        主程序初始化部分代码

        这里主程序的逻辑就是在 getSetting 调用成功后,判断是否已经获得过 userInfo ,如果已经获得过,则可以直接调用 getUserInfo 函数获取值,赋值成一个主程序的全局变量,所有页面都可以用。

        接下来就是一个比较奇怪的点了

        可以看到官方的注释为

        由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回

        所以此处加入 callback 以防止这种情况

        这里判断了主程序内是否含有 userInfoReadyCallback 这个函数,如果有的话就执行。

        qq.getSetting({
                     success: res => {
                         if (res.authSetting['scope.userInfo']) {
                             // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
        @@ -83,5 +155,5 @@
         
        + PaperMod | 鲁ICP备2020034310号
        \ No newline at end of file diff --git a/posts/224/index.html b/posts/224/index.html index 3ba099ef..1a360a9b 100644 --- a/posts/224/index.html +++ b/posts/224/index.html @@ -1,7 +1,10 @@ 关于春节期间的一些碎碎念 | Zs's Blog -

        关于春节期间的一些碎碎念

        前言

        春节期间,走亲访友是必不可少的。交谈的多了,免不得一些问题的讨论。

        读了很多书,经历了很多事,似乎想法也有一些”离经叛道“,记一下自己目前的一些想法,不知道多年后的自己看这篇文章会是什么想法,还会一如既往的坚持吗。

        讨论的话题

        打点关系

        无论是父母,还是各方亲戚,大家好像都喜欢打点关系,以此来获得一些好处。

        最常见的是求人办事,很多时候是我们常说的”走后门“,想让孩子上个好点的小学,避免不了又送礼又吃饭。

        事件上升的恶劣一些,定然就是贪污受贿,这肯定是错的,大家都知道,但是度在哪里呢。

        和我儿时的哥哥探讨中,他认为,这种送礼打点关系是必要的,送点小礼没啥问题。而我总觉得,这就是0、1、无穷的区别,有一就有二,有二就有无穷。

        从出生到现在,试问自己从没遇到过必须送礼才能办成的事,或许以后会遇到,但我想、我应该宁愿放弃这个机会也不会去送礼打点。

        大家都对我说:“你现在是这个想法,是没有经历过社会的毒打,你踏入社会就也会这样了。”,我无言。

        或许吧,或许以后也会变成善于打点关系、整天辗转于酒局的人。

        至少我现在,还是个滴酒不沾、不屑于打点的鸟人。

        酒文化

        我是个滴酒不沾的人

        有两点比较重要的原因

        一个是因为酒真的很难喝,好喝也就罢了,难喝为什么要喝呢?

        二是因为我真的很讨厌饭桌上推杯换盏,你推我我推你,大家都喝得烂醉如泥。村里有很多喝酒出事去世的例子,小时候看见一个哥哥的朋友,喝醉后在大街上和别人干架,然后在欢喜的日子里一起进医院···何必呢?

        推杯换盏还导致饭菜里会混入多多少少的酒,真的不好吃。

        大家为什么都不能别这么执拗,这里用执拗可能不合适,不过没想到什么好的词语。人家明明都说了不喝、不吃,为什么还总要一遍遍的推脱?最后立场不坚定的,只能不情愿地吃了。立场坚定的,又闹得双方不愉快似的。

        还有很多明明想喝、想吃,却又怕尴尬嘴上说着不喝不吃,一样可恶。

        硬唠

        平时在家总喜欢窝在自己的屋子里,倒腾自己的事情。

        亲戚来了,似乎不出去跟他们聊天就是个错误。总是要数落你一下,在饭桌上调侃你一下,跟家长阴阳怪气一下你。

        不想说的是,真的感觉没有什么共同话题,聊不到一起去,实在是没什么话说,只能在那里低头玩手机,哦对了,手机也不得玩,玩多了也会被说。只能在那里干坐着东看西看,听大家侃大山,却因为离家过久大多事都没听说过,时间白白的浪费。

        人际关系真的蛮烦的。

        关于入党

        最近舅家的哥哥萌生了入党的想法,说:”就算无论花多少钱,也得入党。“

        我问,那你入党又是为了做什么呢?

        他说,入党好啊,入党好啊,入党可以在村委里谋个一官半职,可以轻松一些,赚钱也多。

        我说你不应该为了自己的私利来入党,他说,人不为己天诛地灭,没有人不顾自己的私利。

        实话的讲,我哥哥是个不错的人,乐于与村里人交善,村民家里出什么事他也喜欢帮忙。但是这个入党的观念真的让我不理解,入党是应该认为认同,而不是因为利益驱使。

        大家入党好似都是为了后续能谋个公务员的出路,如果能贯彻为人民服务的宗旨还好,如果一心为了钱,很容易会变成蛀虫、老虎,那这样的话,不如踏踏实实另谋出路。

        后记

        春节期间思考了很多,感觉与周围的很多亲戚们都格格不入。

        文章算是想到什么写什么,可能看起来杂乱无章,见谅。文章也只是我自己的一些看法,不代表普遍性,也无言对错,大家看看就好。

        还好的是,我的亲戚们大多不会问我,考的咋样,有对象了没……

        之前与一个舅家的哥哥很要好(与上文不是同一个),因为之前感觉我们两人观念很类似,亲戚们也都觉得我们两个像。

        这个春节与他进一步交流了一些,似乎观念不尽相同了。

        现在他步入社会,参加了工作,开始应付酒局,也会打点关系了。也开始教导我应该善于打点。

        我以后也会这样吗?

        \ No newline at end of file diff --git a/posts/23/index.html b/posts/23/index.html index 8551b8ce..0fda844e 100644 --- a/posts/23/index.html +++ b/posts/23/index.html @@ -5,9 +5,9 @@ 最近感觉遇到了好多单调队列和单调栈的问题,但是因为以前没学好,所以遇见了就一脸懵逼,然后绝对下决心来学一下。。感觉遇到啥都不会,这可咋办呐。。补不完的漏洞。 ">

        单调队列和单调栈总结

        前言

        最近感觉遇到了好多单调队列和单调栈的问题,但是因为以前没学好,所以遇见了就一脸懵逼,然后绝对下决心来学一下。。感觉遇到啥都不会,这可咋办呐。。补不完的漏洞。
        +">

        单调队列和单调栈总结

        前言

        最近感觉遇到了好多单调队列和单调栈的问题,但是因为以前没学好,所以遇见了就一脸懵逼,然后绝对下决心来学一下。。感觉遇到啥都不会,这可咋办呐。。补不完的漏洞。
         

        单调队列(Monotone queue)

        单调队列,即单调递减或单调递增的队列。使用频率不高,但在有些程序中会有非同寻常的作用。

        理解

        顾名思义,他就是一个单调的队列,那么我们可以规定他是单调递增的还是单调递减的,他和普通的队列有点区别,队列一般是尾进头出,而单调队列要实现的话要确保头和尾都可以出,尾可以进。如果要用STL库的话可以用里面的双端队列。 -跟普通队列相比他的进队需要确保一个条件就是要不破坏原有序列的单调性,好比我们有一个单调递增的单调队列,也就是从队首到队尾是单调递增的,那么有一段序列是 $[2,3,1,5,8,7,4,2]$ ,我们从左到右依次入队。

        队列中元素关于元素进出的备注
        22入队
        2,33比2大,可以满足递增性质,入队
        1因为1比2,3都小,要满足递增性质,先把2,3出队,再将1入队
        1,55比1大,可以满足递增性质,入队
        1,5,88比5大,可以满足递增性质,入队
        1,5,77小于8,大于5,要满足递增性质,我们把8出队,然后将7入队
        1,44小于5、7,但是大于1,因此7,5依次出队,4入队
        1,22小于4,大于1,因此4出队,2入队

        根据上述例子不难看出,我们要入队的时候首先要确保队尾元素要比想要入队的元素小,然后才能入队,否则的话就一直循环让尾部元素出队,直到能够满足单调性为止。

        单调队列的应用

        • 求区间的最值问题。下面写的两个例题都是这个用处。
        • 优化dp,我现在能接触到的就是一个用单调队列优化多重背包的一个题,但是那个题我学了这个东西之后还是不理解为什么可以那么做。例题如下:宝物筛选

        单调队列的一些例题

        A. Sliding Window


        题意

        给出一个含有 $n$ 个整数的序列 $a$ ,给出滑动窗口长度 $k$ ,窗口从序列最左端滑动到序列最右端,问滑动过程中每个时刻窗口中最大值和最小值是多少。

        思路

        一道很经典的单调队列的模板题,用于解决定长区间的最大最小值。我们可以维护两个单调队列,一个是单调递增的,一个是单调递减的。因为两种情况类似,我们考虑一下求窗口中最大值的方案。

        求最大值我们用的是单调递减的序列,这样就能够保证每次队首的就是答案,但是,这是为什么呢?我们来考虑一下,因为这是一个单调递减的序列,那么我们每次序列元素入队的时候,我们就去看当前队尾的元素是不是要比他大,如果比他还小,那么我们就直接将队尾元素出队,因为这时候要入队的元素(已经被窗口覆盖了)已经比他大了,那么在接下来的窗口中,肯定就没他什么事了,因为它一定不是最大的,那么如果一直将队尾元素出队到加入入队元素后还继续能保持队列的单调性了,但是这个元素还不是在队首,这就说明,队首的元素还是要比他大的(单调性易得)。

        所以这时候队首元素就是这个窗口中最大的了吗?也还不能确定,因为我们还不能确保这个队首元素就在窗口中,因此我们需要看看这个元素的位置和当前入队元素的位置之差是不是要比窗口长度大了,如果大于窗口长度,那么就说明队首元素已经不在窗口了,我们就将队首元素出队,最后输出队首元素就能确保它既在窗口中,又是窗口中所有元素的最大值了!

        代码实现

        #include<cstdio>
        +跟普通队列相比他的进队需要确保一个条件就是要不破坏原有序列的单调性,好比我们有一个单调递增的单调队列,也就是从队首到队尾是单调递增的,那么有一段序列是 $[2,3,1,5,8,7,4,2]$ ,我们从左到右依次入队。

        队列中元素关于元素进出的备注
        22入队
        2,33比2大,可以满足递增性质,入队
        1因为1比2,3都小,要满足递增性质,先把2,3出队,再将1入队
        1,55比1大,可以满足递增性质,入队
        1,5,88比5大,可以满足递增性质,入队
        1,5,77小于8,大于5,要满足递增性质,我们把8出队,然后将7入队
        1,44小于5、7,但是大于1,因此7,5依次出队,4入队
        1,22小于4,大于1,因此4出队,2入队

        根据上述例子不难看出,我们要入队的时候首先要确保队尾元素要比想要入队的元素小,然后才能入队,否则的话就一直循环让尾部元素出队,直到能够满足单调性为止。

        单调队列的应用

        • 求区间的最值问题。下面写的两个例题都是这个用处。
        • 优化dp,我现在能接触到的就是一个用单调队列优化多重背包的一个题,但是那个题我学了这个东西之后还是不理解为什么可以那么做。例题如下:宝物筛选

        单调队列的一些例题

        A. Sliding Window


        题意

        给出一个含有 $n$ 个整数的序列 $a$ ,给出滑动窗口长度 $k$ ,窗口从序列最左端滑动到序列最右端,问滑动过程中每个时刻窗口中最大值和最小值是多少。

        思路

        一道很经典的单调队列的模板题,用于解决定长区间的最大最小值。我们可以维护两个单调队列,一个是单调递增的,一个是单调递减的。因为两种情况类似,我们考虑一下求窗口中最大值的方案。

        求最大值我们用的是单调递减的序列,这样就能够保证每次队首的就是答案,但是,这是为什么呢?我们来考虑一下,因为这是一个单调递减的序列,那么我们每次序列元素入队的时候,我们就去看当前队尾的元素是不是要比他大,如果比他还小,那么我们就直接将队尾元素出队,因为这时候要入队的元素(已经被窗口覆盖了)已经比他大了,那么在接下来的窗口中,肯定就没他什么事了,因为它一定不是最大的,那么如果一直将队尾元素出队到加入入队元素后还继续能保持队列的单调性了,但是这个元素还不是在队首,这就说明,队首的元素还是要比他大的(单调性易得)。

        所以这时候队首元素就是这个窗口中最大的了吗?也还不能确定,因为我们还不能确保这个队首元素就在窗口中,因此我们需要看看这个元素的位置和当前入队元素的位置之差是不是要比窗口长度大了,如果大于窗口长度,那么就说明队首元素已经不在窗口了,我们就将队首元素出队,最后输出队首元素就能确保它既在窗口中,又是窗口中所有元素的最大值了!

        代码实现

        #include<cstdio>
         #include<cstring>
         #include<algorithm>
         #include<cmath>
        @@ -116,7 +116,7 @@
         	}
         	return 0;
         } 
        -

        单调栈(Monotone stack)

        单调增或单调减的栈,跟单调队列差不多,但是只用到它的一端。

        理解

        单调栈也是在普通栈的基础上加了单调性,一般是用从栈底到栈顶的单调性来命名,好比从栈底到栈顶是单调递增的,那么他就是单调增的栈。跟单调队列一样,他的入栈规则也是要不破坏单调性,因此一个单调递增的栈如果有元素要入栈,如果他比栈顶的元素还要大,就可以直接入栈,如果他比栈顶的元素小,那么就要将栈顶的元素一直出栈到比要入栈元素小为止。如果序列为 $[2,3,1,5,4,7]$,要加入单调递增栈中,过程如下。PS:注意从左到右对应栈底到栈顶。

        栈中的元素关于元素进出的备注
        2元素2压入栈中
        2,33大于2,压入栈中
        11小于3、2,因此全部弹出将1入栈
        1,55大于1,压入栈中
        1,44比5小,比1大,弹出5,压入4
        1,4,77大于4,压入栈中

        根据上述描述不难看出,其实单调栈就是单调队列的半部分,他能完成的任务理论上单调队列都能够完成,但是有些时候不需要麻烦的去维护单调队列只需要维护单调栈即可完成。

        单调栈的应用

        • 确定一个元素的左边区间第一个比它大的元素,第一个比它小的元素
        • 确定右边区间第一个比他大or比他小的元素(根据单调性来看)
        • 确定这个元素是否是一定区间内的最值,或者确定以他为最值的区间长度

        单调栈的一些例题

        A. 单调栈模板

        题意

        给出含有 $n$ 个整数的序列 $a$ ,定义 $f(i)$ 为第 $i$ 个元素后第一个大于 $a_i$ 的下标,求 $f(1)\cdots f(n)$

        思路

        直接就是模板,对应了上述应用里的第二个。

        代码实现

        #include<cstdio>
        +

        单调栈(Monotone stack)

        单调增或单调减的栈,跟单调队列差不多,但是只用到它的一端。

        理解

        单调栈也是在普通栈的基础上加了单调性,一般是用从栈底到栈顶的单调性来命名,好比从栈底到栈顶是单调递增的,那么他就是单调增的栈。跟单调队列一样,他的入栈规则也是要不破坏单调性,因此一个单调递增的栈如果有元素要入栈,如果他比栈顶的元素还要大,就可以直接入栈,如果他比栈顶的元素小,那么就要将栈顶的元素一直出栈到比要入栈元素小为止。如果序列为 $[2,3,1,5,4,7]$,要加入单调递增栈中,过程如下。PS:注意从左到右对应栈底到栈顶。

        栈中的元素关于元素进出的备注
        2元素2压入栈中
        2,33大于2,压入栈中
        11小于3、2,因此全部弹出将1入栈
        1,55大于1,压入栈中
        1,44比5小,比1大,弹出5,压入4
        1,4,77大于4,压入栈中

        根据上述描述不难看出,其实单调栈就是单调队列的半部分,他能完成的任务理论上单调队列都能够完成,但是有些时候不需要麻烦的去维护单调队列只需要维护单调栈即可完成。

        单调栈的应用

        • 确定一个元素的左边区间第一个比它大的元素,第一个比它小的元素
        • 确定右边区间第一个比他大or比他小的元素(根据单调性来看)
        • 确定这个元素是否是一定区间内的最值,或者确定以他为最值的区间长度

        单调栈的一些例题

        A. 单调栈模板

        题意

        给出含有 $n$ 个整数的序列 $a$ ,定义 $f(i)$ 为第 $i$ 个元素后第一个大于 $a_i$ 的下标,求 $f(1)\cdots f(n)$

        思路

        直接就是模板,对应了上述应用里的第二个。

        代码实现

        #include<cstdio>
         #include<cstring>
         #include<algorithm>
         #include<cmath>
        @@ -241,5 +241,5 @@
         
        + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/posts/24/index.html b/posts/24/index.html index 7d185073..81bae870 100644 --- a/posts/24/index.html +++ b/posts/24/index.html @@ -5,7 +5,7 @@ 题意 有一个 $N*N$ 的整数方阵,每个点初始值为0,在一些点上放上数,一个人从左上角走到右下角,规定只能向下或向右走,当他经过的点上有数时会取走它,问走两遍最多能取的数的和最大为多少。">

        dp习题练习

        A. 方格取数

        题意

        有一个 $N*N$ 的整数方阵,每个点初始值为0,在一些点上放上数,一个人从左上角走到右下角,规定只能向下或向右走,当他经过的点上有数时会取走它,问走两遍最多能取的数的和最大为多少。

        思路

        也就是说我们要找两条路径使他取数最大,首先我一开始想法是先走一遍,找到最大的那个路径,将这条路径上所有点设为0,然后再回来找这个方阵中最大的那个路径,两个加起来就行。但是路径上所有的点设为0这个地方不是很好实现,因此我们可以考虑另一个思路,两次同时走。我们把这两次看成两个人走的,表述方便。 +有一个 $N*N$ 的整数方阵,每个点初始值为0,在一些点上放上数,一个人从左上角走到右下角,规定只能向下或向右走,当他经过的点上有数时会取走它,问走两遍最多能取的数的和最大为多少。">

        dp习题练习

        A. 方格取数

        题意

        有一个 $N*N$ 的整数方阵,每个点初始值为0,在一些点上放上数,一个人从左上角走到右下角,规定只能向下或向右走,当他经过的点上有数时会取走它,问走两遍最多能取的数的和最大为多少。

        思路

        也就是说我们要找两条路径使他取数最大,首先我一开始想法是先走一遍,找到最大的那个路径,将这条路径上所有点设为0,然后再回来找这个方阵中最大的那个路径,两个加起来就行。但是路径上所有的点设为0这个地方不是很好实现,因此我们可以考虑另一个思路,两次同时走。我们把这两次看成两个人走的,表述方便。 我们用 $dp[i][j][k][l]$ 来表示当第一个人走到 $(i,j)$ 第二个人走到 $(k,l)$ 时做能取数最多为多少 ,那么我们就可以考虑一下转移怎么转移,因为到达一个点只能是从左边来,或者是从上边来,因此第一个人从 $(i-1,j)$ 或者 $(i,j-1)$ 转移来,那么第二个人就从 $(k-1,l)$ 或者 $(k,l-1)$ 转移来,那么这个转移方程就是四种转移方式。我们需要保证一个问题,就是他俩经过同一个点的判定情况。我们需要将第二个人的坐标通过第一个人来限制,也就是说要确保第二个人和第一个人步数是相同的,当他们步数相同的时候,那么就不存在他们经过同一个点但是时间却是不同的情况了,因为到达一个点的步数是一定的。 再就是这个状态数组其实还是可以压缩到三维和二维的,这个就先不谈了,可以看洛谷的题解区。 这个题是一个经典的多维dp的题目,感觉还是挺有意义的。而且这个题和 传纸条 很像,可以双倍经验。

        代码实现

        #include<cstdio>
        @@ -215,5 +215,5 @@
         
        + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/posts/25/index.html b/posts/25/index.html index 8f69787f..b6030c11 100644 --- a/posts/25/index.html +++ b/posts/25/index.html @@ -2,7 +2,7 @@

        日常水题

        前言

        今天又是颓废的一天,被大佬拉去跟他一起做牛客网的题,QAQ…那我会点啥嘛,就只能替大佬写两道水题了···


        A. 牛牛战队的比赛地

        题意

        由于牛牛战队经常要外出比赛,因此在全国各地建立了很多训练基地,每一个基地都有一个坐标 $(x,y)$ 。 +今天又是颓废的一天,被大佬拉去跟他一起做牛客网的题,QAQ…那我会点啥嘛,就只能替大佬写两道水题了···">

        日常水题

        前言

        今天又是颓废的一天,被大佬拉去跟他一起做牛客网的题,QAQ…那我会点啥嘛,就只能替大佬写两道水题了···


        A. 牛牛战队的比赛地

        题意

        由于牛牛战队经常要外出比赛,因此在全国各地建立了很多训练基地,每一个基地都有一个坐标 $(x,y)$ 。 这周末,牛牛队又要出去比赛了,各个比赛的赛点都在 $x$ 轴上。牛牛战队为了方便比赛,想找一个到达训练基地最大距离最小的地方作为比赛地。请你求出选择的比赛地距离各训练基地最大距离的最小值。

        思路

        这个题首先一看到这种什么最大的最小,第一直觉就是二分。首先我们想一下应该二分什么,肯定先想的是枚举 $x$ 轴上的点,但是这样就会有个问题,二分要用的话必须是单调的,那么我们不能够确定越往右或者越往左,他们的这个值是单调的。因此我们可以用三分,一直向单峰逼近,最终寻找到那个极值点。(说实话这是我第一次接触到三分法,我太菜了。)

        代码实现

        #include<cstdio>
         #include<cstring>
         #include<iostream>
        @@ -182,5 +182,5 @@
         
        + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/posts/26/index.html b/posts/26/index.html index 3a71f5af..8c59208c 100644 --- a/posts/26/index.html +++ b/posts/26/index.html @@ -5,7 +5,7 @@ 题意 给定三个长度为 $n$ 的字符串 $a$ , $b$ , $c$ ,遍历每个 $c$ 中每个字符 $c_i$,可以将其替换成 $a_i$ 或者 $b_i$ ,必须操作其中一个,问能否通过此操作使得字符串 $a$ , $b$ 相同。">

        Codeforces#619 (Div.2)

        A. Three Strings

        题意

        给定三个长度为 $n$ 的字符串 $a$ , $b$ , $c$ ,遍历每个 $c$ 中每个字符 $c_i$,可以将其替换成 $a_i$ 或者 $b_i$ ,必须操作其中一个,问能否通过此操作使得字符串 $a$ , $b$ 相同。

        思路

        仔细思考一下,如果要使得最终两个字符串相同的话,必须字符串 $c$ 中出现的字符,在 $a$ 或者 $b$ 字符串出现过,如果每个位置都出现过,那么就是可以的,否则不行。

        代码实现

        #include<cstdio>
        +给定三个长度为 $n$ 的字符串 $a$ , $b$ , $c$ ,遍历每个 $c$ 中每个字符 $c_i$,可以将其替换成 $a_i$ 或者 $b_i$ ,必须操作其中一个,问能否通过此操作使得字符串 $a$ , $b$ 相同。">

        Codeforces#619 (Div.2)

        A. Three Strings

        题意

        给定三个长度为 $n$ 的字符串 $a$ , $b$ , $c$ ,遍历每个 $c$ 中每个字符 $c_i$,可以将其替换成 $a_i$ 或者 $b_i$ ,必须操作其中一个,问能否通过此操作使得字符串 $a$ , $b$ 相同。

        思路

        仔细思考一下,如果要使得最终两个字符串相同的话,必须字符串 $c$ 中出现的字符,在 $a$ 或者 $b$ 字符串出现过,如果每个位置都出现过,那么就是可以的,否则不行。

        代码实现

        #include<cstdio>
         #include<cstring>
         #include<algorithm>
         #include<cmath>
        @@ -116,5 +116,5 @@
         
        + PaperMod | 鲁ICP备2020034310号
        \ No newline at end of file diff --git a/posts/27/index.html b/posts/27/index.html index ad05deaa..607c0dd7 100644 --- a/posts/27/index.html +++ b/posts/27/index.html @@ -5,7 +5,7 @@ 题意 给定含有 $n$ 个正整数的集合 $A$ 和 $B$ ,你需要建立他们之间的一一映射。将配对的两个数相加可以得到 $n$ 个和,问第 $k$ 大的和最大为多少。">

        杂题训练

        A. 配对

        题意

        给定含有 $n$ 个正整数的集合 $A$ 和 $B$ ,你需要建立他们之间的一一映射。将配对的两个数相加可以得到 $n$ 个和,问第 $k$ 大的和最大为多少。

        思路

        首先我们可以确定,组成前 $k$ 个最大的和一定用的是两个序列里面前 $k$ 大的数字。那么我们只需要知道如何配对能使第 $k$ 大的和最大。我们把问题简化一下如果 $A_1 < A_2$ ,$B_1 < B_2$ ,那么如果想要第二个和最大,肯定是需要 $A_1$ 和 $B_2$ 匹配,$A_2$ 和 $B_1$ 匹配,然后两个选一个最小的。所以这个问题我们类推一下,就是将 $A$ 和 $B$ 序列进行排序,然后取两个里面前 $k$ 个数,$A$ 中大的依次匹配 $B$ 中小的。然后在这 $k$ 个和中取一个最小值即可。

        代码实现

        #include<cstdio>
        +给定含有 $n$ 个正整数的集合 $A$ 和 $B$ ,你需要建立他们之间的一一映射。将配对的两个数相加可以得到 $n$ 个和,问第 $k$ 大的和最大为多少。">

        杂题训练

        A. 配对

        题意

        给定含有 $n$ 个正整数的集合 $A$ 和 $B$ ,你需要建立他们之间的一一映射。将配对的两个数相加可以得到 $n$ 个和,问第 $k$ 大的和最大为多少。

        思路

        首先我们可以确定,组成前 $k$ 个最大的和一定用的是两个序列里面前 $k$ 大的数字。那么我们只需要知道如何配对能使第 $k$ 大的和最大。我们把问题简化一下如果 $A_1 < A_2$ ,$B_1 < B_2$ ,那么如果想要第二个和最大,肯定是需要 $A_1$ 和 $B_2$ 匹配,$A_2$ 和 $B_1$ 匹配,然后两个选一个最小的。所以这个问题我们类推一下,就是将 $A$ 和 $B$ 序列进行排序,然后取两个里面前 $k$ 个数,$A$ 中大的依次匹配 $B$ 中小的。然后在这 $k$ 个和中取一个最小值即可。

        代码实现

        #include<cstdio>
         #include<cstring>
         #include<iostream>
         #include<cmath>
        @@ -133,5 +133,5 @@
         
        + PaperMod | 鲁ICP备2020034310号
        \ No newline at end of file diff --git a/posts/28/index.html b/posts/28/index.html index 99da313b..185106dc 100644 --- a/posts/28/index.html +++ b/posts/28/index.html @@ -2,7 +2,7 @@

        关于STL的一些总结

        前言

        STL之前只会用 stack 和 queue ,set 和 map 啥的也不太会用。学习一下。


        队列(queue)

        概述

        队列是一种特殊的线性表,是一种先进先出(FIFO)的数据结构。它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。

        用法

        首先使用之前需要声明头文件 #include<queue> ,通过 queue<typename> q 的形式来进行定义队列,上述为定义了一个队列元素类型为 typename 的队列,队列名称为 q,typename可以为C++原有数据类型,例如int,char,string这些,也可以是自定义的结构体类型等。

        主要函数及用途

        使用下述函数都是用类似于 队列名称.函数名() 的形式,好比pop函数就是 q.pop()

        1. push(x) 将元素x从队尾入队
        2. front( ) & back( ) 分别为获取队首元素和队尾元素,使用的时候必须确保队列不为空
        3. pop( ) 弹出队首元素,使用的时候必须确保队列不为空
        4. empty( ) 判断队列是否为空,空返回true,不空返回false
        5. size( ) 查询队列中有多少个元素

        应用实例

        #include<cstdio>
        +STL之前只会用 stack 和 queue ,set 和 map 啥的也不太会用。学习一下。">

        关于STL的一些总结

        前言

        STL之前只会用 stack 和 queue ,set 和 map 啥的也不太会用。学习一下。


        队列(queue)

        概述

        队列是一种特殊的线性表,是一种先进先出(FIFO)的数据结构。它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。

        用法

        首先使用之前需要声明头文件 #include<queue> ,通过 queue<typename> q 的形式来进行定义队列,上述为定义了一个队列元素类型为 typename 的队列,队列名称为 q,typename可以为C++原有数据类型,例如int,char,string这些,也可以是自定义的结构体类型等。

        主要函数及用途

        使用下述函数都是用类似于 队列名称.函数名() 的形式,好比pop函数就是 q.pop()

        1. push(x) 将元素x从队尾入队
        2. front( ) & back( ) 分别为获取队首元素和队尾元素,使用的时候必须确保队列不为空
        3. pop( ) 弹出队首元素,使用的时候必须确保队列不为空
        4. empty( ) 判断队列是否为空,空返回true,不空返回false
        5. size( ) 查询队列中有多少个元素

        应用实例

        #include<cstdio>
         #include<iostream>
         #include<queue>
         
        @@ -111,5 +111,5 @@
         
        + PaperMod | 鲁ICP备2020034310号
        \ No newline at end of file diff --git a/posts/29/index.html b/posts/29/index.html index 949095ff..fdd682ca 100644 --- a/posts/29/index.html +++ b/posts/29/index.html @@ -5,7 +5,7 @@ 题意 给定一个 $n\times m$ 的矩阵,其中每个元素为非负整数。每次你可以从每行的行首或行末取一个元素,得到的分数为当前元素的值 $a_{ij}\times 2^k$ ,$k$ 为当前是第几次取该行上的元素。 问最大得分为多少。">

        dp练习

        A. 矩阵取数游戏

        题意

        给定一个 $n\times m$ 的矩阵,其中每个元素为非负整数。每次你可以从每行的行首或行末取一个元素,得到的分数为当前元素的值 $a_{ij}\times 2^k$ ,$k$ 为当前是第几次取该行上的元素。 问最大得分为多少。

        思路

        首先我们发现,虽然答案问的是 $n$ 行,但是我们发现,不同行之间是不会相互影响的,我们只需要讨论一行的情况,然后对每行都处理一遍就可以了。 +给定一个 $n\times m$ 的矩阵,其中每个元素为非负整数。每次你可以从每行的行首或行末取一个元素,得到的分数为当前元素的值 $a_{ij}\times 2^k$ ,$k$ 为当前是第几次取该行上的元素。 问最大得分为多少。">

        dp练习

        A. 矩阵取数游戏

        题意

        给定一个 $n\times m$ 的矩阵,其中每个元素为非负整数。每次你可以从每行的行首或行末取一个元素,得到的分数为当前元素的值 $a_{ij}\times 2^k$ ,$k$ 为当前是第几次取该行上的元素。 问最大得分为多少。

        思路

        首先我们发现,虽然答案问的是 $n$ 行,但是我们发现,不同行之间是不会相互影响的,我们只需要讨论一行的情况,然后对每行都处理一遍就可以了。 那么对于一行上的 $m$ 个元素,我们每一次取都有两种选择,一个是取行首,一个是取行尾。我们发现这是一个区间问题,对于区间 $[i,j]$ 的最优情况,我们可以从 $[i+1,j]$ 和 $[i,j-1]$ 这两个的最优情况转移过来,因此我们可以定义 $f[i][j]$ 是从第 $i$ 个元素到第 $j$ 的元素得分的最大值,然后从上述两个状态转移过来。 还有一个问题就是我们的 $2^k$ 问题,我们考虑到大区间的最优值是从小区间转移来,也就是说小区间乘的指数高,大区间乘的指数低,我们又是从小区间推到大区间,转移一次就乘一次,最后肯定是大区间的少,小区间的多了。qwq因为这个题的次数可能很高,会爆long long,实在是不想写高精度,就用了__int128,第一次用,感觉还不错QAQ..

        代码实现

        #include<cstdio>
         #include<cstring>
        @@ -164,5 +164,5 @@
         
        + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/posts/30/index.html b/posts/30/index.html index cb2655b0..b5cec28f 100644 --- a/posts/30/index.html +++ b/posts/30/index.html @@ -5,7 +5,7 @@ 题意 两个兔子分别位于 $(x,0)$ 和 $(y,0)$ ,两个人对头蹦,前者往前蹦 $a$ ,后者往前蹦 $b$ ,问两人是否能恰好相遇。">

        Codeforces#620 (Div.2)

        A. Two Rabbits

        题意

        两个兔子分别位于 $(x,0)$ 和 $(y,0)$ ,两个人对头蹦,前者往前蹦 $a$ ,后者往前蹦 $b$ ,问两人是否能恰好相遇。

        思路

        算一下两个人直接得距离 $s$ ,每次两者距离减少 $a+b$ ,看 $s$ 是否能被 $a+b$ 整除,如果可以就能够相遇。

        代码实现

        #include<cstdio>
        +两个兔子分别位于 $(x,0)$ 和 $(y,0)$  ,两个人对头蹦,前者往前蹦 $a$ ,后者往前蹦 $b$ ,问两人是否能恰好相遇。">

        Codeforces#620 (Div.2)

        A. Two Rabbits

        题意

        两个兔子分别位于 $(x,0)$ 和 $(y,0)$ ,两个人对头蹦,前者往前蹦 $a$ ,后者往前蹦 $b$ ,问两人是否能恰好相遇。

        思路

        算一下两个人直接得距离 $s$ ,每次两者距离减少 $a+b$ ,看 $s$ 是否能被 $a+b$ 整除,如果可以就能够相遇。

        代码实现

        #include<cstdio>
         #include<cstring>
         #include<algorithm>
         #include<cmath>
        @@ -150,5 +150,5 @@
         
        + PaperMod | 鲁ICP备2020034310号
        \ No newline at end of file diff --git a/posts/31/index.html b/posts/31/index.html index 4bd1a432..f7a6276f 100644 --- a/posts/31/index.html +++ b/posts/31/index.html @@ -2,7 +2,7 @@

        树形dp例题

        前言

        学OI的时候就做过树形dp的题,不过那时候全在划水。看了看题解还不太懂就直接照着题解写了,现在再回来看还是不会QAQ,所以就再看看然后自己写了一遍。


        A. 没有上司的舞会

        题意

        有 $N$ 个职员被邀请去参加公司的舞会,他们每个人对应着一个快乐指数 $h_i$ ,如果该职员来了就会为舞会增加$h_i$ 点快乐指数。这 $N$ 个职员之间有从属关系,也就是说他们的关系就像一棵以顶级上司为根的树,父结点就是子结点的直接上司。如果一个职员的直接上司来到了舞会,那么他本人就不会再来。问邀请哪些职员可获得最大的快乐指数,最大为多少。

        思路

        职员之间的关系是以树的形式给出的,所以先用链式前向星来存储数。存的时候我们用vis数组记录一下如何那个人有上司,就将他标记一下,最终没有标记的就是没有上司的,也就是顶级上司,也就是我们的根节点root。 +学OI的时候就做过树形dp的题,不过那时候全在划水。看了看题解还不太懂就直接照着题解写了,现在再回来看还是不会QAQ,所以就再看看然后自己写了一遍。">

        树形dp例题

        前言

        学OI的时候就做过树形dp的题,不过那时候全在划水。看了看题解还不太懂就直接照着题解写了,现在再回来看还是不会QAQ,所以就再看看然后自己写了一遍。


        A. 没有上司的舞会

        题意

        有 $N$ 个职员被邀请去参加公司的舞会,他们每个人对应着一个快乐指数 $h_i$ ,如果该职员来了就会为舞会增加$h_i$ 点快乐指数。这 $N$ 个职员之间有从属关系,也就是说他们的关系就像一棵以顶级上司为根的树,父结点就是子结点的直接上司。如果一个职员的直接上司来到了舞会,那么他本人就不会再来。问邀请哪些职员可获得最大的快乐指数,最大为多少。

        思路

        职员之间的关系是以树的形式给出的,所以先用链式前向星来存储数。存的时候我们用vis数组记录一下如何那个人有上司,就将他标记一下,最终没有标记的就是没有上司的,也就是顶级上司,也就是我们的根节点root。 树形dp,顾名思义,在树上进行dp,通过递归dfs,先算出子树的状态,再通过递归的回溯来合并。那么我们考虑一下设计状态,很明显一个人的状态有来和不来,两个情况。所以我们设计状态 $dp[i][0/1]$ 来表示职员 i 来或者不来,我们用u来表示当前节点,用v来表示当前节点的子节点,那么状态转移如下:

        • $dp[u][0]=max(dp[v][0],dp[v][1]) $ (上司u没有来,那么下属v可以来,也可以不来,选一个大的策略)

        • $dp[u][1]=dp[v][0]+h[u]$ (上司u来了,下属v肯定不来)

        最终的答案就是 $max(dp[root][0],dp[root][1])$ ,上司来和不来两种策略中的最大一种。

        代码实现

        #include<cstdio>
         #include<cstring>
         #include<algorithm>
        @@ -167,5 +167,5 @@
         
        + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/posts/33/index.html b/posts/33/index.html index b070f2b0..7d5d7e16 100644 --- a/posts/33/index.html +++ b/posts/33/index.html @@ -59,7 +59,7 @@ 可用于变量的显示和操作,可显示你当前创建的变量。并且可对其保存,修改,删除。 -">

        专题一:MATLAB基础知识

        1.1 MATLAB系统环境

        MATLAB操作界面的组成

        1. MATLAB主窗口
        2. 命令行窗口
          • 命令行窗口含有 >> 命令提示符,表示MATLAB处于准备状态,可以接受并执行命令,按下回车键后MATLAB会执行输入命令,并在后面显示执行结果
          • 如果指令过长可以分行输入,在一行末尾写 ... 并按下回车键,在下个命令行继续输入,...称为续行符。
        3. 当前文件夹窗口
          • 在MATLAB编程过程中生成的文件自动存放在当前文件夹,我们可以通过cd命令(例如我们要进入E盘下的work文件夹,可以cd e:\work)或者选择文件工具栏中的文件夹来设置当前文件夹。
        4. 工作区窗口
          • 可用于变量的显示和操作,可显示你当前创建的变量。并且可对其保存,修改,删除。

        MATLAB的搜索路径

        • 检索命令对象的顺序如下

        search.png

        • 设置文件搜索路径
          • 用path命令设置文件搜索路径。例如: path{path,`e:\work`}
          • 用对话框设置文件搜索路径。在MATLAB主窗口的主页中设置。

        1.2 MATLAB数值数据

        数值数据类型的分类

        • 整型

          • 无符号整数:含有8,16,32,64四种
          • 带符号整数:含有8,16,32,64四种

          范围和C语言一样,通过类型(数据) 来进行强转。

        • 浮点型

          • 单精度:占四字节
          • 双精度:占八字节,数值数据默认为双精度

          通过single和double函数进行强转。

        • 复型

          • 复型数据包括实部和虚部两部分,都默认为浮点型,虚数单位用ij来表示。

          • 通过read和imag函数来求复型数据的实部和虚部。

        • 字符型

          • 字符在内部作为数字存储,而不会采用浮点格式存储。

        数值数据的输出格式

        • format命令的格式,使用方法 format 格式符,不带格式符的format会恢复默认格式。ps:format只影响数据的输出,不影响数据的存储和计算。

        常用数学函数

        1. 函数的调用格式为函数名(函数自变量的值)

          • 函数自变量规定为矩阵变量,也可以为标量(为矩阵的特例)。
          • 函数在运算时将函数逐项作用在每个元素上,最后运算出来是一个与自变量同类型矩阵。
        2. 常用函数的应用

          • 三角函数有两类,例如sin和sind两种,前面是弧度制,后面是角度制,其余cos等类似。
          • abs函数可以求实数的绝对值、复数的模、字符串的ASCII码值。
          • 用于取整的函数有fix,floor,ceil,round。分别为靠0取整,向下取整,向上取整,四舍五入取整。
          • 判断是否为素数的函数isprime,是素数返回1,不是返回0。
          >> x=[1:100];
          +">

          专题一:MATLAB基础知识

          1.1 MATLAB系统环境

          MATLAB操作界面的组成

          1. MATLAB主窗口
          2. 命令行窗口
            • 命令行窗口含有 >> 命令提示符,表示MATLAB处于准备状态,可以接受并执行命令,按下回车键后MATLAB会执行输入命令,并在后面显示执行结果
            • 如果指令过长可以分行输入,在一行末尾写 ... 并按下回车键,在下个命令行继续输入,...称为续行符。
          3. 当前文件夹窗口
            • 在MATLAB编程过程中生成的文件自动存放在当前文件夹,我们可以通过cd命令(例如我们要进入E盘下的work文件夹,可以cd e:\work)或者选择文件工具栏中的文件夹来设置当前文件夹。
          4. 工作区窗口
            • 可用于变量的显示和操作,可显示你当前创建的变量。并且可对其保存,修改,删除。

          MATLAB的搜索路径

          • 检索命令对象的顺序如下

          search.png

          • 设置文件搜索路径
            • 用path命令设置文件搜索路径。例如: path{path,`e:\work`}
            • 用对话框设置文件搜索路径。在MATLAB主窗口的主页中设置。

          1.2 MATLAB数值数据

          数值数据类型的分类

          • 整型

            • 无符号整数:含有8,16,32,64四种
            • 带符号整数:含有8,16,32,64四种

            范围和C语言一样,通过类型(数据) 来进行强转。

          • 浮点型

            • 单精度:占四字节
            • 双精度:占八字节,数值数据默认为双精度

            通过single和double函数进行强转。

          • 复型

            • 复型数据包括实部和虚部两部分,都默认为浮点型,虚数单位用ij来表示。

            • 通过read和imag函数来求复型数据的实部和虚部。

          • 字符型

            • 字符在内部作为数字存储,而不会采用浮点格式存储。

          数值数据的输出格式

          • format命令的格式,使用方法 format 格式符,不带格式符的format会恢复默认格式。ps:format只影响数据的输出,不影响数据的存储和计算。

          常用数学函数

          1. 函数的调用格式为函数名(函数自变量的值)

            • 函数自变量规定为矩阵变量,也可以为标量(为矩阵的特例)。
            • 函数在运算时将函数逐项作用在每个元素上,最后运算出来是一个与自变量同类型矩阵。
          2. 常用函数的应用

            • 三角函数有两类,例如sin和sind两种,前面是弧度制,后面是角度制,其余cos等类似。
            • abs函数可以求实数的绝对值、复数的模、字符串的ASCII码值。
            • 用于取整的函数有fix,floor,ceil,round。分别为靠0取整,向下取整,向上取整,四舍五入取整。
            • 判断是否为素数的函数isprime,是素数返回1,不是返回0。
            >> x=[1:100];
             >> k=isprime(x);
             >> k1=find(k);
             >> p=x(k1)
            @@ -153,5 +153,5 @@
             
          + PaperMod | 鲁ICP备2020034310号
          \ No newline at end of file diff --git a/posts/34/index.html b/posts/34/index.html index 8fcdf209..ff4157b9 100644 --- a/posts/34/index.html +++ b/posts/34/index.html @@ -71,7 +71,7 @@ 通过 $\mu+\sigma x$ 来得到均值为 $\mu$ ,方差为 $\sigma{^2}$ 的随机数据。(高中数学知识,证明可百度) -">

          专题二:MATLAB矩阵处理

          2.1 特殊矩阵

          通用的特殊矩阵

          • zeros函数: 产生全0矩阵,即零矩阵。

          • ones函数: 产生全1函数,即幺矩阵。

          • eye函数: 产生对角线为1的矩阵,当矩阵为方针时,为单位矩阵。

          • rand函数: 产生 (0,1) 区间均匀分布的随机矩阵。

          • 通过 fix(a+(b-a+1)*rand(x)) 可产生[a,b]区间上均匀分布的随机整数。

          • randn函数: n为normal的意思,产生均值为0,方差为1的标准正态分布随机矩阵。

            • 通过 $\mu+\sigma x$ 来得到均值为 $\mu$ ,方差为 $\sigma{^2}$ 的随机数据。(高中数学知识,证明可百度)
          • 对于上述函数的调用格式,我们都有如下规定,zeros(m)为产生 $m\times m$ 的零矩阵,zeros(m,n)为产生类型为 $m\times n$ 的零矩阵, zeros(size(A)) 为产生和 A 同类型的零矩阵,其余函数和此类似。

          用于专门学科的特殊矩阵

          1. 魔方/幻方矩阵 (Magic Square)

            • n阶幻方矩阵每行,每列,主副对角线的和相等。
            • n阶幻方矩阵每行每列的元素之和为 $(1+2+3+\cdots+n^2)/n=(n+n^3)/2$
          2. 范德蒙矩阵 (Vandermonde)

            • 利用 Vander(V) 生成以向量 V 为基础的**范德蒙(Vandermonde)**矩阵。

            Vander.png

            A=vander(1:5)
            +">

            专题二:MATLAB矩阵处理

            2.1 特殊矩阵

            通用的特殊矩阵

            • zeros函数: 产生全0矩阵,即零矩阵。

            • ones函数: 产生全1函数,即幺矩阵。

            • eye函数: 产生对角线为1的矩阵,当矩阵为方针时,为单位矩阵。

            • rand函数: 产生 (0,1) 区间均匀分布的随机矩阵。

            • 通过 fix(a+(b-a+1)*rand(x)) 可产生[a,b]区间上均匀分布的随机整数。

            • randn函数: n为normal的意思,产生均值为0,方差为1的标准正态分布随机矩阵。

              • 通过 $\mu+\sigma x$ 来得到均值为 $\mu$ ,方差为 $\sigma{^2}$ 的随机数据。(高中数学知识,证明可百度)
            • 对于上述函数的调用格式,我们都有如下规定,zeros(m)为产生 $m\times m$ 的零矩阵,zeros(m,n)为产生类型为 $m\times n$ 的零矩阵, zeros(size(A)) 为产生和 A 同类型的零矩阵,其余函数和此类似。

            用于专门学科的特殊矩阵

            1. 魔方/幻方矩阵 (Magic Square)

              • n阶幻方矩阵每行,每列,主副对角线的和相等。
              • n阶幻方矩阵每行每列的元素之和为 $(1+2+3+\cdots+n^2)/n=(n+n^3)/2$
            2. 范德蒙矩阵 (Vandermonde)

              • 利用 Vander(V) 生成以向量 V 为基础的**范德蒙(Vandermonde)**矩阵。

              Vander.png

              A=vander(1:5)
               A =
               
                    1     1     1     1     1
              @@ -89,5 +89,5 @@
               
            + PaperMod | 鲁ICP备2020034310号
            \ No newline at end of file diff --git a/posts/36/index.html b/posts/36/index.html index 37173af8..dcee5bd7 100644 --- a/posts/36/index.html +++ b/posts/36/index.html @@ -8,7 +8,7 @@ ">

            专题三:MATLAB程序流程控制

            3.1 顺序结构程序

            程序设计的基本步骤

            step.png

            程序

            • 在matlab中程序文件扩展名为**.m** ,因此程序文件又叫 M文件
            • 程序文件分两种
              • 脚本文件:是可以在命令行窗口直接执行的文件,也叫命令文件。
              • 函数文件:定义一个函数,以函数调用方式来调用,不能单独执行。

            文件的建立

            • 可以在主页点击新建脚本,即可创建脚本文件,并且打开MATLAB编辑器。
            • 在命令行窗口写 edit test 即可在当前文件下创建 test 脚本文件。
            %利用脚本文件求两矩阵乘积
            +">

            专题三:MATLAB程序流程控制

            3.1 顺序结构程序

            程序设计的基本步骤

            step.png

            程序

            • 在matlab中程序文件扩展名为**.m** ,因此程序文件又叫 M文件
            • 程序文件分两种
              • 脚本文件:是可以在命令行窗口直接执行的文件,也叫命令文件。
              • 函数文件:定义一个函数,以函数调用方式来调用,不能单独执行。

            文件的建立

            • 可以在主页点击新建脚本,即可创建脚本文件,并且打开MATLAB编辑器。
            • 在命令行窗口写 edit test 即可在当前文件下创建 test 脚本文件。
            %利用脚本文件求两矩阵乘积
             %脚本文件f1.m
             A=[1:3;4:6];
             B=[1,2;3,4;5,6];
            @@ -151,5 +151,5 @@
             
            + PaperMod | 鲁ICP备2020034310号
            \ No newline at end of file diff --git a/posts/5/index.html b/posts/5/index.html index 320a350b..15232994 100644 --- a/posts/5/index.html +++ b/posts/5/index.html @@ -8,7 +8,7 @@ 给定一个区间$[L,R]$ ,求从这个区间任意取两个整数(可以相同),两者异或后能得到的最大值是多少?">

            排位一和二记录

            Day 1

            A. 兔子的区间密码

            题意

            给定一个区间$[L,R]$ ,求从这个区间任意取两个整数(可以相同),两者异或后能得到的最大值是多少?

            思路

            首先我们想一下特例,当 $L==R$ 的时候,那么只能是L和他自己异或,就是0了。

            然后可以分两部分来想,设区间端点 $L,R$ 的二进制最高位,从右往左开始数位置分别为 $p_1,p_2$

            • 如果 $p_1 \neq p_2 $ ,那么必然是 $p_1 < p_2$ ,我们很容易发现这时候肯定可以取到 $2^{p_2-1}-1 和 2^{p_2-1}$ ,那么两者异或一下就是最大的,答案为 $2^{p_2}$
            • 如果 $p_1 == p_2$ ,那么我们可以转化为更小规模的问题,就是区间为 $[L-2^{p_1-1},R-2^{p_1-1}]$ 。

            代码实现

            #include<cstdio>
            +给定一个区间$[L,R]$ ,求从这个区间任意取两个整数(可以相同),两者异或后能得到的最大值是多少?">

            排位一和二记录

            Day 1

            A. 兔子的区间密码

            题意

            给定一个区间$[L,R]$ ,求从这个区间任意取两个整数(可以相同),两者异或后能得到的最大值是多少?

            思路

            首先我们想一下特例,当 $L==R$ 的时候,那么只能是L和他自己异或,就是0了。

            然后可以分两部分来想,设区间端点 $L,R$ 的二进制最高位,从右往左开始数位置分别为 $p_1,p_2$

            • 如果 $p_1 \neq p_2 $ ,那么必然是 $p_1 < p_2$ ,我们很容易发现这时候肯定可以取到 $2^{p_2-1}-1 和 2^{p_2-1}$ ,那么两者异或一下就是最大的,答案为 $2^{p_2}$
            • 如果 $p_1 == p_2$ ,那么我们可以转化为更小规模的问题,就是区间为 $[L-2^{p_1-1},R-2^{p_1-1}]$ 。

            代码实现

            #include<cstdio>
             #include<cstring>
             #include<algorithm>
             #include<cmath>
            @@ -251,5 +251,5 @@
             
            + PaperMod | 鲁ICP备2020034310号
            \ No newline at end of file diff --git a/posts/51/index.html b/posts/51/index.html index d5273629..8b51bb27 100644 --- a/posts/51/index.html +++ b/posts/51/index.html @@ -29,7 +29,7 @@ 当x为复向量时,则以实部和虚部分别为横纵坐标绘制曲线。 -">

            专题四:MATLAB绘图

            4.1 二维曲线

            plot函数

            • 基本用法plot(x,y) ,x和y分别代表横纵坐标,plot函数会将各个点连接起来,形成线,x和y一般为长度相等的向量。
            • 最简单的调用格式plot(x)
              • 当x为实向量时,则以该元素下表为横坐标,元素的值为纵坐标绘制曲线。
              • 当x为复向量时,则以实部虚部分别为横纵坐标绘制曲线。
            • plot(x,y)函数参数的变化形式
              • 当x为向量,y为矩阵:这时x的长度和y的列数(或行数)必须相等。这时候绘制多条曲线,分别是x为横坐标,取与x长度相等的那一个参数作为纵坐标,另一个参数为曲线的条数。如果y的行、列两个参数相等,那么用y的每一列作为纵坐标,曲线条数等于矩阵列数。
              • 当x和y为同型矩阵:这时以x,y对应列元素为横、纵坐标绘制曲线,曲线条数等于矩阵列数。
              • 含多个输入参数:形如 plot(x1,y1,x2,y2,···,xn,yn) ,那么就是以每一个向量对组成一个点,绘制曲线。
            • 含选项的plot函数,plot(x,y,选项)
              • 线型 :通过"-",":","-.","--" 等参数来实现实线,虚线,点画线,双画线。
              • 颜色 :通过 "r","g" 等实现曲线颜色的切换。当颜色选项省略,绘图自动循环使用。
              • 数据点标记 :通过 "*","o","s" 等来实现将数据点用星号,圆圈,方块标记。

            fplot函数

            可根据参数函数的变化特性自适应地设置采样间隔,当函数值变化缓慢,采样间隔大,当变化快的时候,采样间隔小。

            • 基本用法fplot(f,lims,选项) ,参数分别函数(一般采用函数句柄表示),lims为x轴的取值范围,采用二元向量 [xmin,xmax] 来表示,默认值为 [-5,5] 。选项参数与plot函数相同。

            • 双输入参数函数的用法fplot(funx,funy,tlims,选项) ,前两个分别为x,y的参数表示,通常以函数句柄的形式给出。tlims为前方函数参数 t 的取值范围,用二元向量 [tmin,tmax] 表示,默认的值为 [-5,5] ,选项参数与上述相同。

            例程

            • 利用不同的线型和颜色在同一坐标内绘制曲线 $y=2e^{-0.5x}sin(2\pi x)$ 以及其包络线。(包络线:在几何学,某个曲线族的包络线Envelope),是跟该曲线族的每条线都有至少一点相切的一条曲线。)
            x=(0:pi/50:2*pi)';
            +">

            专题四:MATLAB绘图

            4.1 二维曲线

            plot函数

            • 基本用法plot(x,y) ,x和y分别代表横纵坐标,plot函数会将各个点连接起来,形成线,x和y一般为长度相等的向量。
            • 最简单的调用格式plot(x)
              • 当x为实向量时,则以该元素下表为横坐标,元素的值为纵坐标绘制曲线。
              • 当x为复向量时,则以实部虚部分别为横纵坐标绘制曲线。
            • plot(x,y)函数参数的变化形式
              • 当x为向量,y为矩阵:这时x的长度和y的列数(或行数)必须相等。这时候绘制多条曲线,分别是x为横坐标,取与x长度相等的那一个参数作为纵坐标,另一个参数为曲线的条数。如果y的行、列两个参数相等,那么用y的每一列作为纵坐标,曲线条数等于矩阵列数。
              • 当x和y为同型矩阵:这时以x,y对应列元素为横、纵坐标绘制曲线,曲线条数等于矩阵列数。
              • 含多个输入参数:形如 plot(x1,y1,x2,y2,···,xn,yn) ,那么就是以每一个向量对组成一个点,绘制曲线。
            • 含选项的plot函数,plot(x,y,选项)
              • 线型 :通过"-",":","-.","--" 等参数来实现实线,虚线,点画线,双画线。
              • 颜色 :通过 "r","g" 等实现曲线颜色的切换。当颜色选项省略,绘图自动循环使用。
              • 数据点标记 :通过 "*","o","s" 等来实现将数据点用星号,圆圈,方块标记。

            fplot函数

            可根据参数函数的变化特性自适应地设置采样间隔,当函数值变化缓慢,采样间隔大,当变化快的时候,采样间隔小。

            • 基本用法fplot(f,lims,选项) ,参数分别函数(一般采用函数句柄表示),lims为x轴的取值范围,采用二元向量 [xmin,xmax] 来表示,默认值为 [-5,5] 。选项参数与plot函数相同。

            • 双输入参数函数的用法fplot(funx,funy,tlims,选项) ,前两个分别为x,y的参数表示,通常以函数句柄的形式给出。tlims为前方函数参数 t 的取值范围,用二元向量 [tmin,tmax] 表示,默认的值为 [-5,5] ,选项参数与上述相同。

            例程

            • 利用不同的线型和颜色在同一坐标内绘制曲线 $y=2e^{-0.5x}sin(2\pi x)$ 以及其包络线。(包络线:在几何学,某个曲线族的包络线Envelope),是跟该曲线族的每条线都有至少一点相切的一条曲线。)
            x=(0:pi/50:2*pi)';
             y1=2*exp(-0.5*x)*[1,-1]; %这里绘制的是上下两条包络线,是有两行的矩阵。
             y2=2*exp(-0.5*x).*sin(2*pi*x); %这里绘制的是曲线本身
             x1=0:0.5:6;
            @@ -90,5 +90,5 @@
             
            + PaperMod | 鲁ICP备2020034310号
            \ No newline at end of file diff --git a/posts/63/index.html b/posts/63/index.html index 8d87f041..d29ce155 100644 --- a/posts/63/index.html +++ b/posts/63/index.html @@ -44,10 +44,10 @@ -">

            Linux和Vim入门

            Linux系统常见命令

            基本操作

            • **cd (Change Directory)**命令:跳转目录

              • cd path : path为路径,进入相应目录
              • cd #cd ~ :回到主目录
              • cd - : 回到上次所在目录
              • cd !$ :将上个命令的参数做为输入
              • cd .. :回到上层目录

              image-20200330164354765.png

            • ls (List) 命令:列出当前目录文件

              • ls : 显示当前目录文件

              • ls -a:显示全部的文件及文件夹,包括隐藏的文件和文件夹。

              • ls -l : 显示较全的文件信息,包括权限,用户,用户组。

              image-20200330164408910.png

              • Tab 键:通过按Tab可以进行自动补全。如果当前目录有前缀相同的文件,则按两下Tab可以显示出所有以具有该前缀的文件。

              • mv (Move) 命令:移动(剪切)文件,也可以用作一个等效给文件或目录的重命名。

                通过 mv 文件x 目录a 可以将当前目录下的文件x移入目录k。

                image-20200330164434299.png

              • cp (Copy) 命令:拷贝,将一个文件或目录拷贝到另一个文件或目录。

                通过 cp [options] 文件x 目录a 可以将当前目录下的文件x复制到目录a。

                • -a:此选项通常在复制目录时使用,它保留链接、文件属性,并复制目录下的所有内容。其作用等于dpR参数组合。
              • -d:复制时保留链接。这里所说的链接相当于Windows系统中的快捷方式。

                • -f:覆盖已经存在的目标文件而不给出提示。
              • -i:与-f选项相反,在覆盖目标文件之前给出提示,要求用户确认是否覆盖,回答"y"时目标文件将被覆盖。

                • -p:除复制文件的内容外,还把修改时间和访问权限也复制到新文件中。
              • -r:若给出的源文件是一个目录文件,此时将复制该目录下所有的子目录和文件。

                • -l:不复制文件,只是生成链接文件。
              • pwd(Print Working Directory) 命令:打印出当前工作目录

              • mkdir 命令 : mkdir name创建一个名为name的文件夹

              • rm (Remove) 命令 :删除文件,删除文件后不可恢复。特殊的 ,**rmdir ** 为删除文件夹命令,rm -r是先删除目录内的内容,再删除目录。 rm -i 为交互式进行删除,一个个确定。rm -f 为强制删除(慎用)。

              • gedit 命令:gedit path 打开编辑某个文件。path为绝对路径或相对路径。

              • touch 命令:touch name 创建一个文件,name包含拓展名。

              • cat 命令:打开指定文件, 并显示其中内容在终端,并且可以将其复制到一个另文件中。如果cat后面加多个文件名,那么就会打开多个文件。

              • tar 命令:压缩或解压命令。tar [参数] 打包文件名 要打包的各个文件

                参数表:

                参数含义
                -c生成档案文件,创建打包文件
                -v列出归档解档的详细过程,显示进度
                -f指定档案文件名称,f后面一定是.tar文件,所以放选项最后
                -t列出档案中包含的文件
                -x解开档案文件

                打包实例: tar -cvf 文件名 要打包的文件 解压实例:tar -xvf 压缩包名

            image-20200330164654339.png

            不同的查找方式

            • find :使用方法为find <指定目录><指定条件><指定动作> ,如何find后面不加任何参数,那么就默认搜索当前目录及其子目录,并显示在屏幕上。

              • <指定目录>:用于指定要搜索的目录,默认为当前所在目录。

              • <指定条件>:指定所要搜索文件的特征。

                • -name :按文件名查找
                • -perm:按文件权限查找
                • -depth:查找时先在当前目录查找,然后查找其他子目录。
                • -prune:不在当前指定路径查找。如果同时指定-depth,则此选项被忽略。
                • -user/-nouser:按照文件属主查找/查找无效属主文件
                • -group/-nogroup:按照文件属组查找/查找无效属组文件
                • -newer file1 !file2:查找更改时间比file1新比file2旧的文件。
                • -type:查找某一类型文件,b:块设备文件,d:目录,c:字符设备文件,P:管道文件,l:符号链接文件,f:普通文件。

                image-20200330164709797.png

                image-20200330164721033.png

            • locate :等价于 find -name ,但是速度要快,因为locate在一个本地数据库中存放了所有本地文件信息,每天自动更新,我们查找之前需要通过 updatedb 手动更新其中内容,不然可能会导致新改动的文件查找不到。

              image-20200330164733755.png

            • whereis :whereis可以用于程序名的搜索,可以通过参数 -s,-m,-s 分别搜索二进制文件,man说明文件,和源代码文件。如果省略参数,则返回所有信息。不过这个也是从本地数据库里面进行搜索。

            • which :只能用于寻找可执行文件,并通过path变量寻找。

              关于查找方式的总结,find命令非常强大,搜索全盘,而且可以配合多种参数进行各种各样的搜索。 +">

              Linux和Vim入门

              Linux系统常见命令

              基本操作

              • **cd (Change Directory)**命令:跳转目录

                • cd path : path为路径,进入相应目录
                • cd #cd ~ :回到主目录
                • cd - : 回到上次所在目录
                • cd !$ :将上个命令的参数做为输入
                • cd .. :回到上层目录

                image-20200330164354765.png

              • ls (List) 命令:列出当前目录文件

                • ls : 显示当前目录文件

                • ls -a:显示全部的文件及文件夹,包括隐藏的文件和文件夹。

                • ls -l : 显示较全的文件信息,包括权限,用户,用户组。

                image-20200330164408910.png

                • Tab 键:通过按Tab可以进行自动补全。如果当前目录有前缀相同的文件,则按两下Tab可以显示出所有以具有该前缀的文件。

                • mv (Move) 命令:移动(剪切)文件,也可以用作一个等效给文件或目录的重命名。

                  通过 mv 文件x 目录a 可以将当前目录下的文件x移入目录k。

                  image-20200330164434299.png

                • cp (Copy) 命令:拷贝,将一个文件或目录拷贝到另一个文件或目录。

                  通过 cp [options] 文件x 目录a 可以将当前目录下的文件x复制到目录a。

                  • -a:此选项通常在复制目录时使用,它保留链接、文件属性,并复制目录下的所有内容。其作用等于dpR参数组合。
                • -d:复制时保留链接。这里所说的链接相当于Windows系统中的快捷方式。

                  • -f:覆盖已经存在的目标文件而不给出提示。
                • -i:与-f选项相反,在覆盖目标文件之前给出提示,要求用户确认是否覆盖,回答"y"时目标文件将被覆盖。

                  • -p:除复制文件的内容外,还把修改时间和访问权限也复制到新文件中。
                • -r:若给出的源文件是一个目录文件,此时将复制该目录下所有的子目录和文件。

                  • -l:不复制文件,只是生成链接文件。
                • pwd(Print Working Directory) 命令:打印出当前工作目录

                • mkdir 命令 : mkdir name创建一个名为name的文件夹

                • rm (Remove) 命令 :删除文件,删除文件后不可恢复。特殊的 ,**rmdir ** 为删除文件夹命令,rm -r是先删除目录内的内容,再删除目录。 rm -i 为交互式进行删除,一个个确定。rm -f 为强制删除(慎用)。

                • gedit 命令:gedit path 打开编辑某个文件。path为绝对路径或相对路径。

                • touch 命令:touch name 创建一个文件,name包含拓展名。

                • cat 命令:打开指定文件, 并显示其中内容在终端,并且可以将其复制到一个另文件中。如果cat后面加多个文件名,那么就会打开多个文件。

                • tar 命令:压缩或解压命令。tar [参数] 打包文件名 要打包的各个文件

                  参数表:

                  参数含义
                  -c生成档案文件,创建打包文件
                  -v列出归档解档的详细过程,显示进度
                  -f指定档案文件名称,f后面一定是.tar文件,所以放选项最后
                  -t列出档案中包含的文件
                  -x解开档案文件

                  打包实例: tar -cvf 文件名 要打包的文件 解压实例:tar -xvf 压缩包名

              image-20200330164654339.png

              不同的查找方式

              • find :使用方法为find <指定目录><指定条件><指定动作> ,如何find后面不加任何参数,那么就默认搜索当前目录及其子目录,并显示在屏幕上。

                • <指定目录>:用于指定要搜索的目录,默认为当前所在目录。

                • <指定条件>:指定所要搜索文件的特征。

                  • -name :按文件名查找
                  • -perm:按文件权限查找
                  • -depth:查找时先在当前目录查找,然后查找其他子目录。
                  • -prune:不在当前指定路径查找。如果同时指定-depth,则此选项被忽略。
                  • -user/-nouser:按照文件属主查找/查找无效属主文件
                  • -group/-nogroup:按照文件属组查找/查找无效属组文件
                  • -newer file1 !file2:查找更改时间比file1新比file2旧的文件。
                  • -type:查找某一类型文件,b:块设备文件,d:目录,c:字符设备文件,P:管道文件,l:符号链接文件,f:普通文件。

                  image-20200330164709797.png

                  image-20200330164721033.png

              • locate :等价于 find -name ,但是速度要快,因为locate在一个本地数据库中存放了所有本地文件信息,每天自动更新,我们查找之前需要通过 updatedb 手动更新其中内容,不然可能会导致新改动的文件查找不到。

                image-20200330164733755.png

              • whereis :whereis可以用于程序名的搜索,可以通过参数 -s,-m,-s 分别搜索二进制文件,man说明文件,和源代码文件。如果省略参数,则返回所有信息。不过这个也是从本地数据库里面进行搜索。

              • which :只能用于寻找可执行文件,并通过path变量寻找。

                关于查找方式的总结,find命令非常强大,搜索全盘,而且可以配合多种参数进行各种各样的搜索。 而locate能做到搜索的更快,因为一种特殊的搜索位置,但是功能要略逊于find。whereis和which都是对于指定类型的搜索,专精某一方面。

              软链接和硬链接

              首先我了解到,linux文件系统中,每一个文件都会有一个编号,称为索引节点号inode。也就是i节点。

              链接呢,我的感觉就是,建立一个源文件和链接文件的映射,两个之间会有一定的关系存在。

              创建链接的方式为 ln 源文件 目标文件 ,默认为硬链接,软链接为 ln -s 源文件 目标文件

              对于软链接,很像快捷方式,可以跨文件系统(也就是说可以存在于不同的文件系统中),而且他有一个单独的inode,然后通过软连接可以打开源文件。

              对于硬链接,就像是整了一个毛一样的东西出来,很像备份吧,而且两者名字可不同,他们的inode是同一个,只是把inode link count 域增加了1,也就是多了加了一个索引项,因为他们是一毛一样的东西,那么就肯定不能跨文件系统了,因为你这个东西在这个文件系统里面是代表这个东西,在另一个里面就不一定是了,会产生错误。

              关于他们的几点其他区别如下

              • 软链接可以对一个不存在的文件名进行链接,如果用编辑器打开这个目标文件,那么会默认创建一个名为filename的文件,而硬链接肯定不行了,因为你文件不存在,他也就没有inode,无从创建链接。

              • 软链接可以跨文件系统,硬链接不行。

              • 软链接可以链接目录,硬链接不行。百度了解到,因为硬链接和源文件用的一个inode,用硬链接链接可以会形成循环依赖,导致系统死机。

              • 硬链接在源文件删除后依然可以访问,因为它具有源文件的inode,而软链接在源文件删除后无法对源文件进行访问,因为inode没有了,索引不到了。

              • 我们对硬链接文件中的内容进行修改也会影响到源文件,因为他们是同一个文件。当然软链接也可以,因为他就是相当于打开了源文件。

              • 其他常见操作

                • 新建一个用户:通过sudo useradd -m name 会创建一个名为name的用户,看/home文件下会显示名为name的用户,可以通过 sudo passwd name 来为用户设置密码,通过su name来切换用户,如果想要删除则通过sudo userdel [-r] name 来删除,加上-r代表删除对应文件夹。我们可以通过命令来查看etc中的passwd文件,就能够看到是否创建成功。

                  image-20200330164751936.png

                  image-20200330164808040.png

                • 权限的修改:我们可以通过sudo gedit /etc/sudoers 打开sudoers文件修改 # User privilege specification 下的目录,添加<用户名> ALL=(ALL:ALL) ALL 来为用户添加sudo权限。

                • 连接网络

                  • 无线网
                    • nmcli dev wifi 查看可连接的无线网络
                    • nmcli dev wifi connect name password password name为对应的wifi名称,而后面的password则是对应的密码。
                  • 有线网拨号上网
                    • sudo ifconfig eth0 down/up 为关闭或者开启网卡驱动。
                    • sudo pppoeconf 建立拨号连接,对于有线网卡输入 sudo pppoeconf eth0 然后输入拨号的用户名以及密码即可连接到网络。
                • sudo和su一些区别

                  • su(substitute user):切换用户。
                  • sudo:sudo是通过另一个用户来执行命令,也就是说一个命令需要root权限,你并不需要直接跑到root用户下执行,只需要通过sudo然后输入root的密码即可执行相应的命令。
                • apt-get

                  • apt-get,是一条linux命令,适用于deb包管理式的操作系统,主要用于自动从互联网的软件仓库中搜索、安装、升级、卸载软件或操作系统。通常搭配sudo命令使用。

              Vim的常用操作

              • 首先通过 sudo apt-get install vim 来安装Vim

              image-20200330164821953.png

              • 通过 vim name 来编辑name这个文件,如果不存在那么就会创建一个。

              • Vim的使用

                Vim分为了三种模式,分别是命令模式(Command mode)输入模式(Insert mode)底线命令模式(Last line mode)

                • 命令模式

                  我们刚进入vim就是进入了命令模式,可以通过输入 i或a或o 来切换到输入模式,也可以通过输入x来删除当前光标后的字符,还有一系列操作可以进行,也可以输入 : 来进入底线命令模式。

                  一些常用命令

                  • /word?word :向光标之下 / 光标之上搜索word这个字符串。
                  • n / N :继续上一个搜索操作 / 进行与上一个搜索操作相反的搜索
                  • ZZ :按两下大写的Z,那么就是直接保存后离开。
                • 输入模式

                  输入模式也就是对文本进行编辑,和普通的类似。里面好像有挺多快捷键的,可以通过Page Up/Page Down 来上下翻页,可以通过 HOME/END 来将光标移到行首/行尾。通过 Insert 可以将光标切换为输入/替换模式,光标相应的变为竖线/下划线。通过 Esc 可以退出输入模式,切换到命令模式。

                • 底线命令模式

                  输入 :命令 可以执行非常多的操作,一些常用命令如下。

                  • :set nu / :set nonu : 设置行号,取消行号。
                  • :n1,n2s/word1/word2/g :将n1~n2行中所有的word1替换为word2,g后加c则每次替换前需要用户手动确认,如果加上i则忽略大小写。
                  • :1,$s/word1/word2/g$s/word1/word2/g :将第一行到最后一行中的word1替换为word2,g后加 c 则每次替换前需要用户确认,如果加上 i (ignore) 则忽略大小写。
                  • :w / :w! :分别为保存,强制保存。
                  • :q / :q! :分别为离开vim,强制离开vim,后者是不需要保存的时候可以选择直接退出。
                  • :wq / :wq! : 分别为存储后离开,强制存储后离开,我们发现加个叹号!一般就是强制的意思。
                  • :w [filename] :将文本保存成一个叫filename的文件,类似于另存为。
                  • :r [filename] :将文本文件filename读入写在光标之后。
                  • :n1,n2 w filename :将文本n1~n2行保存在的filename中(新建一个文件保存)。
                  • :! command :暂时离开vim到终端中

              vim.png

              + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/posts/64/index.html b/posts/64/index.html index 2853bd3e..6a2579b2 100644 --- a/posts/64/index.html +++ b/posts/64/index.html @@ -11,7 +11,7 @@ 洛谷大数类的评测结果(开了氧气优化) -这个第四个点真的优化不过去了QAQ,24W的数据,丧心病狂">

              C++大数类的实现

              C++大数类设计思路

              洛谷大数类的评测结果(开了氧气优化)

              BigNumber.png

              这个第四个点真的优化不过去了QAQ,24W的数据,丧心病狂

              整体构思

              构造大数类名为 BigNumber ,首先想法是用字符串读入大数,然后将其转化为vector数组倒序分位存储的整数,然后通过一个 len 来记录数字的位数,便于做运算。还设计了一个标记变量,用于标记这数为正数还是负数。

              构造函数

              我用了两种构造函数,一个是无参构造函数,一个是拷贝构造函数,当然还有一个有参构造函数,但是实际过程中我没有用到。无参构造函数用于上述类成员的初始化,拷贝构造函数用于复制一个相同的大数类进行运算。有参构造函数可以用于对类成员的复制。

              重载运算符

              重载 “+”

              • 首先在类中进行了声明, BigNumber operator + (const BigNumber &b); ,用当前类 *this 来和引入的类 b 进行加法运算,返回值为一个 BigNumber 类。
              • 在类的外部进行重载的定义,先将用拷贝构造函数将当前的类 *this 拷贝为 a ,然后对 ab 进行加法运算,模拟竖式,对应位相加,大于10则进位,最后去掉尾部的 0 即可。
              BigNumber BigNumber::operator + (const BigNumber &b) //重载 "+" 定义 
              +这个第四个点真的优化不过去了QAQ,24W的数据,丧心病狂">

              C++大数类的实现

              C++大数类设计思路

              洛谷大数类的评测结果(开了氧气优化)

              BigNumber.png

              这个第四个点真的优化不过去了QAQ,24W的数据,丧心病狂

              整体构思

              构造大数类名为 BigNumber ,首先想法是用字符串读入大数,然后将其转化为vector数组倒序分位存储的整数,然后通过一个 len 来记录数字的位数,便于做运算。还设计了一个标记变量,用于标记这数为正数还是负数。

              构造函数

              我用了两种构造函数,一个是无参构造函数,一个是拷贝构造函数,当然还有一个有参构造函数,但是实际过程中我没有用到。无参构造函数用于上述类成员的初始化,拷贝构造函数用于复制一个相同的大数类进行运算。有参构造函数可以用于对类成员的复制。

              重载运算符

              重载 “+”

              • 首先在类中进行了声明, BigNumber operator + (const BigNumber &b); ,用当前类 *this 来和引入的类 b 进行加法运算,返回值为一个 BigNumber 类。
              • 在类的外部进行重载的定义,先将用拷贝构造函数将当前的类 *this 拷贝为 a ,然后对 ab 进行加法运算,模拟竖式,对应位相加,大于10则进位,最后去掉尾部的 0 即可。
              BigNumber BigNumber::operator + (const BigNumber &b) //重载 "+" 定义 
               {
                   
               	BigNumber Result;
              @@ -501,5 +501,5 @@
               
              + PaperMod | 鲁ICP备2020034310号
              \ No newline at end of file diff --git a/posts/66/index.html b/posts/66/index.html index d9affee5..f4620094 100644 --- a/posts/66/index.html +++ b/posts/66/index.html @@ -44,7 +44,7 @@ PyPy 它的目标是执行速度。PyPy采用JIT技术,对Python代码进行动态编译(注意不是解释),所以可以显著提高Python代码的执行速度。他与CPython略有不同。 -">

              Python初步学习

              Python学习笔记

              Python的不同解释器

              1. CPython

                这是自带的用C语言开发的解释器,因此叫CPython。它也是使用最广的Python解释器。

              2. IPython

                这是基于CPython之上的一个交互式解释器,只是相比于CPython多了交互上的优化。

              3. PyPy

                它的目标是执行速度。PyPy采用JIT技术,对Python代码进行动态编译(注意不是解释),所以可以显著提高Python代码的执行速度。他与CPython略有不同。

              1. Jython

                这是运行在Java平台上的Python解释器,可以直接把Python代码编译成Java字节码执行。

              2. IronPython

                这是运行在微软.Net平台上的Python解释器,可以直接把Python代码编译成.Net的字节码。

              Python基础

              简单的输入和输出(I/O)

              输入

              python提供了一个 input() 函数供我们输入使用,这读入的是字符串数据,并返回,可以将返回值存放在一个变量中。input函数中可以带字符串,这段字符串在输入前会打印在屏幕上,这使得我们具有很好的交互性,好比我们写:

              name = input("hello,friend! please input your name")
              +">

              Python初步学习

              Python学习笔记

              Python的不同解释器

              1. CPython

                这是自带的用C语言开发的解释器,因此叫CPython。它也是使用最广的Python解释器。

              2. IPython

                这是基于CPython之上的一个交互式解释器,只是相比于CPython多了交互上的优化。

              3. PyPy

                它的目标是执行速度。PyPy采用JIT技术,对Python代码进行动态编译(注意不是解释),所以可以显著提高Python代码的执行速度。他与CPython略有不同。

              1. Jython

                这是运行在Java平台上的Python解释器,可以直接把Python代码编译成Java字节码执行。

              2. IronPython

                这是运行在微软.Net平台上的Python解释器,可以直接把Python代码编译成.Net的字节码。

              Python基础

              简单的输入和输出(I/O)

              输入

              python提供了一个 input() 函数供我们输入使用,这读入的是字符串数据,并返回,可以将返回值存放在一个变量中。input函数中可以带字符串,这段字符串在输入前会打印在屏幕上,这使得我们具有很好的交互性,好比我们写:

              name = input("hello,friend! please input your name")
               print("The input name is ",name)
               

              那么这时候我们运行上述程序,就会提示 hello , friend! please input your name ,这就提示我们应该输入名字。

              这里需要注意的是,input() 函数读入的是一个字符串 str ,就算我们输入了整数他也是一个字符串,如果我们要用真正的整数,那么就需要用 int() 进行类型强制转换。如果其中不是合法的整数,那么会报错。

              输出

              python中的输出函数是 print() ,这和 C++printf 差了一个f。我们在函数的参数中传入什么,他就会打印什么。好比我们写 print("heelo,world") ,那么运行就会打印 hello,world 在屏幕上。print 支持我们传入多个参数,好比 printf("my name is","zs") ,两两之间用逗号隔开,这在输出时会被解析成空格,也就是说两段字符串之间有一个空格。当然此函数也可以打印整数等。

              一些规则

              缩进

              Python中对代码块的区分,不是用C++的大括号,而是用缩进。处于连续同一缩进的是一个代码块,这也是为什么Python又被戏称为游标卡尺语言的原因。当语句以冒号:结尾时,缩进的语句视为代码块。我们通常用一个Tab / 四个空格 的缩进。

              注释

              Python的注释用的是 # ,而 C++ 中的注释用的是 \\

              Case Sensitive

              Python中是大小写敏感的,也就是 a 和 A 不是同一个东西。

              数据类型

              1. 整数

              Python一个很大的好处就是可以处理任意大小的整数,包括负整数。这也是为什么很多大数题大家都喜欢用Python,hhhh。多数地方都用十进制,但是也是支持其他进制的哈~好比 0x 前缀就是16进制。

              2. 浮点数

              浮点数是小数,之所以称为浮点数,是因为小数点位置在科学计数法中是可变的。这里需要注意,整数和浮点数在计算机内部存储方式不同,浮点数应该都是 IEEE754 标准吧?整数之间的运算永远都是精确的,包括除法。而浮点数的运算则会有一定的误差。Python的浮点数也没有大小限制,但是超出一定范围就直接表示为inf(无限大)。

              3. 字符串

              字符串是以单引号 '' 或者双引号 "" 括起来的任意文本。我们注意到Python没有单个字符的概念,就算是单个字符也是一个字符串。如果'' 括起来的字符串内部出现 '' 需要使用\转义,相同的,如果 "" 括起来的字符串内部出现 "" 需要转义。好比下面的程序

              print("My name is 'zs'")  #合法  My name is 'zs'
               
              @@ -191,5 +191,5 @@
               
              + PaperMod | 鲁ICP备2020034310号
              \ No newline at end of file diff --git a/posts/67/index.html b/posts/67/index.html index 3518df73..71830fec 100644 --- a/posts/67/index.html +++ b/posts/67/index.html @@ -5,7 +5,7 @@ 题目描述 使用双向链表作为存储结构,请根据用户输入的一个整数(该整数表示精确到小数点后的位数,可能要求精确到小数点后 500 位),高精度计算PI值。提示:可以利用反三角函数幂级展开式来进行计算。">

              高精度计算pi

              高精度计算PI值

              题目描述

              使用双向链表作为存储结构,请根据用户输入的一个整数(该整数表示精确到小数点后的位数,可能要求精确到小数点后 500 位),高精度计算PI值。提示:可以利用反三角函数幂级展开式来进行计算。

              解题思路

              求PI的算法

              首先这道题是要求必须使用双向链表作为存储结构的,这个需要注意,而且也不能用数组计算完了之后挨个赋值给链表的每个节点,这是耍赖

              那么我们开始再想,用什么公式来求 PI 呢?这是一个问题。先没管题目的提示,我去百度了一通,发现了一个很神奇的算法,用三行就可以计算到圆周率小数点后800+位。

              #include<cstdio>
              +使用双向链表作为存储结构,请根据用户输入的一个整数(该整数表示精确到小数点后的位数,可能要求精确到小数点后 500 位),高精度计算PI值。提示:可以利用反三角函数幂级展开式来进行计算。">

              高精度计算pi

              高精度计算PI值

              题目描述

              使用双向链表作为存储结构,请根据用户输入的一个整数(该整数表示精确到小数点后的位数,可能要求精确到小数点后 500 位),高精度计算PI值。提示:可以利用反三角函数幂级展开式来进行计算。

              解题思路

              求PI的算法

              首先这道题是要求必须使用双向链表作为存储结构的,这个需要注意,而且也不能用数组计算完了之后挨个赋值给链表的每个节点,这是耍赖

              那么我们开始再想,用什么公式来求 PI 呢?这是一个问题。先没管题目的提示,我去百度了一通,发现了一个很神奇的算法,用三行就可以计算到圆周率小数点后800+位。

              #include<cstdio>
               
               using namespace std;
               
              @@ -215,5 +215,5 @@
               
              + PaperMod | 鲁ICP备2020034310号
              \ No newline at end of file diff --git a/posts/68/index.html b/posts/68/index.html index abdc73dd..0c521db2 100644 --- a/posts/68/index.html +++ b/posts/68/index.html @@ -8,7 +8,7 @@ 给出三个不同的初始数字$a,b,c$,黑妹每次选择两个不同的数字,计算出差的绝对值后如果黑板上没有就写在黑板上。问黑妹最多能添加多少个数字。">

              排位三和四记录

              Day 3

              A. 黑妹的游戏Ⅰ

              题意

              给出三个不同的初始数字$a,b,c$,黑妹每次选择两个不同的数字,计算出差的绝对值后如果黑板上没有就写在黑板上。问黑妹最多能添加多少个数字。

              思路

              考虑到辗转相除法的那种过程(其实我也是突发奇想,严谨证明不会),最后黑板上所有的数字是 +给出三个不同的初始数字$a,b,c$,黑妹每次选择两个不同的数字,计算出差的绝对值后如果黑板上没有就写在黑板上。问黑妹最多能添加多少个数字。">

              排位三和四记录

              Day 3

              A. 黑妹的游戏Ⅰ

              题意

              给出三个不同的初始数字$a,b,c$,黑妹每次选择两个不同的数字,计算出差的绝对值后如果黑板上没有就写在黑板上。问黑妹最多能添加多少个数字。

              思路

              考虑到辗转相除法的那种过程(其实我也是突发奇想,严谨证明不会),最后黑板上所有的数字是 $$ ans = \frac{max(a,b,c)}{gcd(a,b,c)} $$ @@ -185,5 +185,5 @@

              + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/posts/77/index.html b/posts/77/index.html index 56aa1a68..91ee2aff 100644 --- a/posts/77/index.html +++ b/posts/77/index.html @@ -5,9 +5,9 @@ 本来之前是用的 Hexo + Github 搭建的,虽然用的是 Github 的服务器,但是我用家里的移动网访问起来还是没什么压力,就是慢一点,可以接受。 后来到了学校,我们学校网访问 Github 的速度简直可以用龟速来形容,白天可以说不开代理根本进不去,只有晚上了才能勉强进得去。然后我就寻思,能不能换成国内的服务器,然后就发现了 Gitee ,这个可以算是中国版的 Github ,他具有的服务 Gitee Pages 在国内可以飞速的访问,But如果想要自定义域名/每次推送自动更新需要开 Github Pages Pro ,还挺贵的,一年大概 120¥ 吧。此外,如果想要将域名解析到国内的服务器必须要备案,备案又必须有服务器,那我有服务器了还费那些事了,于是考虑自己买服务器重构一下博客。">

              自买服务器建站教程

              引言

              本来之前是用的 Hexo + Github 搭建的,虽然用的是 Github 的服务器,但是我用家里的移动网访问起来还是没什么压力,就是慢一点,可以接受。

              后来到了学校,我们学校网访问 Github 的速度简直可以用龟速来形容,白天可以说不开代理根本进不去,只有晚上了才能勉强进得去。然后我就寻思,能不能换成国内的服务器,然后就发现了 Gitee ,这个可以算是中国版的 Github ,他具有的服务 Gitee Pages 在国内可以飞速的访问,But如果想要自定义域名/每次推送自动更新需要开 Github Pages Pro ,还挺贵的,一年大概 120¥ 吧。此外,如果想要将域名解析到国内的服务器必须要备案,备案又必须有服务器,那我有服务器了还费那些事了,于是考虑自己买服务器重构一下博客。

              一些博客系统

              搭博客,首先我们需要构思一下用什么博客系统,市面上比较广泛的有如下几个。

              • Wordpress

                这个绝对是重量级的,在全球范围内也是十分出名的,他的作用也不仅仅局限于搭建个人博客,也有很多例如电商等官网也是基于此系统的,据说全球 37% 的网站都是基于 Wordpress 的,这统治地位,可见一斑。

                优点:博客主题多样,十分的大气,插件也是各种各样的应有尽有。里面的设置也是十分的多,特别特别多,这个可以说是既是优点又是缺点,很多东西如果是个人博客的话根本用不到。

                缺点:不是原生支持markdown,并且对LaTeX的支持十分拉胯。需要安装插件,但是显示效果也是不尽人意。此外,Wordpress相比于下面推出的几个十分的臃肿,因为多了很多东西,安装包挺大的(虽然也就几MB的感觉),而且我没有找到我喜欢的主题,于是装载后卸掉了。

              • Emlog

                Emlog 博客系统十分的简洁轻巧,安装包只有几百KB。

                优点:比较轻巧方便,主题和插件也还算多。

                缺点:其实主题我觉得,没有太好看的。所以没有考虑,大家可以去翻翻看看有没有钟意的主题再考虑是否安装这一个。

              • Typecho

                这个博客系统是我现在正在用的,也是十分的轻巧简洁,是一个国产的博客系统。

                优点:自身对markdown的支持十分的友好,而且有一款插件对LaTeX的支持也是超级棒!因为我比较喜欢之前Hexo里面的NexT主题,而Typecho里面有这个的移植主题,所以最终还是选择的这个系统这个主题。而且他还有好几款例如 Handsome,Aria 这样的我觉得不错的主题。Ps: Handsome主题需要收费,而且现在还在更新,我觉得超值!

                缺点:正式版好久没更新了,上一次更新还是2017年。

              搭建过程

              1. 购买服务器

              首先我们去阿里云那边买一台学生机,一年也就 120¥ 的样子,很实惠。本来一年大概 1600¥ 的样子。

              买学生机的话就买 轻量应用服务器 ,然后应用镜像选一下 BT-Panel 即可。

              一些服务器类型

              初始服务器的配置选择

              2. 登录服务器

              进去之后点击应用详情,看一下 BT-Panel使用步骤

              BT-Panel的使用步骤

              根据上面的指示获取登陆服务器的密码。然后点击左侧的 防火墙 ,在那里开启 8888 端口。如下图所示。

              添加规则

              按如图设置开启8888端口

              3. 配置服务器

              我们登录进入服务器后,点击左侧应用商城。依次安装 Apache、PHP-7.4、Mysql5.6。可能要等挺长时间。

              4. 开启网站

              安装完成后,我们去面板设置那边看一下自己的 服务器ip ,记下来。

              点击左侧网站,添加站点。域名那里写自己的 服务器ip ,然后提交即可。

              新建站点

              然后点击左侧数据库,建立一个新的数据库,用于存放我们之后网站的信息。

              我们访问到我们网站的根目录,然后将自己心仪的博客程序拷入,访问 服务器ip/install.php 即可开启安装!

              安装完成后我们就可以通过 服务器ip 来访问我们的网站了!然后可以去网上找一下心仪的主题和插件来安装~

              一些后续工作

              如果我们要自定义域名,首先我们可以去阿里云 / 腾讯云那边买一个域名,然后进行域名备案,你服务器是在哪边买的就在哪边备案即可。后续备案结束后在云解析那边添加域名解析(具体操作可以百度),然后在 BT-Panel 这边也添加域名解析,这样即可使用我们的自定义域名访问博客了!

              添加域名解析

              还有一些后续的优化例如安装 https安全证书(我自己现在还没搞好QAQ) ,加入 SEO优化 ,提交申请让 搜索引擎收录 等等……大家有兴趣的可以自行探索!

              \ No newline at end of file diff --git a/posts/8/index.html b/posts/8/index.html index a6071975..96777d2b 100644 --- a/posts/8/index.html +++ b/posts/8/index.html @@ -11,7 +11,7 @@ 题意 用一定数目的灯管,显示尽可能大的数 -">

              CodeforcesER #81

              A : Display The Number

              题意

              用一定数目的灯管,显示尽可能大的数

              A

              思路

              因为位数多的肯定更大,所以肯定用尽量少的灯管搭建单个数字更好,最少的两个分别是两个灯管显示的1,以及三个灯管显示的7,所以就是尽可能的用1,如果最后剩余正好三个就显示7。这就转化成了判断奇数还是偶数的题,奇数就显示7111····,偶数就是1111···。注意要把7放在前面(我就踩坑了)。

              代码实现

              #include<cstdio>
              +">

              CodeforcesER #81

              A : Display The Number

              题意

              用一定数目的灯管,显示尽可能大的数

              A

              思路

              因为位数多的肯定更大,所以肯定用尽量少的灯管搭建单个数字更好,最少的两个分别是两个灯管显示的1,以及三个灯管显示的7,所以就是尽可能的用1,如果最后剩余正好三个就显示7。这就转化成了判断奇数还是偶数的题,奇数就显示7111····,偶数就是1111···。注意要把7放在前面(我就踩坑了)。

              代码实现

              #include<cstdio>
               #include<cstring>
               #include<algorithm>
               #include<cmath>
              @@ -152,5 +152,5 @@
               

              + PaperMod | 鲁ICP备2020034310号
              \ No newline at end of file diff --git a/posts/beauty-think/index.html b/posts/beauty-think/index.html index 34330458..a8b4b3f7 100644 --- a/posts/beauty-think/index.html +++ b/posts/beauty-think/index.html @@ -1,67 +1,94 @@ 关于美的一些思考 | Zs's Blog -

              关于美的一些思考

              楔子

              昨天听了学弟们关于博客搭建的一些教程,在听的过程中,也想起了我之前对于博客的种种尝试,发现整体的趋势就是,简约再简约。

              这引发了我对我过去几年的审视,感觉自己的审美一直在变化,对于美的认识和感受也是一直在变的,故写此文来记一些我对美认识的思考。

              简约是我最终的归宿

              遥记得我还在小学和初中时,非常迷恋 QQ飞车 这款游戏,这款游戏里面有一个虚拟人物,人物可以搭配各种装饰,包括但不限于上衣、裤子、发型、发饰、翅膀等,起初我是喜欢要多花哨有多花哨造型,各种发饰、翅膀、脸部特效搞的飞起,现在想起来真是非常搞笑,而且喜欢五颜六色的,当时觉得,真的是太好看了。

              但是过了一段时间,就开始感觉不对劲了,这么花哨,这么丑,这怎么可能是我当时亲手选择的造型。后来就逐渐向简约范靠拢,装饰越简单,色调越单一越喜欢。

              下面的几张图大致可以窥见这个过程:

              qq-car


              而长大后,对于 Blog 的搭建貌似也是这个过程。一开始喜欢相对花哨的,包括各种炫酷的背景、动效等,因此一开始选择了高定制度、有各种花哨特效的 Hexo 框架,不过当时已经在飞车中喜欢上了简约风格,因此主题也选择了 Hexo 中相对简洁的 NexT 主题

              后来发现 Hexo 实在操作过程有些过于繁杂,从操作的意义上来说,他无法做到足够的简洁、简约和高效。

              故而我选择了操作更加方便(例如发表博文、操作主题元素)更加方便的动态博客——Typecho

              起初,我选择延续了在 Hexo 上的 NexT 主题,后来发现了更加符合我审美的 Handsome 主题,第一眼就是非常喜欢,后来忍痛买了主题,用了一段时间后,又逐渐觉得主题没有那么好看,有些看腻了,而且动态博客的升级、安装插件,也是十分繁杂。

              最后,偶然之下,发现了现在在使用的 Hugo 框架,它生成迅速、无需升级、也有着很多简约风的主题,完美符合我的需求,果断迁移了过来,具体流程可见:记一次博客迁移记录 - Zs’s Blog ,一直用到现在,还是对这个框架和主题算是相对满意的。

              总体而言,无论是操作还是页面,都是越来越简约、统一了。不知道未来,我会不会觉得这个也不够简约和统一,再去找寻其他的框架呢。

              各种产品的变迁

              除了上面我自己对美认识的变化,我觉得整个社会对美的认识也是存在变化的。

              往大了讲,是各种建筑、各种设施外观的变化。

              往小了讲,我们用的手机、手机上的软件(例如 QQ、微信),他们的外观每年都在迭代,可能每次变化时有人吐槽有人叫好,但是整体而言,至少对我来说,他是整体都是越来越好看的,虽然逐渐变得臃肿,但是 UI 确实是“实打实”的在进步。下图是 QQ 的变化(左侧是网友仿的一个老版 QQ 界面1,右图是最新版 Mac QQ),可见一二:

              qq

              那就引发了我一个思考,大家对于美的认识是被塑造了呢,还是说这个东西就是客观上的变好看了,美毕竟是一个比较主观的东西。

              如果他是主观上变好看了,那么他是真的好看了吗?而且为什么可以做到如此的统一,让大多数人都觉得变好看了。

              如果他是客观上变好看了,那么到底是什么因素的存在让人觉得他好看呢?

              我觉得美这个东西,很不像生活中常见的发展规律,例如芯片的研发,需要数学、物理、化学等学科实际理论的支持。

              2001 年的人是没有办法设计出 Apple M2 的芯片的,因为受到了各种硬件的制约。而 2001 年的设计师有没有可能设计出最新版 Mac QQ 这样的界面呢,如果不能,是什么制约着它呢?如果能,为什么没有出现这种设计,是因为当时大家觉得他不好看吗?

              因为我不是学设计和美术等专业的,并且这种很很直觉的东西我不知道该怎么去搜索,因此想在这里和大家探讨一下。如果有已经相对成熟的理论,还请大家能够告知与我,解答困扰我好久的疑问。

              AI 绘图

              看网上有人调侃说,愿意称 2022 年为 AI 绘图元年。

              今年确实是突然涌现出非常多的 AI 绘图模型,并且画的还都是有模有样。这也让我想起来之前在 2021年6月 参加过学院的一个 01 学术沙龙2,主题为 “计算 + 艺术 = ∞”。当时在会上和老师们探讨过,是否机器可以理解作品中美的元素,能够理解作品中美的模式?当时大家都是各有各的看法,我个人是持乐观态度的。我觉得美的元素和美的模式,可能是客观存在的,机器人能够让一幅画符合某个模式,来让人觉得这幅画美。

              但是,机器人能否创作出独创性作品,而不是学习、融合之前元素内容,这个还不好说。会不会,这世界上艺术(画作)美的元素、或者美的模式存在是确定的、种类也是确定的,这样如果机器人全部学习到,岂不是可以看作是拿到了整个解空间的基向量,可以创作出任意风格、任意元素的内容了。

              希望不会是这样。

              \ No newline at end of file diff --git a/posts/cxx-class-skills/index.html b/posts/cxx-class-skills/index.html index 410b1e7d..3036f6ee 100644 --- a/posts/cxx-class-skills/index.html +++ b/posts/cxx-class-skills/index.html @@ -1,11 +1,164 @@ C++ 类使用注意事项 | Zs's Blog -

              C++ 类使用注意事项

              前言

              本文包含一些在使用 C++ 类时的注意事项,可避免一些常见问题,并能让你在写代码时更加自信

              因为目前我使用的是 C++ 17,所以仅保证以下内容在 C++ 17 中正确。

              构造函数

              1. 对于单个参数的构造函数,推荐添加 explicit 关键字,防止隐式转换错误调用构造函数。
              class DemoClass {
              +构造函数
              +
              +对于单个参数的构造函数,推荐添加 explicit 关键字,防止隐式转换错误调用构造函数。
              +
              +class DemoClass {
              +    explicit DemoClass(int test) {
              +        this->test_ = test;
              +    }
              +}
              +
              +显式声明有参构造函数后,编译器不会自动生成无参构造函数,若需要,请添加 DemoClass() = default;
              +
              +class DemoClass {
              +    explicit DemoClass(int test) {
              +        this->test_ = test;
              +    }
              +    DemoClass() = default;
              +}
              +
              +若子类中没有显式调用父类的构造函数,子类会默认调用父类的无参构造函数,如果父类没有无参构造函数,会报错。
              +
              +析构函数
              +
              +基类析构函数应该声明为 virtual,这样可以防止子类无法正确的析构。
              +由于基类析构函数为 virtual,派生类的析构函数应该显式的 override。
              +
              +class DemoClass {
              +    virtual ~DemoClass() = default;
              +}
              +
              +class ChildClass: public DemoClass {
              +    ~ChildClass() override {
              +        xxx;
              +    }
              +}
              +成员变量默认值
              +对于类或局部作用域中未明确指定默认值的成员变量,其值遵循以下规则:
              +
              +对于原生类型(primitive types),即 int、float、int*、string* 等,默认值为随机的脏数据。
              +对于对象(objects),例如自定义类、或 std::string 等,会调用默认(无参)构造函数,若没有默认(无参)构造函数,则报错。
              +对于引用(reference)类型,例如 std::string&,必须赋初始值或在构造函数中初始化,若为初始化,则报错。
              +
              +float age; // 脏数据、随机值(无意义),此时访问会出现未定义行为
              +int *ptr;  // 脏数据、随机值(无意义),此时访问会出现未定义行为
              +string name;  // 调用默认构造函数,对于 std::string 来说为空字符串 ""
              +DemoClass demo; // 若 DemoClass 存在无参构造函数,则调用,否则编译错误
              +string *pname;  // 脏数据、随机值(无意义),此时访问会出现未定义行为
              +string &rname;  // 编译错误,必须显式初始化
              +const string &crname;  // 同上,编译错误
              +成员变量初始化方式
              +初始化成员变量一般而言有四种方式,一般而言第二种和第四种方式为等价的,不过在下面我们会看到一种例外:'>

              C++ 类使用注意事项

              前言

              本文包含一些在使用 C++ 类时的注意事项,可避免一些常见问题,并能让你在写代码时更加自信

              因为目前我使用的是 C++ 17,所以仅保证以下内容在 C++ 17 中正确。

              构造函数

              1. 对于单个参数的构造函数,推荐添加 explicit 关键字,防止隐式转换错误调用构造函数。
              class DemoClass {
                   explicit DemoClass(int test) {
                       this->test_ = test;
                   }
              @@ -60,5 +213,5 @@
               
              + PaperMod | 鲁ICP备2020034310号
              \ No newline at end of file diff --git a/posts/default-apps-f2023/index.html b/posts/default-apps-f2023/index.html index bdfdef51..9bc31410 100644 --- a/posts/default-apps-f2023/index.html +++ b/posts/default-apps-f2023/index.html @@ -2,15 +2,105 @@

              My App Defaults - 2023 Fall

              After seeing Duel of the Defaults and App Defaults, I’d like to share here some of my app defaults at the end of 2023.

              Since I am from China, some apps may not be suitable to everyone, such as WeChat, NeteaseMusic, etc.

              The software built-in on iPhone or Mac will have the .app extension.

              \ No newline at end of file diff --git a/posts/docker-gitlab-ssh/index.html b/posts/docker-gitlab-ssh/index.html index 5793fca8..d6769153 100644 --- a/posts/docker-gitlab-ssh/index.html +++ b/posts/docker-gitlab-ssh/index.html @@ -1,20 +1,77 @@ Docker-Gitlab 与主机共用 ssh 的 22 端口 | Zs's Blog -

              Docker-Gitlab 与主机共用 ssh 的 22 端口

              背景

              在使用 Docker 搭建 Gitlab/Gitee 会导致无法与主机端共用 22 端口,这导致 ssh 连接的时候会使用形如 ssh://git@git.xxxx.cn:4022/zs/zsblog.git 的 ssh 链接,而不是像官方 Gitlab 那种非常干净的 git@git.xxxx.cn/zs/zsblog.git 链接。这对于我这种强迫症而言非常的难受啊,但因为主机的 22 端口已经被占用了,无法共用,所以需要考虑两者共享端口的问题。

              虽说是两者共用,但其实还是使用类似于端口转发的特点,简单说就是在主机设置 git 用户,然后通过一个脚本将 git 用户的所有 ssh 流量转发到 Gitlab 容器中,从而完成对应的事情。

              关于 Gitee 的设置,Gitee 官方的 Docker 部署教程1已经说的很清楚了,按照该步骤执行完全没问题。

              而关于 Gitlab 貌似没有比较详尽的教程,搜索后发现了一个 Issue2 以及一篇博文3,后者讲的比较清楚,但是经过实践后发现存在一定问题,因此决定将可行的方案记录下来。

              具体步骤

              一、初始设置

              在开始之前,docker-compose.yml 中设置比较关键的几个配置如下:

              gitlab-web:
              +具体步骤
              +一、初始设置
              +在开始之前,docker-compose.yml 中设置比较关键的几个配置如下:
              +gitlab-web:
              +	image: 'gitlab/gitlab-ce:latest'
              +	container_name: 'gitlab'
              +	restart: always
              +	environment:
              +		GITLAB_OMNIBUS_CONFIG: |
              +			gitlab_rails['gitlab_shell_ssh_port'] = 4022
              +	ports:
              +		- '3090:80'
              +		- '4022:22'
              +		- '6060:6060'
              +	volumes:
              +		- '/srv/gitlab/config:/etc/gitlab'
              +		- '/srv/gitlab/logs:/var/log/gitlab'
              +		- '/srv/gitlab/data:/var/opt/gitlab'
              +		- .... #一些其他的配置
              +如上设置基本可以确保 Gitlab 形如 ssh://git@git.xxxx.cn:4022/zs/zsblog.git 的链接可以使用。">

              Docker-Gitlab 与主机共用 ssh 的 22 端口

              背景

              在使用 Docker 搭建 Gitlab/Gitee 会导致无法与主机端共用 22 端口,这导致 ssh 连接的时候会使用形如 ssh://git@git.xxxx.cn:4022/zs/zsblog.git 的 ssh 链接,而不是像官方 Gitlab 那种非常干净的 git@git.xxxx.cn/zs/zsblog.git 链接。这对于我这种强迫症而言非常的难受啊,但因为主机的 22 端口已经被占用了,无法共用,所以需要考虑两者共享端口的问题。

              虽说是两者共用,但其实还是使用类似于端口转发的特点,简单说就是在主机设置 git 用户,然后通过一个脚本将 git 用户的所有 ssh 流量转发到 Gitlab 容器中,从而完成对应的事情。

              关于 Gitee 的设置,Gitee 官方的 Docker 部署教程1已经说的很清楚了,按照该步骤执行完全没问题。

              而关于 Gitlab 貌似没有比较详尽的教程,搜索后发现了一个 Issue2 以及一篇博文3,后者讲的比较清楚,但是经过实践后发现存在一定问题,因此决定将可行的方案记录下来。

              具体步骤

              一、初始设置

              在开始之前,docker-compose.yml 中设置比较关键的几个配置如下:

              gitlab-web:
               	image: 'gitlab/gitlab-ce:latest'
               	container_name: 'gitlab'
               	restart: always
              @@ -83,5 +140,5 @@
               
              + PaperMod | 鲁ICP备2020034310号
              \ No newline at end of file diff --git a/posts/github-suspended-for-no-reason/index.html b/posts/github-suspended-for-no-reason/index.html index 50c17988..ee61b834 100644 --- a/posts/github-suspended-for-no-reason/index.html +++ b/posts/github-suspended-for-no-reason/index.html @@ -1,30 +1,72 @@ 记一次 GitHub 账号突然被 suspended 的经历 | Zs's Blog -

              记一次 GitHub 账号突然被 suspended 的经历

              TL;DR

              我在 2023.11.07 凌晨被 GitHub 封禁了账号,GitHub 账号被 suspended 后会在 GitHub 上完全除名(只有自建创建的组织不会消失)。

              被封禁后我首先通过 Google 查找了相关的文章。

              根据博主 @phith0n 的指引首先通过 API:https://api.github.com/users/[username]/starred 备份了自己 star 过的项目,同时通过 Can’t sign-in form 来在无法登陆的情况下发起 GitHub Support 工单来询问/请求解封/询问原因等,一般在两天内收到了回复。最终账号顺利恢复。

              我此次被封禁的原因是由于管理的组织内部有成员被盗号,在组织内创建了违法仓库,因此管理员和被盗号的成员都被封禁了,但后续都被解除了封禁。同时也有可能因为创建违反 DMCA 条款 的仓库、fork 违反 DMCA 条款的仓库、贩卖学生/教师教育包等原因被封禁。

              背景

              大约在 2023.11.07 凌晨 00:30 左右,在 GitHub 上看到了一个不错的项目想要 Star,被提示没有登陆。当时我还在想:“怎么这次 session 过期的这么快?” 就当我边疑惑边重新登录后,突然收到了下图的提示我的账号「Account suspended」:

              确认无法登录后,查看邮箱没有任何相关通知。同时我查看了其他内容是否还存在,最后综合表现如下:

              1. 没有任何邮件/信息通知被封禁及更加具体的封禁原因,只告诉违反了 ToS
              2. 个人页面(https://github.com/zzsqwq)无法访问,访问显示 404
              3. 提的相关 Issue 全部被删除(隐藏),无法找到
              4. 个人创建的所有项目,访问全部 404,也无法拉取
              5. 自己参与的项目,被除名
              6. 自己加入的组织,被除名
              7. 自己创建的组织,访问 404

              简单说就是跟这个账号从来没存在过一样,除了仍可以登陆,但是显示 suspended。接下来开始尝试找办法恢复。

              恢复经过

              试图查找封禁原因

              首先看提示上显示违反了 Github Terms of Service,快速的看了一眼 ToS 没发现我有什么明显违规的地方。

              通过搜索引擎搜索 「Github 账号 suspended」相关信息,找到了两个比较强相关的帖子:

              其中第一个是因为 fork 了违反 DMCA 的仓库而被封禁,第二个看起来是因为购买了违规的教师包而被封禁。

              首先我是使用正规身份申请的学生教育包,第二个博主的情况可以排除。关于第一个,我仔细想了一下我过去几天的行为:由于过去几天大量 Clash 相关仓库被删除和停止维护,我 fork 了五个与 Clash 有关的仓库,但是理论上 Clash 相关的仓库是不存在违反 DMCA 这一说的,因此第一个博主的情况也可以被排除。

              同时第一个博主提到,我们可以通过 API:https://api.github.com/users/[username]/starred 来找到之前 star 过的仓库,我试了一下确实,遂备份了一份 json 文件。同时查看了关于关注和被关注相关的 API:https://api.github.com/users/[username]/followershttps://api.github.com/users/[username]/following,均为空,看来只能找到 star 过的仓库。

              但是有一个比较神奇的点是:第一个博主提到:「但是我创建的 Group 还是好的,没有受影响。」。但是在我账号上,我唯一创建的组织 nwpusr-vision-team 访问时也显示 404,和这个博主的情况不符,但暂时不明是什么原因。

              联系 GitHub 寻求帮助

              于是经过一系列查找,我在 GitHub 上使用新的邮箱注册了一个新的账号(旧的邮箱无法注册新账号),并通过 Github Support 界面发起了一个工单说明我的情况。当时是大概凌晨一点多提交的工单,2023.11.07 下午五点多收到了回复,告知我必须使用原邮箱来联系 Github Support 支持才可以处理我的原账号,可以通过 Can’t sign-in form 来在无法登录的情况下提交相关工单(但是似乎直接给 Github 发邮件也可以成功创建工单,不确定)。

              同时在这一天的下午,我也得知了有另外两位认识的同学也跟我一模一样在没有任何通知的情况下被封禁,具体的表现也和我一样。而我们之间的联系就是我们同属于一个组织:nwpusr-vision-team 。至此我推断出了一个大致的原因 —— 我创建的这个 Github 组织出了问题,导致我们三个都受到了牵连,但是具体的什么原因还未知,因为这个组织从我创建后几乎就没用过,里面也只有一个 README 一样的仓库,实在是想不明白有什么封禁的理由。

              一直等到第三天即 2023.11.09 的早上9点多,我收到了一封关于密码被重置的邮件,于是我查看了我的 GitHub个人主页 发现已经不再是 404 了。于是我按照提示重置了密码后,顺利的登录了 Github,同时也收到了 GitHub Support 的回复,全文如下:

              Hello Zhan,

              Thanks for contacting GitHub Support on the email address associated with your zzsqwq account.

              We recently detected suspicious activity on your account and applied restrictions out of an abundance of caution while we investigated what took place.

              To secure your account, we have forced a password reset. If you haven’t already, please reset your password.

              I’ve sent you a separate email just now with a link to complete this process. Please note that the link will expire in 24 hours. Alternatively, visit the following to request a password reset token:

              https://github.com/password_reset

              To protect your account from unauthorized access, please choose a strong and unique password for your account. We have a help article with some recommendations here:

              https://docs.github.com/authentication/keeping-your-account-and-data-secure/creating-a-strong-password

              As an added precaution, we also recommend reviewing your security log and reverting any changes you don’t recognize.

              For more information, read Reviewing your security log in the GitHub Docs.

              Additionally, we also recommend double checking your stars and removing any that weren’t added by you:

              https://github.com/stars

              I hope this clears things up. If you have any further questions, please let us know.

              Kind regards, + +没有任何邮件/信息通知被封禁及更加具体的封禁原因,只告诉违反了 ToS +个人页面(https://github.com/zzsqwq)无法访问,访问显示 404 +提的相关 Issue 全部被删除(隐藏),无法找到 +个人创建的所有项目,访问全部 404,也无法拉取 +自己参与的项目,被除名 +自己加入的组织,被除名 +自己创建的组织,访问 404 + +简单说就是跟这个账号从来没存在过一样,除了仍可以登陆,但是显示 suspended。接下来开始尝试找办法恢复。 +恢复经过 +试图查找封禁原因 +首先看提示上显示违反了 Github Terms of Service,快速的看了一眼 ToS 没发现我有什么明显违规的地方。">

              记一次 GitHub 账号突然被 suspended 的经历

              TL;DR

              我在 2023.11.07 凌晨被 GitHub 封禁了账号,GitHub 账号被 suspended 后会在 GitHub 上完全除名(只有自建创建的组织不会消失)。

              被封禁后我首先通过 Google 查找了相关的文章。

              根据博主 @phith0n 的指引首先通过 API:https://api.github.com/users/[username]/starred 备份了自己 star 过的项目,同时通过 Can’t sign-in form 来在无法登陆的情况下发起 GitHub Support 工单来询问/请求解封/询问原因等,一般在两天内收到了回复。最终账号顺利恢复。

              我此次被封禁的原因是由于管理的组织内部有成员被盗号,在组织内创建了违法仓库,因此管理员和被盗号的成员都被封禁了,但后续都被解除了封禁。同时也有可能因为创建违反 DMCA 条款 的仓库、fork 违反 DMCA 条款的仓库、贩卖学生/教师教育包等原因被封禁。

              背景

              大约在 2023.11.07 凌晨 00:30 左右,在 GitHub 上看到了一个不错的项目想要 Star,被提示没有登陆。当时我还在想:“怎么这次 session 过期的这么快?” 就当我边疑惑边重新登录后,突然收到了下图的提示我的账号「Account suspended」:

              确认无法登录后,查看邮箱没有任何相关通知。同时我查看了其他内容是否还存在,最后综合表现如下:

              1. 没有任何邮件/信息通知被封禁及更加具体的封禁原因,只告诉违反了 ToS
              2. 个人页面(https://github.com/zzsqwq)无法访问,访问显示 404
              3. 提的相关 Issue 全部被删除(隐藏),无法找到
              4. 个人创建的所有项目,访问全部 404,也无法拉取
              5. 自己参与的项目,被除名
              6. 自己加入的组织,被除名
              7. 自己创建的组织,访问 404

              简单说就是跟这个账号从来没存在过一样,除了仍可以登陆,但是显示 suspended。接下来开始尝试找办法恢复。

              恢复经过

              试图查找封禁原因

              首先看提示上显示违反了 Github Terms of Service,快速的看了一眼 ToS 没发现我有什么明显违规的地方。

              通过搜索引擎搜索 「Github 账号 suspended」相关信息,找到了两个比较强相关的帖子:

              其中第一个是因为 fork 了违反 DMCA 的仓库而被封禁,第二个看起来是因为购买了违规的教师包而被封禁。

              首先我是使用正规身份申请的学生教育包,第二个博主的情况可以排除。关于第一个,我仔细想了一下我过去几天的行为:由于过去几天大量 Clash 相关仓库被删除和停止维护,我 fork 了五个与 Clash 有关的仓库,但是理论上 Clash 相关的仓库是不存在违反 DMCA 这一说的,因此第一个博主的情况也可以被排除。

              同时第一个博主提到,我们可以通过 API:https://api.github.com/users/[username]/starred 来找到之前 star 过的仓库,我试了一下确实,遂备份了一份 json 文件。同时查看了关于关注和被关注相关的 API:https://api.github.com/users/[username]/followershttps://api.github.com/users/[username]/following,均为空,看来只能找到 star 过的仓库。

              但是有一个比较神奇的点是:第一个博主提到:「但是我创建的 Group 还是好的,没有受影响。」。但是在我账号上,我唯一创建的组织 nwpusr-vision-team 访问时也显示 404,和这个博主的情况不符,但暂时不明是什么原因。

              联系 GitHub 寻求帮助

              于是经过一系列查找,我在 GitHub 上使用新的邮箱注册了一个新的账号(旧的邮箱无法注册新账号),并通过 Github Support 界面发起了一个工单说明我的情况。当时是大概凌晨一点多提交的工单,2023.11.07 下午五点多收到了回复,告知我必须使用原邮箱来联系 Github Support 支持才可以处理我的原账号,可以通过 Can’t sign-in form 来在无法登录的情况下提交相关工单(但是似乎直接给 Github 发邮件也可以成功创建工单,不确定)。

              同时在这一天的下午,我也得知了有另外两位认识的同学也跟我一模一样在没有任何通知的情况下被封禁,具体的表现也和我一样。而我们之间的联系就是我们同属于一个组织:nwpusr-vision-team 。至此我推断出了一个大致的原因 —— 我创建的这个 Github 组织出了问题,导致我们三个都受到了牵连,但是具体的什么原因还未知,因为这个组织从我创建后几乎就没用过,里面也只有一个 README 一样的仓库,实在是想不明白有什么封禁的理由。

              一直等到第三天即 2023.11.09 的早上9点多,我收到了一封关于密码被重置的邮件,于是我查看了我的 GitHub个人主页 发现已经不再是 404 了。于是我按照提示重置了密码后,顺利的登录了 Github,同时也收到了 GitHub Support 的回复,全文如下:

              Hello Zhan,

              Thanks for contacting GitHub Support on the email address associated with your zzsqwq account.

              We recently detected suspicious activity on your account and applied restrictions out of an abundance of caution while we investigated what took place.

              To secure your account, we have forced a password reset. If you haven’t already, please reset your password.

              I’ve sent you a separate email just now with a link to complete this process. Please note that the link will expire in 24 hours. Alternatively, visit the following to request a password reset token:

              https://github.com/password_reset

              To protect your account from unauthorized access, please choose a strong and unique password for your account. We have a help article with some recommendations here:

              https://docs.github.com/authentication/keeping-your-account-and-data-secure/creating-a-strong-password

              As an added precaution, we also recommend reviewing your security log and reverting any changes you don’t recognize.

              For more information, read Reviewing your security log in the GitHub Docs.

              Additionally, we also recommend double checking your stars and removing any that weren’t added by you:

              https://github.com/stars

              I hope this clears things up. If you have any further questions, please let us know.

              Kind regards, Pip, GitHub Support

              大意就是 GitHub 最近在我的帐户上检测到可疑活动,并在调查发生的事情的同时出于谨慎考虑对我的账号施加了限制。现在已经把我的账号解封了,但是需要重置密码后才可以继续使用。

              后续处理

              登录账号后,我发现组织 nwpusr-vision-team 仍存在限制,提示如下:

              由于被对外隐藏了,因此我自己可以访问这个组织,但是如果不登录账号查看这个组织仍是 404 的。

              通过对组织进行查看,发现组织内多了一个新的仓库,并且是违规仓库,是 fork 了一个 仓库 并更新了 README 更新成违规信息。

              这下我大概推测出了封号原因:首先下图是我们目前仓库成员图,红框内的是这次被封禁的人,从上到下依次是被盗号且创建违法仓库的同学、另一位管理员同学和我。应该由于那位同学被盗号并且在组织内创建了违法仓库,但是身为管理员的我们两个人在有管理权的情况下没有及时将仓库删除,因此 GitHub 认为我们三个人都可能账号存在风险,因此一起被禁了。随后进一步的调查发现这三个账号都已经没什么异常,因此就直接解除了封禁。

              随后我将组织内的违法仓库删除并反馈给 Github Support 后,组织状态也恢复了正常。

              随后我又就被封号原因这个问题,和 Github Support 人员展开了一些沟通,但是他们只是一直在说「GitHub 在我的帐户上检测到可疑活动,并在调查发生的事情的同时出于谨慎考虑对我的账号施加了限制,由于这个过程是他们检测工具自动进行的,恕他们无法告知更准确的原因」,最后仍是无法得知我推断的是否正确,但是应该除此之外没什么其他的原因了,由于我 GitHub 开启了 2FA 同时没泄露任何 token,理论上不会被有被异地登陆的可能。

              Our security team has recently been investigating suspicious activity and account hijacking, and we were concerned that your account may have been affected. Out of an abundance of caution, restrictions were placed on your account as part of our attempts to combat this campaign.

              We use a number of detection methods to find abuse on GitHub, but I’m afraid I’m not at liberty to discuss our internal tooling.

              后记

              整件事情看下来其实 GitHub 的处理有点离谱,仅仅是检测到账号可能存在异常活动,就在没有任何通知且不告知详细缘由的情况下封禁了账号,同时无法访问任何仓库/Issue,目前来看恢复账号也需要个至少两天,可能会耽误很多事情。

              我也就这件事情进行了反馈:

              Lastly, I believe the way GitHub officially handled this situation was quite unreasonable. Our accounts were banned without any email notification, making it impossible to access repos, followers, following, stars, issues (all showing 404), and without stating a specific reason. For instance, as mentioned in the previous reply: “We recently detected suspicious activity on your account and applied restrictions out of an abundance of caution while we investigated what took place.” I think if you were to conduct an investigation, you could consider first imposing restrictions on the account (such as only allowing the repository to be pulled without any write operations on the account/repository) and notify us by email: “We have detected unusual activity and have restricted your account for safety reasons.” This would seem more reasonable and wouldn’t leave us confused. Please seriously consider the workflow for the future; this will make everyone love GitHub more. Thank you!

              他们的一些回复如下(分多封邮件进行交流,不同邮件间使用分割线分割):

              Thanks for your reply and your feedback, I appreciate you taking the time to share it with me and I will make sure to share it with the relevant team.


              We restricted your account as we had reasons to believe it may have been compromised in the aforementioned campaign. However, in your specific case, further review suggests that your personal account was unlikely to have been affected. I do apologize for the inconvenience, but hope you understand our need to prioritize account security.


              I understand that having your account restricted unexpectedly can be a frustrating experience, and I appreciate your feedback on receiving notification. I have shared your feedback internally.

              希望 GitHub 后续可以改进这个流程。


              Ps:这次导致封号的违规仓库居然还是 fork 的 RoboRTS ,就连这个都跟 RM 有关,有点离谱。

              + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/posts/hat-train-fcos/index.html b/posts/hat-train-fcos/index.html index ac2c2ba7..fcf63caa 100644 --- a/posts/hat-train-fcos/index.html +++ b/posts/hat-train-fcos/index.html @@ -1,50 +1,95 @@ 基于地平线 HAT 训练与部署 FCOS 全流程 | Zs's Blog -

              基于地平线 HAT 训练与部署 FCOS 全流程

              前言

              最近想要使用自己采集与标注的数据集来训练与部署一下地平线微调过的 FCOS 网络,在询问和查看文档后发现如果想基于官方微调的模型训练,需要使用提供 HAT(Horizon Algorithm Toolkit,海图) 来进行,具体的文档可以查看:Horizon Algorithm Toolkit 文档,这是在线的版本,版本可能会比较旧,想看最新版的可以查看离线的版本,位置在 OE(Open Explorer,天工开物) 包的 doc 目录下,如下图:

              image-20230224155005117

              想要方便的查看离线文档可以通过 Python 来实现,在 doc 目录下执行:

              python3 -m http.server 3000
              +CUDA Version: 11.7
              +OE Version: v2.4.2( gcc-9.3.0 For XJ3 )">

              基于地平线 HAT 训练与部署 FCOS 全流程

              前言

              最近想要使用自己采集与标注的数据集来训练与部署一下地平线微调过的 FCOS 网络,在询问和查看文档后发现如果想基于官方微调的模型训练,需要使用提供 HAT(Horizon Algorithm Toolkit,海图) 来进行,具体的文档可以查看:Horizon Algorithm Toolkit 文档,这是在线的版本,版本可能会比较旧,想看最新版的可以查看离线的版本,位置在 OE(Open Explorer,天工开物) 包的 doc 目录下,如下图:

              image-20230224155005117

              想要方便的查看离线文档可以通过 Python 来实现,在 doc 目录下执行:

              python3 -m http.server 3000
               

              这样就可以在本地的 0.0.0.0:3000 地址开启一个 http server,随后可以在本地浏览器使用 localhost:3000 或者其他电脑浏览器使用 {ip}:3000 来访问文档。

              但是查看 文档 过后会发现,文档其实也没有那么的全面,讲的比较简单,尝试了一下中间坑还挺多的,社区里面关于这方面的帖子也不多12,因此想记录下我尝试的全流程,也可以作为对上面教程文档的补充。

              下面主要分为三部分:

              1. 训练的环境配置。

              2. 如何基于官方的 COCO 数据集训练?这里就是指基于 mscoco 发布的包含 80 类的数据集

              3. 如何基于自己的数据集进行训练?这里就是指自己建立的,自定义类别的,可能只有四五类,没有 80 类的数据集。

              下方涉及到的一些代码、脚本和模型等,可以在 Github 仓库 中找到。

              训练的环境配置

              我自己环境配置如下:

              OS: Ubuntu 20.04

              Docker: 20.10.23

              Nvidia Docker: 2.11.0-1

              GPU: RTX3090

              NVIDIA Driver Version: 515.65.01

              CUDA Version: 11.7

              OE Version: v2.4.2( gcc-9.3.0 For XJ3 )

              因为我的开发是基于 Ubuntu 进行,训练是 GPU 进行的,所以这里只提及关于 Ubuntu + GPU 训练的环境配置,Windows 情况下,或者只有 CPU 的情况,我也没尝试过。

              首先需要安装 Docker 以及 NVIDIA Docker,前者安装参考:Docker 安装文档,后者安装参考:NVIDIA Docker 安装文档

              参考官方 X3 芯片文档编写启动脚本 run_docker.sh 如下:

              #!/bin/bash
               export version=v2.4.2
               
              @@ -468,5 +513,5 @@
               
              + PaperMod | 鲁ICP备2020034310号
              \ No newline at end of file diff --git a/posts/how-to-search/index.html b/posts/how-to-search/index.html index d3831653..2ba279fd 100644 --- a/posts/how-to-search/index.html +++ b/posts/how-to-search/index.html @@ -1,37 +1,61 @@ 如何善用搜索引擎? | Zs's Blog -

              如何善用搜索引擎?

              前言

              我们使用搜索引擎可能是为了搜集信息、或者是解决一些问题。但如果不能正确的使用搜索引擎,使用关键字等,可能搜到的答案就与问题相关不大,或者与我们的问题相差甚远。

              这篇文章意在分享我个人在学习、工作中使用搜索引擎的一些技巧与思考,可能后续会不断的更新,如有纰漏,还请大家指正。

              应该使用什么搜索平台?

              想要提高搜索的效率,选择一个好的搜索引擎或者内容平台颇为重要。

              下面列举的是我平时会使用的一些平台,列出的顺序代表了我个人对于他们的推荐程度:

              第一类为通用搜索引擎,例如 为什么最近头发掉的更多了? 在其上可以搜索任何问题,其中 Google 的使用门槛相对较高,而 Bing 针对国内用户来说是一个相对不错的选择,不建议常用 Baidu,因为其上广告非常多,有用信息密度相对较小。

              第二类为编程相关问题,例如 CMake 为什么报错了? 其中 Stack Overflow、Github 虽均为国外的平台,但是国内是可以访问的,不过在 Baidu 搜索引擎中词条相对靠后,同时也需要使用英文来进行问题检索。(Btw,Stack 系列还有例如 Stack Exchange 平台,它的模式与前者相同,但是更偏日常一些。)除此以外,后面的平台均为国内平台,所列是我平时常见的一些,整体而言,前面的文章质量普遍会比后面的高一些,其中腾讯云开发者社区、CSDN、华为云开发者社区三者内容重叠度较高。

              第三类为日常问题,例如 Mac 上有什么好用的 App ?可以在 V2EX 上寻找答案,当然,它也是包罗万象的,只不过我常用它来解决日常各类小问题。

              如何正确的知道问题所在?

              我们遇到一个问题,要首先能够定位这个问题的关键。

              例如编译中出错了,可能有很多 log,你必须能够精确定位到到底哪一条 log 才是这次编译出错的关键,进而才能解决这个问题。

              以 CMake 为例,编译时报错 log 一般为红色,警告 log 一般为黄色,普通 log 一般为白色。得益于这种等级/颜色分明的 log ,我们可以快速的定位报错。我们日常编程中,为了便于 Debug,最好也遵循这个规范,例如在 C++ 中打印错误 log 时推荐使用 std::stderr 而不是 std::stdout

              见过很多身边的同学遇到了报错,就一股脑粘贴所有的报错 log,然后贴到搜索引擎中,发现相关的错误基本没有。这就是没有其中错误的关键,报错时的 log 可能 100 行只有 10 行是关键的,甚至只有一行是关键的,例如 100 行 log 中只有 未定义的引用(undefined reference to ‘xxx’) 这一句是最关键的。

              搜索不到怎么办?

              即使你选择了正确的平台,筛选出了关键的报错信息,你可能仍然无法搜索到对应的问题,这怎么办呢?

              首先,你可能需要转换一下语言,例如之前问题采用中文,你应该将其翻译成英文再重新搜索,记得翻译时要保证专有名词的正确性

              如果还是不行,这个时候我认为应该首先静下心来思考一下这是属于什么问题,是这个程序特有的问题,还是这个程序使用的某个库或部件导致的问题?你可能需要仔细思考来进一步提取错误(问题)中的关键所在,使用提取的关键字继续搜索或者去查对应的程序或者库的 Q&A ,如果还是无法找到,就应该去看相应部分的文档,去 RTFM(Read The Fantastic Manual)。

              最后的最后,还是无法找到的话,那你就应该考虑去对应程序、库或部件的 Github Issue 或者论坛、或非定向的 Stack Overflow 等平台提交问题,在提问之前,你最好仔细阅读过 提问的智慧1不然可能无法获得到热情、友善的回复

              Microsoft Edge Question

              上图所示是我之前 有关 Microsoft Edge 的一个提问 ,应该可以算是一个相对正确的示范。

              最好积累一个错误文档

              感觉这个的作用有点类似于高中时候老师们推崇的错题本了,虽然我一直觉得没啥用,也几乎没有照做过。

              但是在平常解决问题时我确实是会遇到,上次明明遇到过类似的问题,我也解决了,但是再遇到又忘了如何解决了。可能是因为随着年纪的增大记性越来越差了🤣,不过如果大家不嫌麻烦可以养成每次遇错都能记录一下,估计坚持下来会非常的有用(虽然我自己都没做到)。

              \ No newline at end of file diff --git a/posts/index.html b/posts/index.html index d6de43b3..5554a3c1 100644 --- a/posts/index.html +++ b/posts/index.html @@ -1,6 +1,6 @@ Posts | Zs's Blog -

              2023 年度总结

              前言 在回望过去时,我们常感叹时间飞逝,我想这或许是因为过去发生的无数大小事情最终在脑海中留存的只有寥寥几件。因此,撰写年度总结这件事似乎变得格外有意义,它能帮助我们更充分地回味过去的一年。可能正是因为如此,现在各大 APP 似乎都很喜欢推出年度总结,例如网易云、QQ音乐、知乎、飞书、京东、美团、支付宝等。为此,我写下了这篇 2023 年度总结。 +

              2023 年度总结

              前言 在回望过去时,我们常感叹时间飞逝,我想这或许是因为过去发生的无数大小事情最终在脑海中留存的只有寥寥几件。因此,撰写年度总结这件事似乎变得格外有意义,它能帮助我们更充分地回味过去的一年。可能正是因为如此,现在各大 APP 似乎都很喜欢推出年度总结,例如网易云、QQ音乐、知乎、飞书、京东、美团、支付宝等。为此,我写下了这篇 2023 年度总结。 仔细回味我这过去的一年,我想用几个关键词来概括:#消费升级、#数码科技、#大模型、#老友重逢。 #消费升级:这一年是我消费升级的一年,尽管今年「消费降级」这个词似乎很火,但我似乎与大众走上了一条相反的道路。可能是因为我以往的消费水平本就不高,所以「降级」更是无从谈起。 #数码科技:这一年我购入了一些新的数码设备,虽然数量不多,但每一件都还挺满意的。同时今年由于消费观念的转变,也支持了很多正版软件,因此今年在软件上的开销也不小。 @@ -17,20 +17,21 @@ 五月 五月似乎是相对平淡的一月,在继续社畜日常的同时开始写毕设了。 六月 月初和朋友去海底捞过了生日,属于是 404 的「企业文化」了。然后终于把毕设给忙完了,返校进行了答辩,结果还算顺利。因为返校了也见了很多老朋友,舍友、基地的伙伴们、学弟们(是的应该是没有学妹),约了数不清次数的饭。 基地的大伙聚会 七月 我正式本科毕业了。 -就像开头说的,回望过去总是很快。感觉开学和父母踏进工大校园的那一天还历历在目,转眼间就要毕业了。纵有万般不舍,但还是不得不和朋友们分别了,最后一晚大家一起在 KTV 合唱《朋友》的时候,忍不住泪奔。 -再见,工大 八月 相对平淡的一月,学弟来深圳参加夏令营,顺便过来找我玩,一起逛了腾讯大厦和华强北,看完感觉大厂平常的这些福利确实还是很不错的(不过确实加班严重)。...

              January 3, 2024 · 1 min · zzsqwq

              App 使用体会记录 - macOS 篇

              平时很喜欢倒腾各种 Apple 平台的各种软件,所以体验了很多 iOS/iPadOS/macOS 上的软件,所以计划汇总一下自己的一些简短的使用体验和评价等,希望能在大家后续选择软件的时候起到一些参考和帮助。 +...

              January 3, 2024 · 1 min · zzsqwq

              App 使用体会记录 - macOS 篇

              平时很喜欢倒腾各种 Apple 平台的各种软件,所以体验了很多 iOS/iPadOS/macOS 上的软件,所以计划汇总一下自己的一些简短的使用体验和评价等,希望能在大家后续选择软件的时候起到一些参考和帮助。 由于软件可能较多,不能一次性写完。同时,因为我也在不断体验新的软件,有新的感受,因此这篇博客应该是持续更新的,欢迎常来看看。 -速览表 App 名称 简短描述 功能限制 订阅形式 价格 购入时间 购入渠道 同类型产品 AIDente 电池电量管理 有免费使用功能,但有共功能需要收费 买断 Free Battery, BatFi AdGuard 广告拦截软件 AltTab 增强 macOS App 切换 Command-Tab Plus, Contexts,HyperSwitch, Bartender 5 Menubar 管理 Bob 大概是最好用翻译软件 EasyDict BuhoCleaner 垃圾清理器/软件卸载器 CleanMyMac, Sensei Clash X / Clash X Pro 代理 Surge, Stash CleanBuddy 键盘锁定清理 Cleaner CleanShot X 大概最好用的截图软件 Cleaner 键盘屏幕锁定清理 CleanBuddy Dash 文档利器 Dato Menubar 日历软件 Fantastical, Itsycal DevUtils 开发小工具合集 Downie 4 各类视频下载器 VDown HapiGo 启动器 Alfred, Raycast HazeOver 生产力工具,突出重点 Hazel 自动清理集合 JetBrains 全家桶 包含 Clion/IDEA 等 VSCode, Eclipse Lunar 显示器管理 MonitorControl, DisplayBuddy, Better Display Maccy 开源免费的剪切板管理工具 Paste, PasteNow, PastePal Manico 快速启动器 Command-Tab Plus MimeStram Gmail 客户端 MonitorControl 开源显示器管理,很够用 Lunar, DisplayBuddy, Better Display NetNewsWire 全平台 RSS 阅读器 Obsidian 笔记软件 Omnivore 稍后读软件 Pocket, MarkMark, Only Switch 一键完成各种任务 One Switch OpenImageOptim 图片压缩 TinyPNG OrbStack 容器管理,平替 Docker Desktop Docker Desktop, Podman, lima, colima Permute 3 图片/视频格式转换工具,类似于格式工厂 HandBrake, Omni Converter, Video Converter X2 Pixea 图片查看器 Viso, Picsee Pixelmator Pro 图片编辑器,80% 平替 PhotoShop Adobe PhotoShop, Darkroom, Photomator, Capture One, Adobe LightRoom Classic PopClip 划词增强 Proxyman 大概是舒服的抓包工具,略贵 Charles Rectangle 分屏软件 Magnet, Swish Swish 触控板手势增强 Stats Menubar 状态监控 iStats Menu, Sensei Subscriptions 订阅管理 Pandora on iOS Surge 代理工具 Clash X, Stash TinyPNG 图片压缩 OpenImageOptim Typora Markdown 文本编辑器 Obsidian Upscayl AI 图片超分 AI Photo Enhancer by Pictura, Pixelmator Pro Viso 6 图片查看器 Pixea, Xee Zotero 文献管理,就是界面一般 coconutBattery iPhone/iPad/Mac 电池信息查看 iRightMenu 右键增强 超级右键, iMouse, iTerm2 终端模拟器 Alacritty, Warp, Wezterm, Terminal 详细信息 AIDente 介绍:可以限制充电上限,据称电池电量维持在 70-80% 是比较健康的,不适宜过高。...

              December 3, 2023 · 2 min · zzsqwq

              My App Defaults - 2023 Fall

              After seeing Duel of the Defaults and App Defaults, I’d like to share here some of my app defaults at the end of 2023. +速览表 App 名称 简短描述 功能限制 订阅形式 价格 购入时间 购入渠道 同类型产品 AIDente 电池电量管理 有免费使用功能,但有共功能需要收费 买断 Free Battery, BatFi AdGuard 广告拦截软件 AltTab 增强 macOS App 切换 Command-Tab Plus, Contexts,HyperSwitch, Bartender 5 Menubar 管理 Bob 大概是最好用翻译软件 EasyDict BuhoCleaner 垃圾清理器/软件卸载器 CleanMyMac, Sensei Clash X / Clash X Pro 代理 Surge, Stash CleanBuddy 键盘锁定清理 Cleaner CleanShot X 大概最好用的截图软件 Cleaner 键盘屏幕锁定清理 CleanBuddy Dash 文档利器 Dato Menubar 日历软件 Fantastical, Itsycal DevUtils 开发小工具合集 Downie 4 各类视频下载器 VDown HapiGo 启动器 Alfred, Raycast HazeOver 生产力工具,突出重点 Hazel 自动清理集合 JetBrains 全家桶 包含 Clion/IDEA 等 VSCode, Eclipse Lunar 显示器管理 MonitorControl, DisplayBuddy, Better Display Maccy 开源免费的剪切板管理工具 Paste, PasteNow, PastePal Manico 快速启动器 Command-Tab Plus MimeStram Gmail 客户端 MonitorControl 开源显示器管理,很够用 Lunar, DisplayBuddy, Better Display NetNewsWire 全平台 RSS 阅读器 Obsidian 笔记软件 Omnivore 稍后读软件 Pocket, MarkMark, Only Switch 一键完成各种任务 One Switch OpenImageOptim 图片压缩 TinyPNG OrbStack 容器管理,平替 Docker Desktop Docker Desktop, Podman, lima, colima Permute 3 图片/视频格式转换工具,类似于格式工厂 HandBrake, Omni Converter, Video Converter X2 Pixea 图片查看器 Viso, Picsee Pixelmator Pro 图片编辑器,80% 平替 PhotoShop Adobe PhotoShop, Darkroom, Photomator, Capture One, Adobe LightRoom Classic PopClip 划词增强 Proxyman 大概是舒服的抓包工具,略贵 Charles Rectangle 分屏软件 Magnet, Swish Swish 触控板手势增强 Stats Menubar 状态监控 iStats Menu, Sensei Subscriptions 订阅管理 Pandora on iOS Surge 代理工具 Clash X, Stash TinyPNG 图片压缩 OpenImageOptim Typora Markdown 文本编辑器 Obsidian Upscayl AI 图片超分 AI Photo Enhancer by Pictura, Pixelmator Pro Viso 6 图片查看器 Pixea, Xee Zotero 文献管理,就是界面一般 coconutBattery iPhone/iPad/Mac 电池信息查看 iRightMenu 右键增强 超级右键, iMouse, iTerm2 终端模拟器 Alacritty, Warp, Wezterm, Terminal 详细信息 AIDente 介绍:可以限制充电上限,据称电池电量维持在 70-80% 是比较健康的,不适宜过高。 +...

              December 3, 2023 · 2 min · zzsqwq

              My App Defaults - 2023 Fall

              After seeing Duel of the Defaults and App Defaults, I’d like to share here some of my app defaults at the end of 2023. Since I am from China, some apps may not be suitable to everyone, such as WeChat, NeteaseMusic, etc. The software built-in on iPhone or Mac will have the .app extension. -📨 Mail Client:Gmail, Mail.app 📮 Mail Server:Gmail 📝 Notes:Obsidian, Typora, Notes.app ✅ To-Do:Reminders.app 📷 iPhone Photo Shooting: Camera....

              December 3, 2023 · 1 min · zzsqwq

              记一次 GitHub 账号突然被 suspended 的经历

              TL;DR 我在 2023.11.07 凌晨被 GitHub 封禁了账号,GitHub 账号被 suspended 后会在 GitHub 上完全除名(只有自建创建的组织不会消失)。 +📨 Mail Client:Gmail, Mail.app 📮 Mail Server:Gmail 📝 Notes:Obsidian, Typora, Notes.app ✅ To-Do:Reminders.app 📷 iPhone Photo Shooting: Camera.app 📸 Photo Shooting: Nikon ZFC, iPhone 13 🟦 Photo Management & Editing: Photos.app, Capture One, Pixelmator Pro 📆 Calendar: Dato, Calendar.app 📁 Cloud File Storage: iCloud Drive 📖 RSS Client: NetNewsWire 📖 RSS Server: FreshRSS with RSSHub 🙍🏻‍♂️ Contacts: Contacts.app 🌐 Browser: Microsoft Edge 💬 Chat: Telegram, WeChat(Not recommended, unless absolutely necessary.), iMeesage.app? 🔖 Bookmarks: Microsoft Edge 📑 Read It Later: Omnivore 📜 Word Processing: Lark Docs, Microsoft 365 📈 Spreadsheets: N/A 📊 Presentations: Microsoft PowerPoint 🛒 Shopping Lists: N/A 🍴 Meal Planning: N/A 💰 Budgeting and Personal Finance: iCost, Subscriptions 📰 News: Channels on Telegram, RSS, Web 🎵 Music: NeteaseMusic, Music.app 🎤 Podcasts: N/A 🔐 Password Management: iCloud Keychain 🧑‍💻 Code Editor: JetBrains Series, VS Code, Vim 🪄 Launcher: HapiGo 😘 Blog Platform: Hugo

              December 3, 2023 · 1 min · zzsqwq

              记一次 GitHub 账号突然被 suspended 的经历

              TL;DR 我在 2023.11.07 凌晨被 GitHub 封禁了账号,GitHub 账号被 suspended 后会在 GitHub 上完全除名(只有自建创建的组织不会消失)。 被封禁后我首先通过 Google 查找了相关的文章。 根据博主 @phith0n 的指引首先通过 API:https://api.github.com/users/[username]/starred 备份了自己 star 过的项目,同时通过 Can’t sign-in form 来在无法登陆的情况下发起 GitHub Support 工单来询问/请求解封/询问原因等,一般在两天内收到了回复。最终账号顺利恢复。 我此次被封禁的原因是由于管理的组织内部有成员被盗号,在组织内创建了违法仓库,因此管理员和被盗号的成员都被封禁了,但后续都被解除了封禁。同时也有可能因为创建违反 DMCA 条款 的仓库、fork 违反 DMCA 条款的仓库、贩卖学生/教师教育包等原因被封禁。 背景 大约在 2023.11.07 凌晨 00:30 左右,在 GitHub 上看到了一个不错的项目想要 Star,被提示没有登陆。当时我还在想:“怎么这次 session 过期的这么快?” 就当我边疑惑边重新登录后,突然收到了下图的提示我的账号「Account suspended」: 确认无法登录后,查看邮箱没有任何相关通知。同时我查看了其他内容是否还存在,最后综合表现如下: 没有任何邮件/信息通知被封禁及更加具体的封禁原因,只告诉违反了 ToS 个人页面(https://github.com/zzsqwq)无法访问,访问显示 404 提的相关 Issue 全部被删除(隐藏),无法找到 个人创建的所有项目,访问全部 404,也无法拉取 自己参与的项目,被除名 自己加入的组织,被除名 自己创建的组织,访问 404 简单说就是跟这个账号从来没存在过一样,除了仍可以登陆,但是显示 suspended。接下来开始尝试找办法恢复。 -恢复经过 试图查找封禁原因 首先看提示上显示违反了 Github Terms of Service,快速的看了一眼 ToS 没发现我有什么明显违规的地方。...

              November 12, 2023 · 4 min · zzsqwq

              为什么应该抵制拼多多?

              TL;DR 本文旨在结合一系列事实总结拼多多过去的一系列恶心行为,包括不限于 +恢复经过 试图查找封禁原因 首先看提示上显示违反了 Github Terms of Service,快速的看了一眼 ToS 没发现我有什么明显违规的地方。 +...

              November 12, 2023 · 4 min · zzsqwq

              为什么应该抵制拼多多?

              TL;DR 本文旨在结合一系列事实总结拼多多过去的一系列恶心行为,包括不限于 虚假宣传 砍一刀套路多 拉人助力 铺天盖地的广告 利用漏洞 希望大家抵制拼多多这种无良平台,非必要不使用拼多多。 前言 最近看了很多拼多多令人反感的操作以及看了很多拼多多的软广,如 拼多多,让谁不爽,看到这么一个无良平台逐渐壮大实在是令人恼火,因此我觉得有必要写一篇文章来总结一下拼多多各种恶心人的操作来让大家了解这个无良平台,来看看他到底为什么让人不爽,并呼吁大家可以联合抵制这个平台。 本文会尽量客观理性,陈述已发生的事实而不是自己的观点,同时因为我不是商家,也不是拼多多的员工,本文只是作为用户角度评判。除了对用户方面的恶心行为,还有对员工及商家的压榨,这个后面有时间再写。欢迎大家补充、批评、指正。 @@ -47,8 +48,9 @@ 据小桀自己回应,直到3月17号下午2点40分左右下播,也没有砍成功,但是突然在4点40分左右莫名其妙的成功了,赠送了一张无门槛购物券可以下单此手机,随后客服回应:砍价不成功不属实,已经发放「特制」优惠券。这一通操作,实在是闻所未闻,谁也能看出来是事态发展到不可预料的地步搞了个东西出来封口的。 实在是太像诈骗、传销了,即使这样广泛的虚假宣传,到现在也没有被整治,也还是随处可见。 附小桀对这件事情的声明: -三、拉人助力 拼多多最特色的行为,应该就是这个拉人助力,可能算是拉人助力的始祖了,如今算是各个软件的标配了,美团、饿了么、携程旅行、智行中也都随处可见。好处显而易见,可以提高自己活动的参与率、提高 App 的下载率、提高品牌知名度、提高用户粘性。...

              May 1, 2023 · 1 min · zzsqwq
              © 2024 Zs's Blog +三、拉人助力 拼多多最特色的行为,应该就是这个拉人助力,可能算是拉人助力的始祖了,如今算是各个软件的标配了,美团、饿了么、携程旅行、智行中也都随处可见。好处显而易见,可以提高自己活动的参与率、提高 App 的下载率、提高品牌知名度、提高用户粘性。 +...

              May 1, 2023 · 1 min · zzsqwq
              + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/posts/index.xml b/posts/index.xml index 501a8eed..af3a59bc 100644 --- a/posts/index.xml +++ b/posts/index.xml @@ -115,490 +115,490 @@ <p>由于软件可能较多,不能一次性写完。同时,因为我也在不断体验新的软件,有新的感受,因此这篇博客应该是持续更新的,欢迎常来看看。</p> <h2 id="速览表">速览表</h2> <table> -<thead> -<tr> -<th>App 名称</th> -<th>简短描述</th> -<th>功能限制</th> -<th>订阅形式</th> -<th>价格</th> -<th>购入时间</th> -<th>购入渠道</th> -<th>同类型产品</th> -</tr> -</thead> -<tbody> -<tr> -<td>AIDente</td> -<td>电池电量管理</td> -<td>有免费使用功能,但有共功能需要收费</td> -<td>买断</td> -<td>Free</td> -<td></td> -<td></td> -<td>Battery, BatFi</td> -</tr> -<tr> -<td>AdGuard</td> -<td>广告拦截软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>AltTab</td> -<td>增强 macOS App 切换</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Command-Tab Plus, Contexts,HyperSwitch,</td> -</tr> -<tr> -<td>Bartender 5</td> -<td>Menubar 管理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Bob</td> -<td>大概是最好用翻译软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>EasyDict</td> -</tr> -<tr> -<td>BuhoCleaner</td> -<td>垃圾清理器/软件卸载器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>CleanMyMac, Sensei</td> -</tr> -<tr> -<td>Clash X / Clash X Pro</td> -<td>代理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Surge, Stash</td> -</tr> -<tr> -<td>CleanBuddy</td> -<td>键盘锁定清理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Cleaner</td> -</tr> -<tr> -<td>CleanShot X</td> -<td>大概最好用的截图软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Cleaner</td> -<td>键盘屏幕锁定清理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>CleanBuddy</td> -</tr> -<tr> -<td>Dash</td> -<td>文档利器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Dato</td> -<td>Menubar 日历软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Fantastical, Itsycal</td> -</tr> -<tr> -<td>DevUtils</td> -<td>开发小工具合集</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Downie 4</td> -<td>各类视频下载器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>VDown</td> -</tr> -<tr> -<td>HapiGo</td> -<td>启动器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Alfred, Raycast</td> -</tr> -<tr> -<td>HazeOver</td> -<td>生产力工具,突出重点</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Hazel</td> -<td>自动清理集合</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>JetBrains 全家桶</td> -<td>包含 Clion/IDEA 等</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>VSCode, Eclipse</td> -</tr> -<tr> -<td>Lunar</td> -<td>显示器管理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>MonitorControl, DisplayBuddy, Better Display</td> -</tr> -<tr> -<td>Maccy</td> -<td>开源免费的剪切板管理工具</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Paste, PasteNow, PastePal</td> -</tr> -<tr> -<td>Manico</td> -<td>快速启动器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Command-Tab Plus</td> -</tr> -<tr> -<td>MimeStram</td> -<td>Gmail 客户端</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>MonitorControl</td> -<td>开源显示器管理,很够用</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Lunar, DisplayBuddy, Better Display</td> -</tr> -<tr> -<td>NetNewsWire</td> -<td>全平台 RSS 阅读器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Obsidian</td> -<td>笔记软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Omnivore</td> -<td>稍后读软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Pocket, MarkMark,</td> -</tr> -<tr> -<td>Only Switch</td> -<td>一键完成各种任务</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>One Switch</td> -</tr> -<tr> -<td>OpenImageOptim</td> -<td>图片压缩</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>TinyPNG</td> -</tr> -<tr> -<td>OrbStack</td> -<td>容器管理,平替 Docker Desktop</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Docker Desktop, Podman, lima, colima</td> -</tr> -<tr> -<td>Permute 3</td> -<td>图片/视频格式转换工具,类似于格式工厂</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>HandBrake, Omni Converter, Video Converter X2</td> -</tr> -<tr> -<td>Pixea</td> -<td>图片查看器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Viso, Picsee</td> -</tr> -<tr> -<td>Pixelmator Pro</td> -<td>图片编辑器,80% 平替 PhotoShop</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Adobe PhotoShop, Darkroom, Photomator, Capture One, Adobe LightRoom Classic</td> -</tr> -<tr> -<td>PopClip</td> -<td>划词增强</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Proxyman</td> -<td>大概是舒服的抓包工具,略贵</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Charles</td> -</tr> -<tr> -<td>Rectangle</td> -<td>分屏软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Magnet, Swish</td> -</tr> -<tr> -<td>Swish</td> -<td>触控板手势增强</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Stats</td> -<td>Menubar 状态监控</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>iStats Menu, Sensei</td> -</tr> -<tr> -<td>Subscriptions</td> -<td>订阅管理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Pandora on iOS</td> -</tr> -<tr> -<td>Surge</td> -<td>代理工具</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Clash X, Stash</td> -</tr> -<tr> -<td>TinyPNG</td> -<td>图片压缩</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>OpenImageOptim</td> -</tr> -<tr> -<td>Typora</td> -<td>Markdown 文本编辑器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Obsidian</td> -</tr> -<tr> -<td>Upscayl</td> -<td>AI 图片超分</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>AI Photo Enhancer by Pictura, Pixelmator Pro</td> -</tr> -<tr> -<td>Viso 6</td> -<td>图片查看器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Pixea, Xee</td> -</tr> -<tr> -<td>Zotero</td> -<td>文献管理,就是界面一般</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>coconutBattery</td> -<td>iPhone/iPad/Mac 电池信息查看</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>iRightMenu</td> -<td>右键增强</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>超级右键, iMouse,</td> -</tr> -<tr> -<td>iTerm2</td> -<td>终端模拟器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Alacritty, Warp, Wezterm, Terminal</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">App 名称</th> + <th style="text-align: left">简短描述</th> + <th style="text-align: left">功能限制</th> + <th style="text-align: left">订阅形式</th> + <th style="text-align: left">价格</th> + <th style="text-align: left">购入时间</th> + <th style="text-align: left">购入渠道</th> + <th style="text-align: left">同类型产品</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">AIDente</td> + <td style="text-align: left">电池电量管理</td> + <td style="text-align: left">有免费使用功能,但有共功能需要收费</td> + <td style="text-align: left">买断</td> + <td style="text-align: left">Free</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Battery, BatFi</td> + </tr> + <tr> + <td style="text-align: left">AdGuard</td> + <td style="text-align: left">广告拦截软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">AltTab</td> + <td style="text-align: left">增强 macOS App 切换</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Command-Tab Plus, Contexts,HyperSwitch,</td> + </tr> + <tr> + <td style="text-align: left">Bartender 5</td> + <td style="text-align: left">Menubar 管理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Bob</td> + <td style="text-align: left">大概是最好用翻译软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">EasyDict</td> + </tr> + <tr> + <td style="text-align: left">BuhoCleaner</td> + <td style="text-align: left">垃圾清理器/软件卸载器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">CleanMyMac, Sensei</td> + </tr> + <tr> + <td style="text-align: left">Clash X / Clash X Pro</td> + <td style="text-align: left">代理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Surge, Stash</td> + </tr> + <tr> + <td style="text-align: left">CleanBuddy</td> + <td style="text-align: left">键盘锁定清理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Cleaner</td> + </tr> + <tr> + <td style="text-align: left">CleanShot X</td> + <td style="text-align: left">大概最好用的截图软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Cleaner</td> + <td style="text-align: left">键盘屏幕锁定清理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">CleanBuddy</td> + </tr> + <tr> + <td style="text-align: left">Dash</td> + <td style="text-align: left">文档利器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Dato</td> + <td style="text-align: left">Menubar 日历软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Fantastical, Itsycal</td> + </tr> + <tr> + <td style="text-align: left">DevUtils</td> + <td style="text-align: left">开发小工具合集</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Downie 4</td> + <td style="text-align: left">各类视频下载器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">VDown</td> + </tr> + <tr> + <td style="text-align: left">HapiGo</td> + <td style="text-align: left">启动器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Alfred, Raycast</td> + </tr> + <tr> + <td style="text-align: left">HazeOver</td> + <td style="text-align: left">生产力工具,突出重点</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Hazel</td> + <td style="text-align: left">自动清理集合</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">JetBrains 全家桶</td> + <td style="text-align: left">包含 Clion/IDEA 等</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">VSCode, Eclipse</td> + </tr> + <tr> + <td style="text-align: left">Lunar</td> + <td style="text-align: left">显示器管理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">MonitorControl, DisplayBuddy, Better Display</td> + </tr> + <tr> + <td style="text-align: left">Maccy</td> + <td style="text-align: left">开源免费的剪切板管理工具</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Paste, PasteNow, PastePal</td> + </tr> + <tr> + <td style="text-align: left">Manico</td> + <td style="text-align: left">快速启动器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Command-Tab Plus</td> + </tr> + <tr> + <td style="text-align: left">MimeStram</td> + <td style="text-align: left">Gmail 客户端</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">MonitorControl</td> + <td style="text-align: left">开源显示器管理,很够用</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Lunar, DisplayBuddy, Better Display</td> + </tr> + <tr> + <td style="text-align: left">NetNewsWire</td> + <td style="text-align: left">全平台 RSS 阅读器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Obsidian</td> + <td style="text-align: left">笔记软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Omnivore</td> + <td style="text-align: left">稍后读软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Pocket, MarkMark,</td> + </tr> + <tr> + <td style="text-align: left">Only Switch</td> + <td style="text-align: left">一键完成各种任务</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">One Switch</td> + </tr> + <tr> + <td style="text-align: left">OpenImageOptim</td> + <td style="text-align: left">图片压缩</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">TinyPNG</td> + </tr> + <tr> + <td style="text-align: left">OrbStack</td> + <td style="text-align: left">容器管理,平替 Docker Desktop</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Docker Desktop, Podman, lima, colima</td> + </tr> + <tr> + <td style="text-align: left">Permute 3</td> + <td style="text-align: left">图片/视频格式转换工具,类似于格式工厂</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">HandBrake, Omni Converter, Video Converter X2</td> + </tr> + <tr> + <td style="text-align: left">Pixea</td> + <td style="text-align: left">图片查看器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Viso, Picsee</td> + </tr> + <tr> + <td style="text-align: left">Pixelmator Pro</td> + <td style="text-align: left">图片编辑器,80% 平替 PhotoShop</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Adobe PhotoShop, Darkroom, Photomator, Capture One, Adobe LightRoom Classic</td> + </tr> + <tr> + <td style="text-align: left">PopClip</td> + <td style="text-align: left">划词增强</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Proxyman</td> + <td style="text-align: left">大概是舒服的抓包工具,略贵</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Charles</td> + </tr> + <tr> + <td style="text-align: left">Rectangle</td> + <td style="text-align: left">分屏软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Magnet, Swish</td> + </tr> + <tr> + <td style="text-align: left">Swish</td> + <td style="text-align: left">触控板手势增强</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Stats</td> + <td style="text-align: left">Menubar 状态监控</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">iStats Menu, Sensei</td> + </tr> + <tr> + <td style="text-align: left">Subscriptions</td> + <td style="text-align: left">订阅管理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Pandora on iOS</td> + </tr> + <tr> + <td style="text-align: left">Surge</td> + <td style="text-align: left">代理工具</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Clash X, Stash</td> + </tr> + <tr> + <td style="text-align: left">TinyPNG</td> + <td style="text-align: left">图片压缩</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">OpenImageOptim</td> + </tr> + <tr> + <td style="text-align: left">Typora</td> + <td style="text-align: left">Markdown 文本编辑器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Obsidian</td> + </tr> + <tr> + <td style="text-align: left">Upscayl</td> + <td style="text-align: left">AI 图片超分</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">AI Photo Enhancer by Pictura, Pixelmator Pro</td> + </tr> + <tr> + <td style="text-align: left">Viso 6</td> + <td style="text-align: left">图片查看器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Pixea, Xee</td> + </tr> + <tr> + <td style="text-align: left">Zotero</td> + <td style="text-align: left">文献管理,就是界面一般</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">coconutBattery</td> + <td style="text-align: left">iPhone/iPad/Mac 电池信息查看</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">iRightMenu</td> + <td style="text-align: left">右键增强</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">超级右键, iMouse,</td> + </tr> + <tr> + <td style="text-align: left">iTerm2</td> + <td style="text-align: left">终端模拟器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Alacritty, Warp, Wezterm, Terminal</td> + </tr> + </tbody> </table> <h2 id="详细信息">详细信息</h2> <h3 id="aidente">AIDente</h3> @@ -2989,70 +2989,70 @@ Changes not staged for commit: <p>波士顿住房数据由哈里森和鲁宾菲尔德于1978年Harrison and Rubinfeld<sup><a href="https://blog.zzsqwq.cn/usr/uploads/2021/05/406125417.png">1</a></sup>收集。它包括了波士顿大区每个调查行政区的506个观察值。1980年Belsley et al.<sup><a href="https://blog.zzsqwq.cn/usr/uploads/2021/05/3238192089.png">2</a></sup>曾对此数据做过分析。</p> <p>数据一共14列,每一列的含义分别如下:</p> <table> -<thead> -<tr> -<th>英文简称</th> -<th>详细含义</th> -</tr> -</thead> -<tbody> -<tr> -<td>CRIM</td> -<td>城镇的人均犯罪率</td> -</tr> -<tr> -<td>ZN</td> -<td>大于25,000平方英尺的地块的住宅用地比例。</td> -</tr> -<tr> -<td>INDUS</td> -<td>每个镇的非零售业务英亩的比例。</td> -</tr> -<tr> -<td>CHAS</td> -<td>查尔斯河虚拟变量(如果环河,则等于1;否则等于0)</td> -</tr> -<tr> -<td>NOX</td> -<td>一氧化氮的浓度(百万分之几)</td> -</tr> -<tr> -<td>RM</td> -<td>每个住宅的平均房间数</td> -</tr> -<tr> -<td>AGE</td> -<td>1940年之前建造的自有住房的比例</td> -</tr> -<tr> -<td>DIS</td> -<td>到五个波士顿就业中心的加权距离</td> -</tr> -<tr> -<td>RAD</td> -<td>径向公路通达性的指标</td> -</tr> -<tr> -<td>TAX</td> -<td>每一万美元的全值财产税率</td> -</tr> -<tr> -<td>PTRATIO</td> -<td>各镇的师生比率</td> -</tr> -<tr> -<td>B</td> -<td>计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例</td> -</tr> -<tr> -<td>LSTAT</td> -<td>底层人口的百分比(%)</td> -</tr> -<tr> -<td><strong>price</strong></td> -<td>自有住房数的中位数,单位(千美元)</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">英文简称</th> + <th style="text-align: left">详细含义</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">CRIM</td> + <td style="text-align: left">城镇的人均犯罪率</td> + </tr> + <tr> + <td style="text-align: left">ZN</td> + <td style="text-align: left">大于25,000平方英尺的地块的住宅用地比例。</td> + </tr> + <tr> + <td style="text-align: left">INDUS</td> + <td style="text-align: left">每个镇的非零售业务英亩的比例。</td> + </tr> + <tr> + <td style="text-align: left">CHAS</td> + <td style="text-align: left">查尔斯河虚拟变量(如果环河,则等于1;否则等于0)</td> + </tr> + <tr> + <td style="text-align: left">NOX</td> + <td style="text-align: left">一氧化氮的浓度(百万分之几)</td> + </tr> + <tr> + <td style="text-align: left">RM</td> + <td style="text-align: left">每个住宅的平均房间数</td> + </tr> + <tr> + <td style="text-align: left">AGE</td> + <td style="text-align: left">1940年之前建造的自有住房的比例</td> + </tr> + <tr> + <td style="text-align: left">DIS</td> + <td style="text-align: left">到五个波士顿就业中心的加权距离</td> + </tr> + <tr> + <td style="text-align: left">RAD</td> + <td style="text-align: left">径向公路通达性的指标</td> + </tr> + <tr> + <td style="text-align: left">TAX</td> + <td style="text-align: left">每一万美元的全值财产税率</td> + </tr> + <tr> + <td style="text-align: left">PTRATIO</td> + <td style="text-align: left">各镇的师生比率</td> + </tr> + <tr> + <td style="text-align: left">B</td> + <td style="text-align: left">计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例</td> + </tr> + <tr> + <td style="text-align: left">LSTAT</td> + <td style="text-align: left">底层人口的百分比(%)</td> + </tr> + <tr> + <td style="text-align: left"><strong>price</strong></td> + <td style="text-align: left">自有住房数的中位数,单位(千美元)</td> + </tr> + </tbody> </table> <p>基于上述数据,请完成以下问题:</p> <p><strong>建立波士顿房价预测模型并对预测结果进行评价。</strong></p> @@ -3077,46 +3077,46 @@ $$ 其中 $x_i,y_i$ 为数据的每个分量,$\bar{x},\bar{y}$ 为数据的均值</p> <p>该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下:</p> <table> -<thead> -<tr> -<th>CRIM</th> -<th>ZN</th> -<th>INDUS</th> -<th>CHAS</th> -<th>NOX</th> -<th>RM</th> -<th>LSTAT</th> -</tr> -</thead> -<tbody> -<tr> -<td>-0.385832</td> -<td>0.360445</td> -<td>-0.483725</td> -<td>0.175260</td> -<td>-0.427321</td> -<td>0.695360</td> -<td>-0.737663</td> -</tr> -<tr> -<td><strong>AGE</strong></td> -<td><strong>DIS</strong></td> -<td><strong>RAD</strong></td> -<td><strong>TAX</strong></td> -<td><strong>PTRATIO</strong></td> -<td><strong>B</strong></td> -<td></td> -</tr> -<tr> -<td>-0.376955</td> -<td>0.249929</td> -<td>-0.381626</td> -<td>-0.468536</td> -<td>-0.507787</td> -<td>0.333461</td> -<td></td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">CRIM</th> + <th style="text-align: left">ZN</th> + <th style="text-align: left">INDUS</th> + <th style="text-align: left">CHAS</th> + <th style="text-align: left">NOX</th> + <th style="text-align: left">RM</th> + <th style="text-align: left">LSTAT</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">-0.385832</td> + <td style="text-align: left">0.360445</td> + <td style="text-align: left">-0.483725</td> + <td style="text-align: left">0.175260</td> + <td style="text-align: left">-0.427321</td> + <td style="text-align: left">0.695360</td> + <td style="text-align: left">-0.737663</td> + </tr> + <tr> + <td style="text-align: left"><strong>AGE</strong></td> + <td style="text-align: left"><strong>DIS</strong></td> + <td style="text-align: left"><strong>RAD</strong></td> + <td style="text-align: left"><strong>TAX</strong></td> + <td style="text-align: left"><strong>PTRATIO</strong></td> + <td style="text-align: left"><strong>B</strong></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">-0.376955</td> + <td style="text-align: left">0.249929</td> + <td style="text-align: left">-0.381626</td> + <td style="text-align: left">-0.468536</td> + <td style="text-align: left">-0.507787</td> + <td style="text-align: left">0.333461</td> + <td style="text-align: left"></td> + </tr> + </tbody> </table> <p>观察结果可以发现,在给定的十三个变量中,<strong>LSTAT <strong>与 <strong>price</strong> 的相关程度最高$(|r|&gt;0.7)$,其次是 <strong>RM</strong> 与</strong>PTRATIO</strong> $(|r|&gt;0.5)$,再者是 <strong>TAX,INDUS,NOX</strong> $(|r|&gt;0.4)$,除上述之外的七个变量都与 <strong>price</strong> 无较强的相关性,因此我们考虑使用六个相关性较强变量和十三个变量分别来对房价进行预测,并对他们进行对比,来寻找最优的回归模型。</p> <h5 id="模型的构建">模型的构建</h5> @@ -5907,34 +5907,34 @@ $$</p> <p><strong>tar</strong> 命令:压缩或解压命令。<code>tar [参数] 打包文件名 要打包的各个文件 </code> 。</p> <p>参数表:</p> <table> -<thead> -<tr> -<th>参数</th> -<th>含义</th> -</tr> -</thead> -<tbody> -<tr> -<td>-c</td> -<td>生成档案文件,创建打包文件</td> -</tr> -<tr> -<td>-v</td> -<td>列出归档解档的详细过程,显示进度</td> -</tr> -<tr> -<td>-f</td> -<td>指定档案文件名称,f后面一定是.tar文件,所以放选项最后</td> -</tr> -<tr> -<td>-t</td> -<td>列出档案中包含的文件</td> -</tr> -<tr> -<td>-x</td> -<td>解开档案文件</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">参数</th> + <th style="text-align: left">含义</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">-c</td> + <td style="text-align: left">生成档案文件,创建打包文件</td> + </tr> + <tr> + <td style="text-align: left">-v</td> + <td style="text-align: left">列出归档解档的详细过程,显示进度</td> + </tr> + <tr> + <td style="text-align: left">-f</td> + <td style="text-align: left">指定档案文件名称,f后面一定是.tar文件,所以放选项最后</td> + </tr> + <tr> + <td style="text-align: left">-t</td> + <td style="text-align: left">列出档案中包含的文件</td> + </tr> + <tr> + <td style="text-align: left">-x</td> + <td style="text-align: left">解开档案文件</td> + </tr> + </tbody> </table> <p>打包实例: <code>tar -cvf 文件名 要打包的文件</code> 解压实例:<code>tar -xvf 压缩包名</code></p> </li> @@ -9042,46 +9042,46 @@ QAQ刷了这么多天的dp好像终于有点作用了,我终于看出来这是 <p>顾名思义,他就是一个单调的队列,那么我们可以规定他是单调递增的还是单调递减的,他和普通的队列有点区别,队列一般是尾进头出,而单调队列要实现的话要确保头和尾都可以出,尾可以进。如果要用STL库的话可以用里面的双端队列。 跟普通队列相比他的进队需要确保一个条件就是要<strong>不破坏原有序列的单调性</strong>,好比我们有一个单调递增的单调队列,也就是从队首到队尾是单调递增的,那么有一段序列是 $[2,3,1,5,8,7,4,2]$ ,我们从左到右依次入队。</p> <table> -<thead> -<tr> -<th>队列中元素</th> -<th>关于元素进出的备注</th> -</tr> -</thead> -<tbody> -<tr> -<td>2</td> -<td>2入队</td> -</tr> -<tr> -<td>2,3</td> -<td>3比2大,可以满足递增性质,入队</td> -</tr> -<tr> -<td>1</td> -<td>因为1比2,3都小,要满足递增性质,先把2,3出队,再将1入队</td> -</tr> -<tr> -<td>1,5</td> -<td>5比1大,可以满足递增性质,入队</td> -</tr> -<tr> -<td>1,5,8</td> -<td>8比5大,可以满足递增性质,入队</td> -</tr> -<tr> -<td>1,5,7</td> -<td>7小于8,大于5,要满足递增性质,我们把8出队,然后将7入队</td> -</tr> -<tr> -<td>1,4</td> -<td>4小于5、7,但是大于1,因此7,5依次出队,4入队</td> -</tr> -<tr> -<td>1,2</td> -<td>2小于4,大于1,因此4出队,2入队</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">队列中元素</th> + <th style="text-align: left">关于元素进出的备注</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">2</td> + <td style="text-align: left">2入队</td> + </tr> + <tr> + <td style="text-align: left">2,3</td> + <td style="text-align: left">3比2大,可以满足递增性质,入队</td> + </tr> + <tr> + <td style="text-align: left">1</td> + <td style="text-align: left">因为1比2,3都小,要满足递增性质,先把2,3出队,再将1入队</td> + </tr> + <tr> + <td style="text-align: left">1,5</td> + <td style="text-align: left">5比1大,可以满足递增性质,入队</td> + </tr> + <tr> + <td style="text-align: left">1,5,8</td> + <td style="text-align: left">8比5大,可以满足递增性质,入队</td> + </tr> + <tr> + <td style="text-align: left">1,5,7</td> + <td style="text-align: left">7小于8,大于5,要满足递增性质,我们把8出队,然后将7入队</td> + </tr> + <tr> + <td style="text-align: left">1,4</td> + <td style="text-align: left">4小于5、7,但是大于1,因此7,5依次出队,4入队</td> + </tr> + <tr> + <td style="text-align: left">1,2</td> + <td style="text-align: left">2小于4,大于1,因此4出队,2入队</td> + </tr> + </tbody> </table> <p>根据上述例子不难看出,我们要入队的时候首先要确保队尾元素要比想要入队的元素小,然后才能入队,否则的话就一直循环让尾部元素出队,直到能够满足单调性为止。</p> <h2 id="单调队列的应用">单调队列的应用</h2> @@ -9219,38 +9219,38 @@ QAQ刷了这么多天的dp好像终于有点作用了,我终于看出来这是 <h2 id="理解-1">理解</h2> <p>单调栈也是在普通栈的基础上加了单调性,一般是用从栈底到栈顶的单调性来命名,好比从栈底到栈顶是单调递增的,那么他就是单调增的栈。跟单调队列一样,他的入栈规则也是<strong>要不破坏单调性</strong>,因此一个单调递增的栈如果有元素要入栈,如果他比栈顶的元素还要大,就可以直接入栈,如果他比栈顶的元素小,那么就要将栈顶的元素一直出栈到比要入栈元素小为止。如果序列为 $[2,3,1,5,4,7]$,要加入单调递增栈中,过程如下。<strong>PS:注意从左到右对应栈底到栈顶。</strong></p> <table> -<thead> -<tr> -<th>栈中的元素</th> -<th>关于元素进出的备注</th> -</tr> -</thead> -<tbody> -<tr> -<td>2</td> -<td>元素2压入栈中</td> -</tr> -<tr> -<td>2,3</td> -<td>3大于2,压入栈中</td> -</tr> -<tr> -<td>1</td> -<td>1小于3、2,因此全部弹出将1入栈</td> -</tr> -<tr> -<td>1,5</td> -<td>5大于1,压入栈中</td> -</tr> -<tr> -<td>1,4</td> -<td>4比5小,比1大,弹出5,压入4</td> -</tr> -<tr> -<td>1,4,7</td> -<td>7大于4,压入栈中</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">栈中的元素</th> + <th style="text-align: left">关于元素进出的备注</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">2</td> + <td style="text-align: left">元素2压入栈中</td> + </tr> + <tr> + <td style="text-align: left">2,3</td> + <td style="text-align: left">3大于2,压入栈中</td> + </tr> + <tr> + <td style="text-align: left">1</td> + <td style="text-align: left">1小于3、2,因此全部弹出将1入栈</td> + </tr> + <tr> + <td style="text-align: left">1,5</td> + <td style="text-align: left">5大于1,压入栈中</td> + </tr> + <tr> + <td style="text-align: left">1,4</td> + <td style="text-align: left">4比5小,比1大,弹出5,压入4</td> + </tr> + <tr> + <td style="text-align: left">1,4,7</td> + <td style="text-align: left">7大于4,压入栈中</td> + </tr> + </tbody> </table> <p>根据上述描述不难看出,其实单调栈就是单调队列的半部分,他能完成的任务理论上单调队列都能够完成,但是有些时候不需要麻烦的去维护单调队列只需要维护单调栈即可完成。</p> <h2 id="单调栈的应用">单调栈的应用</h2> @@ -10164,58 +10164,58 @@ $$ <li>碱基配对时相似度的定义如下</li> </ul> <table> -<thead> -<tr> -<th style="text-align:center"></th> -<th style="text-align:center">A</th> -<th style="text-align:center">C</th> -<th style="text-align:center">G</th> -<th style="text-align:center">T</th> -<th style="text-align:center">空</th> -</tr> -</thead> -<tbody> -<tr> -<td style="text-align:center">A</td> -<td style="text-align:center">5</td> -<td style="text-align:center">-1</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-1</td> -<td style="text-align:center">-3</td> -</tr> -<tr> -<td style="text-align:center">C</td> -<td style="text-align:center">-1</td> -<td style="text-align:center">5</td> -<td style="text-align:center">-3</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-4</td> -</tr> -<tr> -<td style="text-align:center">G</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-3</td> -<td style="text-align:center">5</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-2</td> -</tr> -<tr> -<td style="text-align:center">T</td> -<td style="text-align:center">-1</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">5</td> -<td style="text-align:center">-1</td> -</tr> -<tr> -<td style="text-align:center">空</td> -<td style="text-align:center">-3</td> -<td style="text-align:center">-4</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-1</td> -<td style="text-align:center">非法</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: center"></th> + <th style="text-align: center">A</th> + <th style="text-align: center">C</th> + <th style="text-align: center">G</th> + <th style="text-align: center">T</th> + <th style="text-align: center">空</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: center">A</td> + <td style="text-align: center">5</td> + <td style="text-align: center">-1</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-1</td> + <td style="text-align: center">-3</td> + </tr> + <tr> + <td style="text-align: center">C</td> + <td style="text-align: center">-1</td> + <td style="text-align: center">5</td> + <td style="text-align: center">-3</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-4</td> + </tr> + <tr> + <td style="text-align: center">G</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-3</td> + <td style="text-align: center">5</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-2</td> + </tr> + <tr> + <td style="text-align: center">T</td> + <td style="text-align: center">-1</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">5</td> + <td style="text-align: center">-1</td> + </tr> + <tr> + <td style="text-align: center">空</td> + <td style="text-align: center">-3</td> + <td style="text-align: center">-4</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-1</td> + <td style="text-align: center">非法</td> + </tr> + </tbody> </table> <hr> <h4 id="思路-2">思路</h4> diff --git a/posts/macos-app-use-experience-record/index.html b/posts/macos-app-use-experience-record/index.html index 90fb0b1d..7eccc805 100644 --- a/posts/macos-app-use-experience-record/index.html +++ b/posts/macos-app-use-experience-record/index.html @@ -1,13 +1,1486 @@ App 使用体会记录 - macOS 篇 | Zs's Blog

              App 使用体会记录 - macOS 篇

              平时很喜欢倒腾各种 Apple 平台的各种软件,所以体验了很多 iOS/iPadOS/macOS 上的软件,所以计划汇总一下自己的一些简短的使用体验和评价等,希望能在大家后续选择软件的时候起到一些参考和帮助。

              由于软件可能较多,不能一次性写完。同时,因为我也在不断体验新的软件,有新的感受,因此这篇博客应该是持续更新的,欢迎常来看看。

              速览表

              App 名称简短描述功能限制订阅形式价格购入时间购入渠道同类型产品
              AIDente电池电量管理有免费使用功能,但有共功能需要收费买断FreeBattery, BatFi
              AdGuard广告拦截软件
              AltTab增强 macOS App 切换Command-Tab Plus, Contexts,HyperSwitch,
              Bartender 5Menubar 管理
              Bob大概是最好用翻译软件EasyDict
              BuhoCleaner垃圾清理器/软件卸载器CleanMyMac, Sensei
              Clash X / Clash X Pro代理Surge, Stash
              CleanBuddy键盘锁定清理Cleaner
              CleanShot X大概最好用的截图软件
              Cleaner键盘屏幕锁定清理CleanBuddy
              Dash文档利器
              DatoMenubar 日历软件Fantastical, Itsycal
              DevUtils开发小工具合集
              Downie 4各类视频下载器VDown
              HapiGo启动器Alfred, Raycast
              HazeOver生产力工具,突出重点
              Hazel自动清理集合
              JetBrains 全家桶包含 Clion/IDEA 等VSCode, Eclipse
              Lunar显示器管理MonitorControl, DisplayBuddy, Better Display
              Maccy开源免费的剪切板管理工具Paste, PasteNow, PastePal
              Manico快速启动器Command-Tab Plus
              MimeStramGmail 客户端
              MonitorControl开源显示器管理,很够用Lunar, DisplayBuddy, Better Display
              NetNewsWire全平台 RSS 阅读器
              Obsidian笔记软件
              Omnivore稍后读软件Pocket, MarkMark,
              Only Switch一键完成各种任务One Switch
              OpenImageOptim图片压缩TinyPNG
              OrbStack容器管理,平替 Docker DesktopDocker Desktop, Podman, lima, colima
              Permute 3图片/视频格式转换工具,类似于格式工厂HandBrake, Omni Converter, Video Converter X2
              Pixea图片查看器Viso, Picsee
              Pixelmator Pro图片编辑器,80% 平替 PhotoShopAdobe PhotoShop, Darkroom, Photomator, Capture One, Adobe LightRoom Classic
              PopClip划词增强
              Proxyman大概是舒服的抓包工具,略贵Charles
              Rectangle分屏软件Magnet, Swish
              Swish触控板手势增强
              StatsMenubar 状态监控iStats Menu, Sensei
              Subscriptions订阅管理Pandora on iOS
              Surge代理工具Clash X, Stash
              TinyPNG图片压缩OpenImageOptim
              TyporaMarkdown 文本编辑器Obsidian
              UpscaylAI 图片超分AI Photo Enhancer by Pictura, Pixelmator Pro
              Viso 6图片查看器Pixea, Xee
              Zotero文献管理,就是界面一般
              coconutBatteryiPhone/iPad/Mac 电池信息查看
              iRightMenu右键增强超级右键, iMouse,
              iTerm2终端模拟器Alacritty, Warp, Wezterm, Terminal

              详细信息

              AIDente

              • 介绍:可以限制充电上限,据称电池电量维持在 70-80% 是比较健康的,不适宜过高。

              • 目前是否在用:是

              • 收费形式:139/3设备

              • 评价:好用,界面也挺好看的

              • 同类型产品:Battery, BatFi

              • 软件快照:

                Aldente-1

              TODO…

              \ No newline at end of file diff --git a/posts/my-hugo-academia-theme/index.html b/posts/my-hugo-academia-theme/index.html index f1e559d5..307902b5 100644 --- a/posts/my-hugo-academia-theme/index.html +++ b/posts/my-hugo-academia-theme/index.html @@ -1,52 +1,73 @@ 一个基于 Hugo 的个人主页主题 | Zs's Blog -

              一个基于 Hugo 的个人主页主题

              背景

              之前看到过学长学姐做过个人主页,多是用来申请一些学校的夏令营使用的,觉得非常的 Nice,自己也想搞一个。

              大家之前好像大多用的是基于 Hexo 的一个主题 — hexo-theme-academia,但是由于之前我用过 Hexo,觉得他有一些比较明显的弊端,例如环境配置比较麻烦、需要安装 Nodejs、npm 等环境,然后再安装 Hexo。其次它的构建速度比较慢,用起来感觉比较僵硬。

              后来随着了解增多,尝试了 Typecho、WordPress,Hugo 等主题后,目前还是决定使用 Hugo。它构建速度快,而且安装简单,在 Ubuntu 上只需要一行 sudo apt install hugo 即可,不可谓不简单。因此萌生了移植一个 Hugo 版本主题的想法,刚好可以锻炼一下自己。

              欢迎点击 这里 查看我的个人主页。

              一些难点

              之前从来没有了解过 Hugo 主题的写法以及 Hexo 主题的写法,不过看了一下仓库的组织形式还算好理解。

              这类静态博客生成器都是需要写一些模板文件,然后根据配置文件进行个性化构建。

              Hugo 的文档 十分的完善,学习就像是学习一门编程语言,里面有很多函数和变量,还有各种条件结构、循环结构等。原主题是采用的 pug + stylus 的方式,而不是传统的 html + css 。不过这两者之间的转换并不麻烦,而且有一些工具可以参考着转换,例如 pug2html 以及 stylus2css

              后续就参考着一点点的移植就可以,同时我也改写了一下配置文件(使用的 yaml 格式),大概是更易于配置了。

              同时,得益于 Hugo 的强大,我很方便的完成了对多语言的支持。

              最终效果

              目前已经更新到了 v1.1.0 版本,欢迎大家体验,有问题可以及时反馈!

              主题链接:https://github.com/zzsqwq/hugo-academia-theme

              演示站:https://zzsqwq.github.io/academic-pages-demo/

              英文文档:https://github.com/zzsqwq/hugo-academia-theme/blob/master/README.md

              中文文档:https://github.com/zzsqwq/hugo-academia-theme/blob/master/README.zh_cn.md

              英文效果图:

              demo-en

              中文效果图:

              demo-zh_cn

              \ No newline at end of file diff --git a/posts/orangepi4-lts-with-openwrt/index.html b/posts/orangepi4-lts-with-openwrt/index.html index 15dc2136..36ea8d5f 100644 --- a/posts/orangepi4-lts-with-openwrt/index.html +++ b/posts/orangepi4-lts-with-openwrt/index.html @@ -1,31 +1,46 @@ 使用 OrangePi 4 LTS 做旁路由 | Zs's Blog -

              使用 OrangePi 4 LTS 做旁路由

              前言

              最近同居的学长从香港带了个最新版的 Apple TV 回来,但是 Apple TV 在国内用不了,必须要代理才可以,所以考虑到了路由器代理的方案。但是现在家里在用的路由器是 Redmi AX3000,没法刷固件,也不想再买个 R2S 这种软路由了,因此就计划将公司之前用完的 香橙派(OrangePi) 4 LTS 利用一下。它的芯片是 RK3399,用来做路由器绰绰有余,不用可惜了。

              旁路由成品图

              为什么是旁路由?

              不熟悉旁路由的同学可以看篇指南:从听说到上手,人人都能看懂的旁路由入门指南


              找了一些常见的固件,貌似只有针对于 OrangePi R1 和 OrangePi R1 Plus 编译的软路由固件,并且讯龙官方也有放出针对这两个板子的 Openwrt 固件1,可以说是就是为软路由而生,价格也比较便宜,200 左右,性能和 R2S 差别不大。

              试了一下在 4 LTS 上跑 R1 和 R1 Plus 的固件2,都无法正常点亮,可能可以自己编译一个对应架构的 OpenWrt,但是有点麻烦,还是没尝试。

              考虑到 4 LTS 上可以使用 Docker,因此可以在上面用 Docker 跑一个 OpenWrt 然后做旁路由,到时候只需要把 Apple TV 或者路由器的网关和 DNS 改一下就可以,因此最终选择使用旁路由方案。

              具体方案

              这里直接参考了小苏的教程:https://mlapp.cn/376.html,写的很清晰,而且很好的考虑了没有基础的同学,赞一个!

              里面写的很详细,但是需要注意的是,因为香橙派4 LTS是 ARMv8 架构的,但是直接拉教程里面的默认 latest 镜像是 ARMv7 的,因此需要指定一下镜像的版本,具体的镜像版本可以看 Docker Hub 中的介绍

              docker pull registry.cn-shanghai.aliyuncs.com/suling/openwrt:armv8
              +具体方案
              +这里直接参考了小苏的教程:https://mlapp.cn/376.html,写的很清晰,而且很好的考虑了没有基础的同学,赞一个!
              +里面写的很详细,但是需要注意的是,因为香橙派4 LTS是 ARMv8 架构的,但是直接拉教程里面的默认 latest 镜像是 ARMv7 的,因此需要指定一下镜像的版本,具体的镜像版本可以看 Docker Hub 中的介绍。">

              使用 OrangePi 4 LTS 做旁路由

              前言

              最近同居的学长从香港带了个最新版的 Apple TV 回来,但是 Apple TV 在国内用不了,必须要代理才可以,所以考虑到了路由器代理的方案。但是现在家里在用的路由器是 Redmi AX3000,没法刷固件,也不想再买个 R2S 这种软路由了,因此就计划将公司之前用完的 香橙派(OrangePi) 4 LTS 利用一下。它的芯片是 RK3399,用来做路由器绰绰有余,不用可惜了。

              旁路由成品图

              为什么是旁路由?

              不熟悉旁路由的同学可以看篇指南:从听说到上手,人人都能看懂的旁路由入门指南


              找了一些常见的固件,貌似只有针对于 OrangePi R1 和 OrangePi R1 Plus 编译的软路由固件,并且讯龙官方也有放出针对这两个板子的 Openwrt 固件1,可以说是就是为软路由而生,价格也比较便宜,200 左右,性能和 R2S 差别不大。

              试了一下在 4 LTS 上跑 R1 和 R1 Plus 的固件2,都无法正常点亮,可能可以自己编译一个对应架构的 OpenWrt,但是有点麻烦,还是没尝试。

              考虑到 4 LTS 上可以使用 Docker,因此可以在上面用 Docker 跑一个 OpenWrt 然后做旁路由,到时候只需要把 Apple TV 或者路由器的网关和 DNS 改一下就可以,因此最终选择使用旁路由方案。

              具体方案

              这里直接参考了小苏的教程:https://mlapp.cn/376.html,写的很清晰,而且很好的考虑了没有基础的同学,赞一个!

              里面写的很详细,但是需要注意的是,因为香橙派4 LTS是 ARMv8 架构的,但是直接拉教程里面的默认 latest 镜像是 ARMv7 的,因此需要指定一下镜像的版本,具体的镜像版本可以看 Docker Hub 中的介绍

              docker pull registry.cn-shanghai.aliyuncs.com/suling/openwrt:armv8
               ---
               docker run --restart always --name openwrt -d --network macnet --privileged registry.cn-shanghai.aliyuncs.com/suling/openwrt:armv8 /sbin/init
               

              除此以外,根据它的指导来基本就不会有问题,其中如果需要给路由器下所有设备代理就把路由器的网关和 DNS 改为旁路由的 IP,如果是单独给某个设备(例如只给 Apple TV 终端),就可以只给单个设备设置 DNS 和 网关。

              UDP 代理

              我们想在 Apple TV 上联机玩狂野飙车8,启动多人对战一直报加入服务器错误,观察了一下发现应该是 UDP 流量没有被代理到,因此开启了 OpenClash 的 TUN 模式,开启以后发现更糟了,直接无法上网。搜了一下发现已经有对应的 Issue,疑似是旁路由和 OpenClash 防火墙设置有冲突,删掉对应的规则即可。

              顺便说一句 Apple TV 真的有点香,这个价位,这个性能。

              + PaperMod | 鲁ICP备2020034310号
              \ No newline at end of file diff --git a/posts/page/10/index.html b/posts/page/10/index.html index 1838800a..fa61307c 100644 --- a/posts/page/10/index.html +++ b/posts/page/10/index.html @@ -1,6 +1,6 @@ Posts | Zs's Blog -

              关于STL的一些总结

              前言 STL之前只会用 stack 和 queue ,set 和 map 啥的也不太会用。学习一下。 +

              关于STL的一些总结

              前言 STL之前只会用 stack 和 queue ,set 和 map 啥的也不太会用。学习一下。 ...

              February 16, 2020 · 3 min · zzsqwq

              杂题训练

              A. 配对 题意 给定含有 $n$ 个正整数的集合 $A$ 和 $B$ ,你需要建立他们之间的一一映射。将配对的两个数相加可以得到 $n$ 个和,问第 $k$ 大的和最大为多少。 ...

              February 15, 2020 · 2 min · zzsqwq

              Codeforces#619 (Div.2)

              A. Three Strings 题意 给定三个长度为 $n$ 的字符串 $a$ , $b$ , $c$ ,遍历每个 $c$ 中每个字符 $c_i$,可以将其替换成 $a_i$ 或者 $b_i$ ,必须操作其中一个,问能否通过此操作使得字符串 $a$ , $b$ 相同。 ...

              February 14, 2020 · 2 min · zzsqwq

              日常水题

              前言 今天又是颓废的一天,被大佬拉去跟他一起做牛客网的题,QAQ…那我会点啥嘛,就只能替大佬写两道水题了··· @@ -9,5 +9,5 @@

              + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/posts/page/11/index.html b/posts/page/11/index.html index f59a7c8f..8b852fd5 100644 --- a/posts/page/11/index.html +++ b/posts/page/11/index.html @@ -1,6 +1,6 @@ Posts | Zs's Blog -

              单调队列和单调栈总结

              前言 最近感觉遇到了好多单调队列和单调栈的问题,但是因为以前没学好,所以遇见了就一脸懵逼,然后绝对下决心来学一下。。感觉遇到啥都不会,这可咋办呐。。补不完的漏洞。 ...

              February 11, 2020 · 3 min · zzsqwq

              Codeforces #618 (Div.2)

              A. Non-zero 题意 给出一段含有 $n$ 个数的序列 $a$ ,可以对其中任何数加一,问最少操作多少次让每一个数和序列和都不为0。 +

              单调队列和单调栈总结

              前言 最近感觉遇到了好多单调队列和单调栈的问题,但是因为以前没学好,所以遇见了就一脸懵逼,然后绝对下决心来学一下。。感觉遇到啥都不会,这可咋办呐。。补不完的漏洞。 ...

              February 11, 2020 · 3 min · zzsqwq

              Codeforces #618 (Div.2)

              A. Non-zero 题意 给出一段含有 $n$ 个数的序列 $a$ ,可以对其中任何数加一,问最少操作多少次让每一个数和序列和都不为0。 ...

              February 10, 2020 · 2 min · zzsqwq

              背包进阶

              1. 分组背包 题意 在01背包基础上,将其中的物体分成 $k$ 组,每组内的物品相互冲突,即只能取其中一个,问最大价值。 ...

              February 9, 2020 · 2 min · zzsqwq

              一些关于背包的题

              前言 今天跟着背包九讲把背包再学习一下,dd_engi大佬的背包九讲Github链接: 背包九讲 1. 采药(01背包) 题意 有 $n$ 个价值为 $w_i$ ,体积为 $v_i$ 的物品,装入体积为 $V$ 的背包中,问能获得的最大为多少。 @@ -9,5 +9,5 @@

              + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/posts/page/12/index.html b/posts/page/12/index.html index 2e0535bb..7cc6ff80 100644 --- a/posts/page/12/index.html +++ b/posts/page/12/index.html @@ -1,6 +1,6 @@ Posts | Zs's Blog -

              基础线性dp例题

              前言 某位大佬曾经说过,dp不会没问题,想不到状态转移方程没问题,多做题就会了。所以,我打算多刷点dp题。那么,先从基础刷起吧。 +

              基础线性dp例题

              前言 某位大佬曾经说过,dp不会没问题,想不到状态转移方程没问题,多做题就会了。所以,我打算多刷点dp题。那么,先从基础刷起吧。 1. P1091 合唱队形 题意 已知序列 $a$ 有 $n$ 个数,通过取出其中一些数可以使他满足严格的先增再减序列,问最少取出几个。 ...

              February 6, 2020 · 1 min · zzsqwq

              Codeforces#617(Div.3)

              A. Array with Odd Sum 题意 给出包含 n 个正整数的序列 a ,你可以把任何一个元素 $a_i$ ,赋值给另一个元素 $a_j$ ($i\neq j$) ,问通过任意此操作能否将序列 a 的和变为奇数。可以输出 YES ,不可以输入 NO. 思路 首先当起始和为奇数的时候,就直接可输出 YES 了,如果是偶数的话,我们可以发现,如果序列元素中同时包含奇数和偶数,那么就是可以的,否则不可以。 @@ -9,5 +9,5 @@ ...

              February 2, 2020 · 2 min · zzsqwq
              + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/posts/page/2/index.html b/posts/page/2/index.html index 0d9a53b9..81dc73cc 100644 --- a/posts/page/2/index.html +++ b/posts/page/2/index.html @@ -1,6 +1,6 @@ Posts | Zs's Blog -

              基于地平线 HAT 训练与部署 FCOS 全流程

              前言 最近想要使用自己采集与标注的数据集来训练与部署一下地平线微调过的 FCOS 网络,在询问和查看文档后发现如果想基于官方微调的模型训练,需要使用提供 HAT(Horizon Algorithm Toolkit,海图) 来进行,具体的文档可以查看:Horizon Algorithm Toolkit 文档,这是在线的版本,版本可能会比较旧,想看最新版的可以查看离线的版本,位置在 OE(Open Explorer,天工开物) 包的 doc 目录下,如下图: +

              基于地平线 HAT 训练与部署 FCOS 全流程

              前言 最近想要使用自己采集与标注的数据集来训练与部署一下地平线微调过的 FCOS 网络,在询问和查看文档后发现如果想基于官方微调的模型训练,需要使用提供 HAT(Horizon Algorithm Toolkit,海图) 来进行,具体的文档可以查看:Horizon Algorithm Toolkit 文档,这是在线的版本,版本可能会比较旧,想看最新版的可以查看离线的版本,位置在 OE(Open Explorer,天工开物) 包的 doc 目录下,如下图: 想要方便的查看离线文档可以通过 Python 来实现,在 doc 目录下执行: python3 -m http.server 3000 这样就可以在本地的 0.0.0.0:3000 地址开启一个 http server,随后可以在本地浏览器使用 localhost:3000 或者其他电脑浏览器使用 {ip}:3000 来访问文档。 但是查看 文档 过后会发现,文档其实也没有那么的全面,讲的比较简单,尝试了一下中间坑还挺多的,社区里面关于这方面的帖子也不多12,因此想记录下我尝试的全流程,也可以作为对上面教程文档的补充。 @@ -15,7 +15,9 @@ Nvidia Docker: 2.11.0-1 GPU: RTX3090 NVIDIA Driver Version: 515.65.01 -CUDA Version: 11....

              February 25, 2023 · 9 min · zzsqwq

              2022 年度总结

              2022 依旧是被疫情伴随的一年,时间正着看总是要比回看慢很多,现在回头看过往一年似乎一瞬间就过去了。 +CUDA Version: 11.7 +OE Version: v2.4.2( gcc-9.3.0 For XJ3 ) +...

              February 25, 2023 · 9 min · zzsqwq

              2022 年度总结

              2022 依旧是被疫情伴随的一年,时间正着看总是要比回看慢很多,现在回头看过往一年似乎一瞬间就过去了。 今年共发了 11 篇文章,其中还包含了两篇碎碎念,还是没有达到月更,新的一年希望可以。2022 年对我来说变化很大,算是暂时摆脱了学生生活,体验了社畜的感觉,打卡了北上广深中的北和深。 接下来按月份盘点一些值得纪念的事情吧。 一月: @@ -42,20 +44,18 @@ 哦对了,这个月还搬了新的住所,因为人逐渐变多了,之前的屋子已经住不下了。九月,真是繁忙的一月。 十月: 这个月初入手了 Apple Watch,补齐了个人设备的最后一块拼图算是。iMac 这种没有算进来,因为 iOS、iPadOS、MacOS、WatchOS 四个系统已经集齐了,苹果生态给人的感觉真的很不错。 -有了 Watch 以后,借着新鲜感锻炼了一段时间,但是体重不降反增了,于是动力没了,又回到了肥宅的生活😁。 -同时这个月还和乐乐和雷宝一起去了深圳的欢乐谷游玩,体验了失重的感觉,下次不敢了。 -十一月:平淡的一个月,上班、吃吃吃、玩玩玩。卓卓越来越好看了。 -十二月: -学长从 HK 带回来了最新版的 Apple TV,苹果生态又添一员。现在的联动已经非常棒了,手机可以直接推流到 Homepod、电视、Mac、耳机等。...

              January 1, 2023 · 1 min · zzsqwq

              使用 OrangePi 4 LTS 做旁路由

              前言 最近同居的学长从香港带了个最新版的 Apple TV 回来,但是 Apple TV 在国内用不了,必须要代理才可以,所以考虑到了路由器代理的方案。但是现在家里在用的路由器是 Redmi AX3000,没法刷固件,也不想再买个 R2S 这种软路由了,因此就计划将公司之前用完的 香橙派(OrangePi) 4 LTS 利用一下。它的芯片是 RK3399,用来做路由器绰绰有余,不用可惜了。 +...

              January 1, 2023 · 1 min · zzsqwq

              使用 OrangePi 4 LTS 做旁路由

              前言 最近同居的学长从香港带了个最新版的 Apple TV 回来,但是 Apple TV 在国内用不了,必须要代理才可以,所以考虑到了路由器代理的方案。但是现在家里在用的路由器是 Redmi AX3000,没法刷固件,也不想再买个 R2S 这种软路由了,因此就计划将公司之前用完的 香橙派(OrangePi) 4 LTS 利用一下。它的芯片是 RK3399,用来做路由器绰绰有余,不用可惜了。 为什么是旁路由? 不熟悉旁路由的同学可以看篇指南:从听说到上手,人人都能看懂的旁路由入门指南 找了一些常见的固件,貌似只有针对于 OrangePi R1 和 OrangePi R1 Plus 编译的软路由固件,并且讯龙官方也有放出针对这两个板子的 Openwrt 固件1,可以说是就是为软路由而生,价格也比较便宜,200 左右,性能和 R2S 差别不大。 试了一下在 4 LTS 上跑 R1 和 R1 Plus 的固件2,都无法正常点亮,可能可以自己编译一个对应架构的 OpenWrt,但是有点麻烦,还是没尝试。 考虑到 4 LTS 上可以使用 Docker,因此可以在上面用 Docker 跑一个 OpenWrt 然后做旁路由,到时候只需要把 Apple TV 或者路由器的网关和 DNS 改一下就可以,因此最终选择使用旁路由方案。 具体方案 这里直接参考了小苏的教程:https://mlapp.cn/376.html,写的很清晰,而且很好的考虑了没有基础的同学,赞一个! 里面写的很详细,但是需要注意的是,因为香橙派4 LTS是 ARMv8 架构的,但是直接拉教程里面的默认 latest 镜像是 ARMv7 的,因此需要指定一下镜像的版本,具体的镜像版本可以看 Docker Hub 中的介绍。 -docker pull registry....

              December 31, 2022 · 1 min · zzsqwq

              C++ 类使用注意事项

              前言 本文包含一些在使用 C++ 类时的注意事项,可避免一些常见问题,并能让你在写代码时更加自信。 +...

              December 31, 2022 · 1 min · zzsqwq

              C++ 类使用注意事项

              前言 本文包含一些在使用 C++ 类时的注意事项,可避免一些常见问题,并能让你在写代码时更加自信。 因为目前我使用的是 C++ 17,所以仅保证以下内容在 C++ 17 中正确。 -构造函数 对于单个参数的构造函数,推荐添加 explicit 关键字,防止隐式转换错误调用构造函数。 class DemoClass { explicit DemoClass(int test) { this->test_ = test; } } 显式声明有参构造函数后,编译器不会自动生成无参构造函数,若需要,请添加 DemoClass() = default; class DemoClass { explicit DemoClass(int test) { this->test_ = test; } DemoClass() = default; } 若子类中没有显式调用父类的构造函数,子类会默认调用父类的无参构造函数,如果父类没有无参构造函数,会报错。 析构函数 基类析构函数应该声明为 virtual,这样可以防止子类无法正确的析构。 由于基类析构函数为 virtual,派生类的析构函数应该显式的 override。 class DemoClass { virtual ~DemoClass() = default; } class ChildClass: public DemoClass { ~ChildClass() override { xxx; } } 成员变量默认值 对于类或局部作用域中未明确指定默认值的成员变量,其值遵循以下规则:...

              November 9, 2022 · 2 min · zzsqwq

              关于美的一些思考

              楔子 昨天听了学弟们关于博客搭建的一些教程,在听的过程中,也想起了我之前对于博客的种种尝试,发现整体的趋势就是,简约再简约。 +构造函数 对于单个参数的构造函数,推荐添加 explicit 关键字,防止隐式转换错误调用构造函数。 class DemoClass { explicit DemoClass(int test) { this->test_ = test; } } 显式声明有参构造函数后,编译器不会自动生成无参构造函数,若需要,请添加 DemoClass() = default; class DemoClass { explicit DemoClass(int test) { this->test_ = test; } DemoClass() = default; } 若子类中没有显式调用父类的构造函数,子类会默认调用父类的无参构造函数,如果父类没有无参构造函数,会报错。 析构函数 基类析构函数应该声明为 virtual,这样可以防止子类无法正确的析构。 由于基类析构函数为 virtual,派生类的析构函数应该显式的 override。 class DemoClass { virtual ~DemoClass() = default; } class ChildClass: public DemoClass { ~ChildClass() override { xxx; } } 成员变量默认值 对于类或局部作用域中未明确指定默认值的成员变量,其值遵循以下规则: +对于原生类型(primitive types),即 int、float、int*、string* 等,默认值为随机的脏数据。 对于对象(objects),例如自定义类、或 std::string 等,会调用默认(无参)构造函数,若没有默认(无参)构造函数,则报错。 对于引用(reference)类型,例如 std::string&,必须赋初始值或在构造函数中初始化,若为初始化,则报错。 float age; // 脏数据、随机值(无意义),此时访问会出现未定义行为 int *ptr; // 脏数据、随机值(无意义),此时访问会出现未定义行为 string name; // 调用默认构造函数,对于 std::string 来说为空字符串 "" DemoClass demo; // 若 DemoClass 存在无参构造函数,则调用,否则编译错误 string *pname; // 脏数据、随机值(无意义),此时访问会出现未定义行为 string &rname; // 编译错误,必须显式初始化 const string &crname; // 同上,编译错误 成员变量初始化方式 初始化成员变量一般而言有四种方式,一般而言第二种和第四种方式为等价的,不过在下面我们会看到一种例外: +...

              November 9, 2022 · 2 min · zzsqwq

              关于美的一些思考

              楔子 昨天听了学弟们关于博客搭建的一些教程,在听的过程中,也想起了我之前对于博客的种种尝试,发现整体的趋势就是,简约再简约。 这引发了我对我过去几年的审视,感觉自己的审美一直在变化,对于美的认识和感受也是一直在变的,故写此文来记一些我对美认识的思考。 简约是我最终的归宿 遥记得我还在小学和初中时,非常迷恋 QQ飞车 这款游戏,这款游戏里面有一个虚拟人物,人物可以搭配各种装饰,包括但不限于上衣、裤子、发型、发饰、翅膀等,起初我是喜欢要多花哨有多花哨造型,各种发饰、翅膀、脸部特效搞的飞起,现在想起来真是非常搞笑,而且喜欢五颜六色的,当时觉得,真的是太好看了。 但是过了一段时间,就开始感觉不对劲了,这么花哨,这么丑,这怎么可能是我当时亲手选择的造型。后来就逐渐向简约范靠拢,装饰越简单,色调越单一越喜欢。 @@ -75,9 +75,10 @@ 我觉得美这个东西,很不像生活中常见的发展规律,例如芯片的研发,需要数学、物理、化学等学科实际理论的支持。 2001 年的人是没有办法设计出 Apple M2 的芯片的,因为受到了各种硬件的制约。而 2001 年的设计师有没有可能设计出最新版 Mac QQ 这样的界面呢,如果不能,是什么制约着它呢?如果能,为什么没有出现这种设计,是因为当时大家觉得他不好看吗? 因为我不是学设计和美术等专业的,并且这种很很直觉的东西我不知道该怎么去搜索,因此想在这里和大家探讨一下。如果有已经相对成熟的理论,还请大家能够告知与我,解答困扰我好久的疑问。 -AI 绘图 看网上有人调侃说,愿意称 2022 年为 AI 绘图元年。...

              October 30, 2022 · 1 min · zzsqwq
              + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/posts/page/3/index.html b/posts/page/3/index.html index 9b5d2b3d..5b3ce3ed 100644 --- a/posts/page/3/index.html +++ b/posts/page/3/index.html @@ -1,6 +1,6 @@ Posts | Zs's Blog -

              如何善用搜索引擎?

              前言 我们使用搜索引擎可能是为了搜集信息、或者是解决一些问题。但如果不能正确的使用搜索引擎,使用关键字等,可能搜到的答案就与问题相关不大,或者与我们的问题相差甚远。 +

              如何善用搜索引擎?

              前言 我们使用搜索引擎可能是为了搜集信息、或者是解决一些问题。但如果不能正确的使用搜索引擎,使用关键字等,可能搜到的答案就与问题相关不大,或者与我们的问题相差甚远。 这篇文章意在分享我个人在学习、工作中使用搜索引擎的一些技巧与思考,可能后续会不断的更新,如有纰漏,还请大家指正。 应该使用什么搜索平台? 想要提高搜索的效率,选择一个好的搜索引擎或者内容平台颇为重要。 下面列举的是我平时会使用的一些平台,列出的顺序代表了我个人对于他们的推荐程度: @@ -10,11 +10,13 @@ 如何正确的知道问题所在? 我们遇到一个问题,要首先能够定位这个问题的关键。 例如编译中出错了,可能有很多 log,你必须能够精确定位到到底哪一条 log 才是这次编译出错的关键,进而才能解决这个问题。 以 CMake 为例,编译时报错 log 一般为红色,警告 log 一般为黄色,普通 log 一般为白色。得益于这种等级/颜色分明的 log ,我们可以快速的定位报错。我们日常编程中,为了便于 Debug,最好也遵循这个规范,例如在 C++ 中打印错误 log 时推荐使用 std::stderr 而不是 std::stdout 。 -见过很多身边的同学遇到了报错,就一股脑粘贴所有的报错 log,然后贴到搜索引擎中,发现相关的错误基本没有。这就是没有其中错误的关键,报错时的 log 可能 100 行只有 10 行是关键的,甚至只有一行是关键的,例如 100 行 log 中只有 未定义的引用(undefined reference to ‘xxx’) 这一句是最关键的。...

              October 30, 2022 · 1 min · zzsqwq

              为什么要使用条件变量?

              为什么要使用条件变量? 前言 最近看了很多与线程有关的 C++ 新特性,条件变量是见的比较多的一个特性。 +见过很多身边的同学遇到了报错,就一股脑粘贴所有的报错 log,然后贴到搜索引擎中,发现相关的错误基本没有。这就是没有其中错误的关键,报错时的 log 可能 100 行只有 10 行是关键的,甚至只有一行是关键的,例如 100 行 log 中只有 未定义的引用(undefined reference to ‘xxx’) 这一句是最关键的。 +...

              October 30, 2022 · 1 min · zzsqwq

              为什么要使用条件变量?

              为什么要使用条件变量? 前言 最近看了很多与线程有关的 C++ 新特性,条件变量是见的比较多的一个特性。 看的时候我发现,想要理解一个新的特性,关键的要看它的引入到底解决了哪些问题,没有什么特性我们要实现相同的功能要怎么做? 以我的理解来看,条件变量是一个线程间互相同步与通知的手段,他通过主动唤醒的方式减小了各个线程的开销,取代了简单但是消耗较大的一直被动循环检验与等待。 没有条件变量我们如何实现相同的需求? 这里采用现代C++教程1 中关于条件变量的一个例子作为基础: -不使用条件变量版本 #include <queue> #include <chrono> #include <mutex> #include <thread> #include <iostream> #include <condition_variable> int main() { std::queue<int> produced_nums; std::mutex mtx; // 生产者 auto producer = [&]() { for (int i = 0; ; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(900)); std::unique_lock<std::mutex> lock(mtx); std::cout << "producing " << i << std::endl; produced_nums.push(i); } }; // 消费者 auto consumer = [&]() { while (true) { { std::unique_lock<std::mutex> lock(mtx); if(produced_nums....

              August 24, 2022 · 2 min · zzsqwq

              一个基于 Hugo 的个人主页主题

              背景 之前看到过学长学姐做过个人主页,多是用来申请一些学校的夏令营使用的,觉得非常的 Nice,自己也想搞一个。 +不使用条件变量版本 #include <queue> #include <chrono> #include <mutex> #include <thread> #include <iostream> #include <condition_variable> int main() { std::queue<int> produced_nums; std::mutex mtx; // 生产者 auto producer = [&]() { for (int i = 0; ; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(900)); std::unique_lock<std::mutex> lock(mtx); std::cout << "producing " << i << std::endl; produced_nums.push(i); } }; // 消费者 auto consumer = [&]() { while (true) { { std::unique_lock<std::mutex> lock(mtx); if(produced_nums.empty()) continue; } std::unique_lock<std::mutex> lock(mtx); // 短暂取消锁,使得生产者有机会在消费者消费空前继续生产 lock.unlock(); // 消费者慢于生产者 std::this_thread::sleep_for(std::chrono::milliseconds(1000)); lock.lock(); while (!produced_nums.empty()) { std::cout << "consuming " << produced_nums.front() << std::endl; produced_nums.pop(); } } }; // 分别在不同的线程中运行 std::thread p(producer); std::thread cs[2]; for (int i = 0; i < 2; ++i) { cs[i] = std::thread(consumer); } p.join(); for (int i = 0; i < 2; ++i) { cs[i].join(); } return 0; } 使用条件变量版本 #include <queue> #include <chrono> #include <mutex> #include <thread> #include <iostream> #include <condition_variable> int main() { std::queue<int> produced_nums; std::mutex mtx; std::condition_variable cv; bool notified = false; // 通知信号 // 生产者 auto producer = [&]() { for (int i = 0; ; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(900)); std::unique_lock<std::mutex> lock(mtx); std::cout << "producing " << i << std::endl; produced_nums.push(i); notified = true; cv.notify_all(); // 此处也可以使用 notify_one } }; // 消费者 auto consumer = [&]() { while (true) { std::unique_lock<std::mutex> lock(mtx); while (!notified) { // 避免虚假唤醒 cv.wait(lock); } // 短暂取消锁,使得生产者有机会在消费者消费空前继续生产 lock.unlock(); // 消费者慢于生产者 std::this_thread::sleep_for(std::chrono::milliseconds(1000)); lock.lock(); while (!produced_nums.empty()) { std::cout << "consuming " << produced_nums.front() << std::endl; produced_nums.pop(); } notified = false; } }; // 分别在不同的线程中运行 std::thread p(producer); std::thread cs[2]; for (int i = 0; i < 2; ++i) { cs[i] = std::thread(consumer); } p.join(); for (int i = 0; i < 2; ++i) { cs[i].join(); } return 0; } 这两段代码在效果上是等效的,都是一个生产者两个消费者。 +...

              August 24, 2022 · 2 min · zzsqwq

              一个基于 Hugo 的个人主页主题

              背景 之前看到过学长学姐做过个人主页,多是用来申请一些学校的夏令营使用的,觉得非常的 Nice,自己也想搞一个。 大家之前好像大多用的是基于 Hexo 的一个主题 — hexo-theme-academia,但是由于之前我用过 Hexo,觉得他有一些比较明显的弊端,例如环境配置比较麻烦、需要安装 Nodejs、npm 等环境,然后再安装 Hexo。其次它的构建速度比较慢,用起来感觉比较僵硬。 后来随着了解增多,尝试了 Typecho、WordPress,Hugo 等主题后,目前还是决定使用 Hugo。它构建速度快,而且安装简单,在 Ubuntu 上只需要一行 sudo apt install hugo 即可,不可谓不简单。因此萌生了移植一个 Hugo 版本主题的想法,刚好可以锻炼一下自己。 欢迎点击 这里 查看我的个人主页。 @@ -34,7 +36,8 @@ 关于 Gitee 的设置,Gitee 官方的 Docker 部署教程1已经说的很清楚了,按照该步骤执行完全没问题。 而关于 Gitlab 貌似没有比较详尽的教程,搜索后发现了一个 Issue2 以及一篇博文3,后者讲的比较清楚,但是经过实践后发现存在一定问题,因此决定将可行的方案记录下来。 具体步骤 一、初始设置 在开始之前,docker-compose.yml 中设置比较关键的几个配置如下: -gitlab-web: image: 'gitlab/gitlab-ce:latest' container_name: 'gitlab' restart: always environment: GITLAB_OMNIBUS_CONFIG: | gitlab_rails['gitlab_shell_ssh_port'] = 4022 ports: - '3090:80' - '4022:22' - '6060:6060' volumes: - '/srv/gitlab/config:/etc/gitlab' - '/srv/gitlab/logs:/var/log/gitlab' - '/srv/gitlab/data:/var/opt/gitlab' - ....

              April 24, 2022 · 3 min · zzsqwq

              关于春节期间的一些碎碎念

              前言 春节期间,走亲访友是必不可少的。交谈的多了,免不得一些问题的讨论。 +gitlab-web: image: 'gitlab/gitlab-ce:latest' container_name: 'gitlab' restart: always environment: GITLAB_OMNIBUS_CONFIG: | gitlab_rails['gitlab_shell_ssh_port'] = 4022 ports: - '3090:80' - '4022:22' - '6060:6060' volumes: - '/srv/gitlab/config:/etc/gitlab' - '/srv/gitlab/logs:/var/log/gitlab' - '/srv/gitlab/data:/var/opt/gitlab' - .... #一些其他的配置 如上设置基本可以确保 Gitlab 形如 ssh://git@git.xxxx.cn:4022/zs/zsblog.git 的链接可以使用。 +...

              April 24, 2022 · 3 min · zzsqwq

              关于春节期间的一些碎碎念

              前言 春节期间,走亲访友是必不可少的。交谈的多了,免不得一些问题的讨论。 读了很多书,经历了很多事,似乎想法也有一些”离经叛道“,记一下自己目前的一些想法,不知道多年后的自己看这篇文章会是什么想法,还会一如既往的坚持吗。 讨论的话题 打点关系 无论是父母,还是各方亲戚,大家好像都喜欢打点关系,以此来获得一些好处。 最常见的是求人办事,很多时候是我们常说的”走后门“,想让孩子上个好点的小学,避免不了又送礼又吃饭。 @@ -71,5 +74,5 @@

              + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/posts/page/4/index.html b/posts/page/4/index.html index cde5c4b2..8bc34ab7 100644 --- a/posts/page/4/index.html +++ b/posts/page/4/index.html @@ -1,6 +1,6 @@ Posts | Zs's Blog -

              一个 Javascript 中异步的小技巧

              前言 最近看了一些 js 有关的知识,其中令我这种初学者感到很头疼的一个问题就是异步问题。 +

              一个 Javascript 中异步的小技巧

              前言 最近看了一些 js 有关的知识,其中令我这种初学者感到很头疼的一个问题就是异步问题。 今天就我碰到的一个小问题详解一个关于异步的小技巧。 背景 我在程序中需要鉴权,来判断一个用户是普通用户还是管理员,针对不同的用户渲染不同的页面。 每个用户具有唯一的 ID,因此我只需要将管理员的 ID 放到数据库,然后加载程序的时候一一比对即可。 @@ -15,7 +15,8 @@ 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 所以此处加入 callback 以防止这种情况 这里判断了主程序内是否含有 userInfoReadyCallback 这个函数,如果有的话就执行。 -qq.getSetting({ success: res => { if (res.authSetting['scope.userInfo']) { // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框 qq.getUserInfo({ success: res => { // 可以将 res 发送给后台解码出 unionId this.globalData.userInfo = res.userInfo // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 if (this....

              January 19, 2022 · 1 min · zzsqwq

              记一次博客迁移记录

              前言 更换博客系统的想法已经萌生很久了,一个是感觉 Handsome 这个主题有点看腻了,但是在 Typecho 中好似已经没有更好的博客主题可选择了。 +qq.getSetting({ success: res => { if (res.authSetting['scope.userInfo']) { // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框 qq.getUserInfo({ success: res => { // 可以将 res 发送给后台解码出 unionId this.globalData.userInfo = res.userInfo // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 if (this.userInfoReadyCallback) { this.userInfoReadyCallback(res) } } }) } } }) 页面初始化部分代码: +...

              January 19, 2022 · 1 min · zzsqwq

              记一次博客迁移记录

              前言 更换博客系统的想法已经萌生很久了,一个是感觉 Handsome 这个主题有点看腻了,但是在 Typecho 中好似已经没有更好的博客主题可选择了。 有一个看起来貌似很不错,主题名叫 maupassant。效果如下图所示,顺附链接 pagecho/maupassant(github.com) 不过一直没有下定决心更换,后来也尝试过使用 WordPress,又觉得 WordPress 体量有点太大了。 @@ -26,7 +27,8 @@ 具体导出为 zip 的时候可能会提示损坏,这样的话可以直接去服务器 \tmp\Export2Hugo 下面打包。 安装 hugo 过程基于 Windows 平台,很简单,在 这里 下载 hugo 最新的 release 版本,找到对应自己系统的即可。下载后解压到某个目录下,设置一下环境变量即可。这里牵扯到 hugo 和 hugo_extended 两个版本的区别,以下是某个 issue 中的解释: I agree. -The only functional difference is SASS/SCSS The technical build time difference is that it requires a C++ build chain for the target platform to build, the reason why we currently only build the extended for 3 platforms (Windows, Linux, MacOS) Binaries are slightly less portable as you need a compatible Libc version on your computer (for Windows we build a fully static version as Libc is rather uncommon unless you have Visual Studio or something installed)....

              December 13, 2021 · 2 min · zzsqwq

              Markdown 编辑器推荐

              前言 近期著名 Markdown 编辑器 Typora 宣布收费了,起初感觉很难受,后来感慨之余也觉得算是合理,毕竟 Typora 用起来感觉是真的很良心,也在考虑是否买一份支持一下。 +The only functional difference is SASS/SCSS The technical build time difference is that it requires a C++ build chain for the target platform to build, the reason why we currently only build the extended for 3 platforms (Windows, Linux, MacOS) Binaries are slightly less portable as you need a compatible Libc version on your computer (for Windows we build a fully static version as Libc is rather uncommon unless you have Visual Studio or something installed). via: Please document the difference between the “extended” and non-“extended” versions +...

              December 13, 2021 · 2 min · zzsqwq

              Markdown 编辑器推荐

              前言 近期著名 Markdown 编辑器 Typora 宣布收费了,起初感觉很难受,后来感慨之余也觉得算是合理,毕竟 Typora 用起来感觉是真的很良心,也在考虑是否买一份支持一下。 已于2021/12/10购入,还是选择回归了 Typora 了哈哈哈 虽说左右分屏的设计可能更符合 Markdown 的初衷,但是像 Typora 这种所见即所得(WYSIWYG) 的书写体验确实是感觉习惯了就回不去了。 因此近期也搜集了 Markdown 编辑器作为 Typora 的替代品,在这里给大家分享一下。 @@ -41,7 +43,8 @@ 在我使用的一段时间内,他给我的感觉是,功能十分丰富的一个 Markdown 文件管理工具。如果你购买了他的同步服务,那你可以很轻松的在各平台同步你的 Markdown 文件夹,并且基于他强大的插件,可以很完成很多 Markdown 文件份外的事,例如待办清单、日历等等。 他虽没有所见即所得的模式,但是依靠其一款第三方插件,可以达成类似的效果,不过还是用起来不如 Typora 这种顺手。同时,它的各端同步如果不开启官方的服务,用起来还是挺麻烦的,经过我的一阵倒腾,我总结了如下几个方案: 使用第三方Git管理插件,可以定时推送文件夹中的内容到仓库,这样可以完成 linux 与 Windwos 平台的同步,只需要在某一方推送某一方拉取即可。而 Windows 平台与 iPad 平台的同步,可以借助 Apple 的 iCloud,Windows上有对应的客户端,这也是 Obsidian 官方支持的。不过在我使用的过程中我发现,这样异常的麻烦,使用 Git 来管理很可能会产生冲突,导致需要手动处理冲突,久而久之就会觉得很烦。 -使用自建云盘如 NextCloud + Obsidian,或者 Seafile + Obsidian。 这个是我觉得目前非常可行的一个方案,最近我也有在尝试 NextCloud,它的多端同步做的非常不错,依靠此可以在各个平台同步文件夹,加上 Obsidian 强悍的能力,是不错的组合!...

              December 1, 2021 · 1 min · zzsqwq

              2021版小新Pro14 Ubuntu 20.04 配置指南

              2021版小新Pro14 Ubuntu 20.04 配置指南 补充 最近重装了 Ubuntu 20.04,又找了相关的一些帖子,发现 聯想Yoga 14s 2021款裝機小記 中提到了下文中提到的屏幕闪烁的问题,解决办法是:只需要在内核参数中加入 i915.enable_psr=0 即可。 +使用自建云盘如 NextCloud + Obsidian,或者 Seafile + Obsidian。 这个是我觉得目前非常可行的一个方案,最近我也有在尝试 NextCloud,它的多端同步做的非常不错,依靠此可以在各个平台同步文件夹,加上 Obsidian 强悍的能力,是不错的组合! +...

              December 1, 2021 · 1 min · zzsqwq

              2021版小新Pro14 Ubuntu 20.04 配置指南

              2021版小新Pro14 Ubuntu 20.04 配置指南 补充 最近重装了 Ubuntu 20.04,又找了相关的一些帖子,发现 聯想Yoga 14s 2021款裝機小記 中提到了下文中提到的屏幕闪烁的问题,解决办法是:只需要在内核参数中加入 i915.enable_psr=0 即可。 具体操作步骤如下: $ sudo vim /etc/default/grub 在 GRUB_CMDLINE_LINUX_DEFAULT 这一行的最后添加 i915.enable_psr=0,保存后终端运行: $ sudo update-grub 然后重启即可。 @@ -49,7 +52,8 @@ CPU:酷睿 i5-11300H 显卡:集成显卡 Intel 锐炬Iris Xe 内存:16G 外存:512 SSD 屏幕:分辨率 2880x1800、400nits、100%sRGB 这里需要注意的是,不同时间出的小新Pro14配置是不太一样的,所以我这里列了一下配置。主要区别在于有一部分是2.2K分辨率+MX450显卡,而我这个是2.8K分辨率+锐炬Iris Xe显卡。 为了工作的需要,要装一个Ubuntu,先是装了之前用过的 Ubuntu 18.04,安装后发现触摸板无法使用,一系列探索后无果,在朋友的推荐下,还是决定安装 Ubuntu 20.04 试一下,踩了一些坑,在这里记录一下。 问题列表 如果你遇到了以下问题,那么这篇文章的方法可能会对你有益处: -Ubuntu 18.04 相关 Ubuntu 18.04 无法使用触摸板 Ubuntu 18.04 无法使用内置键盘 Ubuntu 18.04 无法调节亮 Ubuntu 18.04 查看GPU发现是llvm,而不是Iris Xe Ubuntu 20.04 相关 Ubuntu 20....

              November 2, 2021 · 2 min · zzsqwq

              关于Git的一些理解

              前言 前段时间在 Github 学完了关于 git 的小游戏 learnGitBranching ,受益匪浅。 +Ubuntu 18.04 相关 Ubuntu 18.04 无法使用触摸板 Ubuntu 18.04 无法使用内置键盘 Ubuntu 18.04 无法调节亮 Ubuntu 18.04 查看GPU发现是llvm,而不是Iris Xe Ubuntu 20.04 相关 Ubuntu 20.04 进入后屏幕花屏、黑屏 Ubuntu 20.04 查看GPU发现是llvm,而不是Iris Xe 现在达成的效果 Ubuntu 20.04 能够正常使用,触摸板以及外界屏幕,亮度调节均无问题。 +...

              November 2, 2021 · 2 min · zzsqwq

              关于Git的一些理解

              前言 前段时间在 Github 学完了关于 git 的小游戏 learnGitBranching ,受益匪浅。 它通过可视化的方式将分支的关系,每条命令的作用等都明明白白的体现出来,可以很直观的感受到你每条命令对整个分支树,每一个 ref 的作用。 通过这种学习感觉自己对 Git 的理解更加深入一步,能够理解其中的原理,而不是浅尝辄止,照猫画虎。 学习中记了一些零零散散的思路,想要写一篇笔记记录出来,之前已经写过一个简单的 Git 教程,这篇教程将会更加深入,希望可以帮助大家更好的掌握 Git。 @@ -57,9 +61,10 @@ Git中的分区 首先,Git中存在三大分区,分别是工作区、暂存区、版本库。其中, 工作区即我们工作的目录,暂存区是我们执行 git add 后文件存在的区域。 我们可以通过 git status 对两种状态进行查看,例如: -~/test master* base ❯ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: test Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>....

              July 23, 2021 · 3 min · zzsqwq
              + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/posts/page/5/index.html b/posts/page/5/index.html index 7820c9fd..f44b4e7f 100644 --- a/posts/page/5/index.html +++ b/posts/page/5/index.html @@ -1,6 +1,6 @@ Posts | Zs's Blog -

              利用树莓派为HP LaserJet 1020配置无线打印功能

              前言 最近基地的打印机突然又好起来了。 +

              利用树莓派为HP LaserJet 1020配置无线打印功能

              前言 最近基地的打印机突然又好起来了。 因为基地的打印机型号比较老——HP LaserJet 1020,没有无线打印的功能。所以之前一位学长1 用树莓派配置了打印机的无线打印功能,但是后来发现有一些问题,有时候发送打印请求树莓派无法接收,而且不知道为何,学长之前用的是树莓派自己创建WiFi,连接对应WiFi才能打印,但是这个显然不是最优的解决办法。 考虑到之间已经配置好基地WiFi,我决定重新配置一下打印功能,使其连接基地WiFi即可实现局域网打印。 配置过程 查看树莓派内容 通过ssh连接树莓派,发现里面除了Github上的一个开源项目create_ap ,就没有什么其他的内容了,连接屏幕后发现没有任何图像信号,无从下手,因此考虑重新刷机。 @@ -14,13 +14,15 @@ $ sudo ifconfig 查看WiFi对应的IP,至此,树莓派可以摆脱屏幕,我们可以使用电脑进行使用 ssh 连接。 这里也可以使用网线进行连接,具体操作如下 用网线连接树莓派和自己的电脑。 -在树莓派的利用 nmtui 选择 Edit a connection ,Add一个Ethernet connect,对IPv4 CONFIGURATION进行设置,首先讲 Automatic 设置为 Manual,设置 Address 为 静态IP 如 192....

              July 18, 2021 · 2 min · zzsqwq

              deepin-wine-qq-9.1.8版本无法正常启动的解决方案

              问题描述 ​Ubuntu下想要使用QQ有一个比较好的解决方案就是deepin-wine的版本,deepin-wine版本的QQ一共有两个版本,分别是 8.9.1 和 9.1.8 ,前者安装后发现无法登陆,登录时会提示版本过低的问题,于是我换到9.1.8版本后,启动初始化后就无任何信息了,于是开始排查问题 +在树莓派的利用 nmtui 选择 Edit a connection ,Add一个Ethernet connect,对IPv4 CONFIGURATION进行设置,首先讲 Automatic 设置为 Manual,设置 Address 为 静态IP 如 192.168.3.2 ,Gateway 设置为 192.168.3.1 。 +...

              July 18, 2021 · 2 min · zzsqwq

              deepin-wine-qq-9.1.8版本无法正常启动的解决方案

              问题描述 ​Ubuntu下想要使用QQ有一个比较好的解决方案就是deepin-wine的版本,deepin-wine版本的QQ一共有两个版本,分别是 8.9.1 和 9.1.8 ,前者安装后发现无法登陆,登录时会提示版本过低的问题,于是我换到9.1.8版本后,启动初始化后就无任何信息了,于是开始排查问题 解决方案 ​首先我们根据上文的启示,因为每一个应用程序对应了一个 xxx.desktop 文件,因此在应用库中的QQ一定也有一个对应的 desktop 文件 ​我们进入到 /usr/share/applications ,运行 $ ls | grep -i qq ​可以发现其中有一个名为 deepin.com.qq.im.desktop 的文件,我们打开后发现内容如下: #!/usr/bin/env xdg-open [Desktop Entry] Encoding=UTF-8 Type=Application X-Created-By=Deepin WINE Team Categories=chat; Icon=deepin.com.qq.im Exec="/opt/deepinwine/apps/Deepin-QQ/run.sh" -u %u Name=QQ Name[zh_CN]=QQ Comment=Tencent QQ Client on Deepin Wine StartupWMClass=QQ.exe MimeType= ​可以看到Exec那一栏为 Exec="/opt/deepinwine/apps/Deepin-QQ/run.sh" -u %u ,发现他是运行目录下的一个 run.sh 脚本来启动的。 ​我们进入目录下直接运行该脚本,查看log信息: -base ❯ ./run.sh Run Deepin-QQ 9.1.8deepin0 c:/Program Files/Tencent/QQ/Bin/QQ.exe run Deepin-QQ progress pid Gtk-Message: 01:16:58.069: GtkDialog mapped without a transient parent....

              June 16, 2021 · 4 min · zzsqwq

              利用神经网络进行波士顿房价预测

              前言 前一阵学校有五一数模节校赛,和朋友一起参加做B题,波士顿房价预测,算是第一次自己动手实现一个简单的小网络吧,虽然很简单,但还是想记录一下。 +base ❯ ./run.sh Run Deepin-QQ 9.1.8deepin0 c:/Program Files/Tencent/QQ/Bin/QQ.exe run Deepin-QQ progress pid Gtk-Message: 01:16:58.069: GtkDialog mapped without a transient parent. This is discouraged. total 0 lrwxrwxrwx 1 zs zs 10 6月 16 01:16 c: -> ../drive_c lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com1 -> /dev/ttyS0 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com10 -> /dev/ttyS9 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com11 -> /dev/ttyS10 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com12 -> /dev/ttyS11 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com13 -> /dev/ttyS12 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com14 -> /dev/ttyS13 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com15 -> /dev/ttyS14 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com16 -> /dev/ttyS15 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com17 -> /dev/ttyS16 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com18 -> /dev/ttyS17 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com19 -> /dev/ttyS18 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com2 -> /dev/ttyS1 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com20 -> /dev/ttyS19 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com21 -> /dev/ttyS20 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com22 -> /dev/ttyS21 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com23 -> /dev/ttyS22 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com24 -> /dev/ttyS23 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com25 -> /dev/ttyS24 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com26 -> /dev/ttyS25 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com27 -> /dev/ttyS26 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com28 -> /dev/ttyS27 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com29 -> /dev/ttyS28 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com3 -> /dev/ttyS2 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com30 -> /dev/ttyS29 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com31 -> /dev/ttyS30 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com32 -> /dev/ttyS31 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com4 -> /dev/ttyS3 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com5 -> /dev/ttyS4 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com6 -> /dev/ttyS5 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com7 -> /dev/ttyS6 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com8 -> /dev/ttyS7 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com9 -> /dev/ttyS8 lrwxrwxrwx 1 zs zs 8 6月 16 01:16 y: -> /home/zs lrwxrwxrwx 1 zs zs 1 6月 16 01:16 z: -> / CallApp Deepin-QQ c:/Program Files/Tencent/QQ/Bin/QQ.exe 2021年 06月 16日 星期三 01:16:58 CST:kill QQ.exe block 2021年 06月 16日 星期三 01:16:58 CST:No wine process found /home/zs/.deepinwine/Deepin-QQ/drive_c/Program Files/Tencent/QQ/Bin Starting process c:/Program Files/Tencent/QQ/Bin/QQ.exe ... /opt/deepinwine/apps/Deepin-QQ base ❯ wine: cannot find L"C:\\windows\\system32\\winemenubuilder.exe" wine version: 2.18 libGL error: No matching fbConfigs or visuals found libGL error: failed to load driver: swrast X Error of failed request: GLXBadContext Major opcode of failed request: 152 (GLX) Minor opcode of failed request: 6 (X_GLXIsDirect) Serial number of failed request: 207 Current serial number in output stream: 206 ​可以发现最下面的log信息有一些异常,首先第一行是因为我们是Ubuntu系统,可以暂且不关注 +...

              June 16, 2021 · 4 min · zzsqwq

              利用神经网络进行波士顿房价预测

              前言 前一阵学校有五一数模节校赛,和朋友一起参加做B题,波士顿房价预测,算是第一次自己动手实现一个简单的小网络吧,虽然很简单,但还是想记录一下。 题目介绍 波士顿住房数据由哈里森和鲁宾菲尔德于1978年Harrison and Rubinfeld1收集。它包括了波士顿大区每个调查行政区的506个观察值。1980年Belsley et al.2曾对此数据做过分析。 数据一共14列,每一列的含义分别如下: 英文简称 详细含义 CRIM 城镇的人均犯罪率 ZN 大于25,000平方英尺的地块的住宅用地比例。 INDUS 每个镇的非零售业务英亩的比例。 CHAS 查尔斯河虚拟变量(如果环河,则等于1;否则等于0) NOX 一氧化氮的浓度(百万分之几) RM 每个住宅的平均房间数 AGE 1940年之前建造的自有住房的比例 DIS 到五个波士顿就业中心的加权距离 RAD 径向公路通达性的指标 TAX 每一万美元的全值财产税率 PTRATIO 各镇的师生比率 B 计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例 LSTAT 底层人口的百分比(%) price 自有住房数的中位数,单位(千美元) 基于上述数据,请完成以下问题: @@ -30,7 +32,8 @@ 建立前馈神经网络模型,根据通用逼近定理,我们可以拟合此回归模型。 我们对上述模型来进行实现并确定评估标准来对他们进行比较,选择最优的模型作为预测模型。 算法流程 传统的回归算法 自变量的选择 首先,考虑到数据集中13列自变量其中某一些可能和最终的房价并无强相关性,如果全部使用进行预测可能会对模型引入噪声,因此我们首先计算了房价price与各个自变量之间的相关系数 $r$ ,其中 $r$ 计算公式如下: $$ r = \frac{\sum(x_i-\bar{x})(y_i-\bar{y})}{\sqrt{\sum(x_i-\bar{x})^2\sum(y_i-\bar{y})^2}} $$ 其中 $x_i,y_i$ 为数据的每个分量,$\bar{x},\bar{y}$ 为数据的均值 -该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下:...

              May 16, 2021 · 1 min · zzsqwq

              2021RoboMaster中国赛比赛记录

              前言 ​说起来的话今天距离比赛已经过去近一个月了,比赛结束一直想要记录一下and总结一下经验,但是实在是太懒了,临近五一假期,在四月的末尾为这次中国赛画一个句号吧。 +该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下: +...

              May 16, 2021 · 1 min · zzsqwq

              2021RoboMaster中国赛比赛记录

              前言 ​说起来的话今天距离比赛已经过去近一个月了,比赛结束一直想要记录一下and总结一下经验,但是实在是太懒了,临近五一假期,在四月的末尾为这次中国赛画一个句号吧。 比赛过程 ​如果没记错的话比赛是3.30号(周二)去,4.1号(周四)结束,共三天。但是因为第三天没做什么有意义的事情,就只记录两天了。 第一天 ​第一天大概中午十点到的吧,去的时候登记完领了牌,就在当地布置场地了。到了场地上才发现,我们好像是拿的东西最多的,包括外接显示屏和集成主机,好像都基本没人带过去····集成主机拿了过去也没怎么用到,本来预想用到的哨岗相机因为 ROS 的通信问题也没能跑成,最后两个机器人还是各跑各的策略了。 ​调试的时候出了一点问题,两个哨岗相机通过20m的USB延长线后,只有一个能连接,后来排查了一下,好像是因为有一条线是光纤USB3.0的线,跟相机的接口不兼容···这个问题还没想好怎么解决,可能会考虑到时候自己带一根USB延长线过去。 @@ -51,5 +54,5 @@

              + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/posts/page/6/index.html b/posts/page/6/index.html index bdb39915..e602ab98 100644 --- a/posts/page/6/index.html +++ b/posts/page/6/index.html @@ -1,6 +1,6 @@ Posts | Zs's Blog -

              如何使用CenterNet做3D目标检测测试

              CenterNet—Objects as Points介绍 ​CenterNet是一个anchor-free的目标检测网络,与YOLOv3相比,精度有所提升,此外他不仅能够用于2D目标检测,也能够用于人体姿态识别,3D目标检测等··· +

              如何使用CenterNet做3D目标检测测试

              CenterNet—Objects as Points介绍 ​CenterNet是一个anchor-free的目标检测网络,与YOLOv3相比,精度有所提升,此外他不仅能够用于2D目标检测,也能够用于人体姿态识别,3D目标检测等··· 安装CenterNet ​其实安装CenterNet的过程就是一个配置环境的问题,直接跟着官方给出的这里Install.md配置一下即可,十分推荐使用Conda来管理环境,这里给出我的环境给大家参考一下: Ubuntu = 18.04 LTS pytorch = 1.2.0 @@ -13,7 +13,11 @@ python demo.py ctdet --demo ${CenterNet_Root}/images/17790319373_bd19b24cfc_k.jpg --load_model ../models/ctdet_coco_dla_2x.pth ​这里需要注意的是 --demo 后面的 ${CenterNet_Root}/images/17790319373_bd19b24cfc_k.jpg ,这里我使用的是官方给出的实例图片,它位于CenterNet根目录的images文件夹中,前面的 ${CenterNet_Root} 代表的是 CenterNet根目录,好比我的就位于 /home/zs/CenterNet 。 ​如果不出意外的话效果应该如下图所示: 运行CenterNet的3D目标检测 配置数据集和模型 ​我们可以直接参考官方的 DATA.md 来配置我们的数据集。 -​然后到 Model zoo 下载3D检测使用的模型 ddd_3dop....

              January 27, 2021 · 2 min · zzsqwq

              Git的简易教程

              前言 最近在复习Git,因此顺手做个笔记分享出来,方便大家学习和查阅。相信无论是以后的课程作业还是工作,我们都会或多或少的接触/用到Git。 +​然后到 Model zoo 下载3D检测使用的模型 ddd_3dop.pth 。 +​这里说一下遇到的几个坑: +首先是配置数据集的过程中,我们需要配置的目录结构如图所示(官方给出的结构树有点模糊不清的感觉) +. ├── ImageSets_3dop │ ├── test.txt │ ├── train.txt │ ├── trainval.txt │ └── val.txt ├── ImageSets_subcnn │ ├── test.txt │ ├── train.txt │ ├── trainval.txt │ └── val.txt └── training ├── calib ├── image_2 └── label_2 然后去到 ${CenterNet_ROOT}/src/tools目录下,运行 python convert_kitti_to_coco.py 将 kitti 数据集转换为 coco 数据集的格式,不出意外应该会报错如下: +...

              January 27, 2021 · 2 min · zzsqwq

              Git的简易教程

              前言 最近在复习Git,因此顺手做个笔记分享出来,方便大家学习和查阅。相信无论是以后的课程作业还是工作,我们都会或多或少的接触/用到Git。 什么是Git? Git你可能没听说过,但是我相信你应该听说过Github,毕竟是全球最大的同性交友网站。他和Git有着密不可分的联系,我们后续再详细介绍。 Git的中文全称叫 分布式版本控制系统 ,版本控制系统是什么意思呢?我们举一个简单的例子,你在做一个大作业,很可能要写上千行的代码,但是你可能写完一个功能以后,对他不够满意,但是又害怕改了以后后悔了,又找不回来了,所以你可能就有很多版本,版本1,版本2,版本3等等等。Git就是解决这个问题的,让你文件能够保持最新,但是又能恢复到之前的版本。 那么既然有分布式版本控制系统,就有 集中式版本控制系统,前者的代表是 Git ,后者的代表有 SVN、CVS 等。 @@ -36,7 +40,8 @@ git init 顾名思义这就是一个初始化的过程,运行以后在当前目录生成一个 .git 文件夹,里面是我们版本控制的数据,一般不要修改。 把文件添加到Git的暂存区 这里出现了 暂存区 这个名词,Git内部的逻辑大概把我们工作的过程分为了三部分 -一个是 工作区 ,这个就是我们本地的文件夹。 一个是 暂存区 ,这是我们把文件暂时放到暂存区里,没有决定更新我们的版本。 一个是 最终分支,这就是我们最终的版本存放的位置。 贴一张廖雪峰老师教程中的一张图,我觉得还挺形象的。...

              December 5, 2020 · 2 min · zzsqwq

              Ubuntu18.04优化教程

              前言 因为最近Ubuntu用的比较频繁,所以前一阵把Ubuntu16.04换成Ubuntu18.04了,并且囿于机械硬盘那启动速度,我忍痛割爱把我80G的固态硬盘分给了Ubuntu。 +一个是 工作区 ,这个就是我们本地的文件夹。 一个是 暂存区 ,这是我们把文件暂时放到暂存区里,没有决定更新我们的版本。 一个是 最终分支,这就是我们最终的版本存放的位置。 贴一张廖雪峰老师教程中的一张图,我觉得还挺形象的。 +...

              December 5, 2020 · 2 min · zzsqwq

              Ubuntu18.04优化教程

              前言 因为最近Ubuntu用的比较频繁,所以前一阵把Ubuntu16.04换成Ubuntu18.04了,并且囿于机械硬盘那启动速度,我忍痛割爱把我80G的固态硬盘分给了Ubuntu。 后来,用着用着就觉得这个Ubuntu的原始界面确实不是特别的好看,配色偏基佬紫的感觉。“工欲善其事,必先利其器“,我们只有将自己的工作环境布置的舒心一些才能有做下去的动力!所以我想给Ubuntu换一个看起来舒服点的界面,然后上网找教程乱七八糟的倒腾了一会,感觉换完以后完全不一样了,这个界面真的好看!!用起来也特别的舒心,感觉自己马上就要告别Windows投奔Linux的怀抱了。后续还有一些其他的优化,例如装QQ、微信、配置终端等,一并写在这里吧。 Ubuntu界面的优化 具体效果 先放几张效果图上来,是我改后的界面。大概就是这样(自我感觉挺好看的),当然也有其他的主题可供选择。 1.安装GNOME桌面环境主题配置工具 如果要改主题,那么首先要有一个利器,这里我用的Ubuntu18.04,桌面环境为 GNOME 3.28.2 ,因为我目前接触的只有GNOME桌面环境的,Ubuntu18.04本来的桌面环境就是GNOME,但是Ubuntu16.04好像没有自带,但是可以安装,这里大家可以自行百度了解。 @@ -51,18 +56,20 @@ 然后我们回到 GNOME Tweaks 软件中就可以发现,我们已经可以在主题\图标\光标\Shell清单中找到我们移动到文件夹中的文件了,然后选择就可以切换了。这里需要注意的,很多主题都是自带Shell的,你下了一个主题,那么你可以在Shell和主题这两个栏目中都找到他们,是一个配套的。 4.一些后续的调整 我们后续可以改变左边收藏夹的位置,我觉得放在左边有一丢丢的丑,所以我选择把它放在的下面。 我们去Ubuntu软件中搜索 Dash to dock,然后安装这个拓展,然后打开 GNOME Tweaks 软件在拓展中找到他就可以随心所欲的调我们的收藏夹的位置了。 -5.我自己的配置 theme&shell Canta-light-compact icons 01-McMojave-circle 6.界面修改的参考链接 Ubuntu18.04美化主题(mac主题) Ubuntu18.04美化主题(完整版) GNOME-LOOK.ORG 30个非常不错的Ubuntu主题供你选择 ubuntu18....

              December 4, 2020 · 1 min · zzsqwq

              “程序星编程之路”第二次作业题解

              “程序星编程之路”第二次作业题解 A. Zs的回文质数 题目描述 读入一个整数 $n$ ,输出 $[1,n]$ 的所有回文质数,我们规定 $1\sim9$ 也是回文数。 +5.我自己的配置 theme&shell Canta-light-compact icons 01-McMojave-circle 6.界面修改的参考链接 Ubuntu18.04美化主题(mac主题) Ubuntu18.04美化主题(完整版) GNOME-LOOK.ORG 30个非常不错的Ubuntu主题供你选择 ubuntu18.04更换鼠标游标主题 配置终端 前言 唔,终端本来用起来感觉也还行,感觉终端就是linux的灵魂,啥都能干。 +...

              December 4, 2020 · 1 min · zzsqwq

              “程序星编程之路”第二次作业题解

              “程序星编程之路”第二次作业题解 A. Zs的回文质数 题目描述 读入一个整数 $n$ ,输出 $[1,n]$ 的所有回文质数,我们规定 $1\sim9$ 也是回文数。 思路 首先我们需要了解什么是回文数,以及什么是质数。 简单点说,回文数就是正着读反着读都是一样的,也就是对称的,形如 $abcba $ 或者 $123321$ 这样的。 质数的话,对于一个数 $n$ ,如果他是质数,那它除了 $1$ 和 $n$ 没有其他因子。例如 $2,3,5,7,11$ 这样的。 那么接下来我们考虑一下解决这个问题应该怎么做,首先我们看一下数据范围,$[1,100000]$ ,还是挺小的,我们可以考虑直接枚举每一个数来判断它是不是回文数,然后再判断一下是不是质数,如果两个都满足,我们就输出它。 判断回文数,我们可以考虑到 NOJ05 幸运数 一题的解题思路,也就是说我们把一个数倒置过来,好比一个数 $xyz$ 倒置成 $zyx$ ,然后判断是否 $xyz == zyx$ ,如果相等的话就是回文数,如果不相等就不是。 判断质数,我们可以在 $[2,\lfloor\sqrt{n}\rfloor]$ 枚举它的因子,这个的完备性我上课的时候证明过,不再赘述。这里需要注意 $1,2$ 需要特判一下。 -代码 #include<stdio.h> #include<math.h> //我们需要用到sqrt函数,因此需要引入数学库 int main() { int n; bool flag = false; // 标记 i 是否满足条件 scanf("%d",&n); for(int i=1;i<=n;i++) { flag = true; int p=i,j=0; while(p) // 将 p 反转为 j { j=j*10+p%10; p/=10; } if(j==i) { if(j==1) continue; // 特判 1 if(j==2) // 特判 2 { printf("2\n"); continue; } int sqrtj = sqrt(j); for(int k=2;k<=sqrtj;k++) // 枚举 [2,sqrt(n)] { if(j%k==0) // 如果能够整除(余数为0),那么是 j 的因子 { flag = false; break; } } if(flag) { printf("%d\n",j); } } } } 其他 因为我们讲到这里的时候,我们没讲函数,但是这道题如果我们把判断是否为回文数,判断是否为质数,都另成一个函数模块,将使得程序变得更加简洁。我在这里也将函数版本的贴出来,有兴趣的可以看一下。...

              November 12, 2020 · 3 min · zzsqwq

              Visual Studio 2019 中 OpenCV 配置教程

              Windows 平台 Visual Studio 2019 中 OpenCV 配置教程 前言 我这里配置用的是4.5.0版本,但实际配置过程中需要的大部分时间只是路径,因此和版本基本无关。 +代码 #include<stdio.h> #include<math.h> //我们需要用到sqrt函数,因此需要引入数学库 int main() { int n; bool flag = false; // 标记 i 是否满足条件 scanf("%d",&n); for(int i=1;i<=n;i++) { flag = true; int p=i,j=0; while(p) // 将 p 反转为 j { j=j*10+p%10; p/=10; } if(j==i) { if(j==1) continue; // 特判 1 if(j==2) // 特判 2 { printf("2\n"); continue; } int sqrtj = sqrt(j); for(int k=2;k<=sqrtj;k++) // 枚举 [2,sqrt(n)] { if(j%k==0) // 如果能够整除(余数为0),那么是 j 的因子 { flag = false; break; } } if(flag) { printf("%d\n",j); } } } } 其他 因为我们讲到这里的时候,我们没讲函数,但是这道题如果我们把判断是否为回文数,判断是否为质数,都另成一个函数模块,将使得程序变得更加简洁。我在这里也将函数版本的贴出来,有兴趣的可以看一下。 +...

              November 12, 2020 · 3 min · zzsqwq

              Visual Studio 2019 中 OpenCV 配置教程

              Windows 平台 Visual Studio 2019 中 OpenCV 配置教程 前言 我这里配置用的是4.5.0版本,但实际配置过程中需要的大部分时间只是路径,因此和版本基本无关。 只有一个地方是和版本有关系的,在配置链接器的 opencv_wordxyzd.lib 时,大家一定要注意!! ...

              October 31, 2020 · 1 min · zzsqwq
              + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/posts/page/7/index.html b/posts/page/7/index.html index 5d6be7d6..13757e66 100644 --- a/posts/page/7/index.html +++ b/posts/page/7/index.html @@ -1,6 +1,6 @@ Posts | Zs's Blog -

              数据库的一些基础知识总结

              了解SQL 一.什么是SQL SQL是结构化查询语言(Structured Query Language)的缩写。是一种专门用来与数据库通信的语言。 +

              数据库的一些基础知识总结

              了解SQL 一.什么是SQL SQL是结构化查询语言(Structured Query Language)的缩写。是一种专门用来与数据库通信的语言。 二.什么是数据库? 数据库(Database):保存有组织的数据的容器(通常是一个文件或一组文件)。 ​[scode type = “yellow”]需要注意的是,有时候我们把数据库软件也简称为数据库,但是数据库软件和数据库有本质区别,数据库软件应称为DBMS(数据库管理系统),我们通过数据库软件对数据库进行删减等操作,他代替你操作和访问数据库。[/scode] 三.数据库的组成 表 数据库中通常有多张表,这类似于一个清单。就好像我们管理两个班级就可以用两个表单。 @@ -43,5 +43,5 @@

              + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/posts/page/8/index.html b/posts/page/8/index.html index 1f813cc4..e15bb421 100644 --- a/posts/page/8/index.html +++ b/posts/page/8/index.html @@ -1,6 +1,6 @@ Posts | Zs's Blog -

              Python初步学习

              Python学习笔记 Python的不同解释器 CPython +

              Python初步学习

              Python学习笔记 Python的不同解释器 CPython 这是自带的用C语言开发的解释器,因此叫CPython。它也是使用最广的Python解释器。 IPython 这是基于CPython之上的一个交互式解释器,只是相比于CPython多了交互上的优化。 @@ -12,5 +12,5 @@

              + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/posts/page/9/index.html b/posts/page/9/index.html index 897b02e3..fc416309 100644 --- a/posts/page/9/index.html +++ b/posts/page/9/index.html @@ -1,6 +1,6 @@ Posts | Zs's Blog -

              专题二:MATLAB矩阵处理

              2.1 特殊矩阵 通用的特殊矩阵 zeros函数: 产生全0矩阵,即零矩阵。 +

              专题二:MATLAB矩阵处理

              2.1 特殊矩阵 通用的特殊矩阵 zeros函数: 产生全0矩阵,即零矩阵。 ones函数: 产生全1函数,即幺矩阵。 eye函数: 产生对角线为1的矩阵,当矩阵为方针时,为单位矩阵。 rand函数: 产生 (0,1) 区间均匀分布的随机矩阵。 @@ -13,5 +13,5 @@

              + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/posts/summary-2022/index.html b/posts/summary-2022/index.html index fccbbd3f..5e0ef9c1 100644 --- a/posts/summary-2022/index.html +++ b/posts/summary-2022/index.html @@ -2,19 +2,29 @@

              2022 年度总结

              2022 依旧是被疫情伴随的一年,时间正着看总是要比回看慢很多,现在回头看过往一年似乎一瞬间就过去了。

              今年共发了 11 篇文章,其中还包含了两篇碎碎念,还是没有达到月更,新的一年希望可以。2022 年对我来说变化很大,算是暂时摆脱了学生生活,体验了社畜的感觉,打卡了北上广深中的北和深。

              接下来按月份盘点一些值得纪念的事情吧。


              一月

              这一月大多是在学校里度过的,封校了很长时间,封校期间报名了送餐志愿者,每天都负责给大家配送三餐,有点累,但是感觉能听到大家感谢的声音以及幸福的笑容还是很值得的,我感觉我一直还挺乐于助人的,帮助别人其实还挺快乐的。值得一提的是,因为之前总喜欢续费超级会员,疫情期间还建了一个宿舍群,送餐期间也兼职在群里传达各种信息,虽然是个吃力不讨好的活,还因为一些过激的言论被挂到知乎说是官僚主义。

              一月疫情回家

              二月

              二月换了手机(iPhone 13),加入了果粉的队列,并在心中种下了苹果全家桶的种子。还和家人一起去了青岛的海洋馆玩,和从未见过的网友学弟面了基。

              三月

              三月报名参加了 RMUS 2022 ,同时也在备赛 RMUA 2022 和准备大创的中期检查。搭建了一个新的 RMUA 场地。

              四月

              移植了一个学术风的 Hexo 主题,搞了一个自己的学术主页,计划用于后面的申请夏令营等。

              学术主页

              五月

              带队参加了 RMUA 2022,也担任了其中的赛事志愿者。今年的分组不错,可惜还是因为各种原因惨败了,很难受的一个月。回来还被隔离了七天,隔离的时候也无心学习,后面有考试和各种大作业的检查,这段时间是一年中最难受的时候。

              六月

              六月是考试月,各种考试、各种大作业、各种 DDL,压的人喘不过气来。

              在 6月12日,基地也搬了新的场地,大二上学期刚加入基地的时候,基地也是新搬场地,现在,基地又新搬了场地,我也该退休了。

              学术主页

              七月

              六月的结束也意味着学期的结束,假期的开始。七月学长邀请我去他公司实习,我欣然答应,于是我们就在学期结束后一起飞到了深圳,开始了社畜生活。在深圳的生活很愉快,也有了自己可以支配的收入,不再依赖于家里面的生活费了,也可以攒些小钱买自己想买的东西,这种感觉很棒。同时这个月还入手了 Airpods 3,空间音频给人的感觉很震撼。

              八月

              八月继续社畜,做了社畜以后有了比学生生活期间更多的活动,也吃了更多的好吃的,成了KFC、麦当劳、海底捞、肉蟹煲的常客,每天都稳定点两次外卖。这个月还看了《请回答1988》的解说,真的很好看,是令人暖心的剧集。

              九月

              九月要开学了,但是因为大四上学期已经没什么课了,而且深圳的疫情非常严重,没有返校。本月最重要的是我成了一名铲屎官(猫屎真的好臭😷),已经是人生赢家了,Siri 给他起名为卓卓

              同时九月也是保研名单公布和保研结束一段时间,再三考虑后决定放弃了保研名额,跟学长一起创业,先在港中文做 RA,后面或许可以去那里读 Ph.D,想出去看看。

              这个月还因为要做 iOS 开发公司给配了 Mac,现在已经拥有 iPhone、iPad、Mac、Airpods,距离 Apple 全家桶只有一步之遥。

              哦对了,这个月还搬了新的住所,因为人逐渐变多了,之前的屋子已经住不下了。九月,真是繁忙的一月。

              学术主页

              十月

              这个月初入手了 Apple Watch,补齐了个人设备的最后一块拼图算是。iMac 这种没有算进来,因为 iOS、iPadOS、MacOS、WatchOS 四个系统已经集齐了,苹果生态给人的感觉真的很不错。

              有了 Watch 以后,借着新鲜感锻炼了一段时间,但是体重不降反增了,于是动力没了,又回到了肥宅的生活😁。

              同时这个月还和乐乐和雷宝一起去了深圳的欢乐谷游玩,体验了失重的感觉,下次不敢了。

              学术主页

              十一月:平淡的一个月,上班、吃吃吃、玩玩玩。卓卓越来越好看了。

              学术主页

              十二月

              学长从 HK 带回来了最新版的 Apple TV,苹果生态又添一员。现在的联动已经非常棒了,手机可以直接推流到 Homepod、电视、Mac、耳机等。

              因为疫情放开了,我也体验了一次阳性的感觉,不过只高烧了一天就好了,也没感觉有什么后遗症,同居的六个人已经阳了四个,希望不会短期内再次感染🙏。这个月还和学长一起去了趟北京,不过只住了一天就回来了。

              这个月也抽时间购买了 FirstUI-uniapp 框架,把之前发单小程序的界面重构了一下,算是一步步的把之前的屎山代码给救了回来。因为在公司也担任了 Code Viewer 的角色,越发感觉代码风格对编程很重要,一个好的代码规范能够提升编程的效率,无论是自己还是团队,学编程语言应该必学代码规范。

              学术主页

              总的来说,今年要比去年精彩的多,可能是因为了保研结束了,当了社畜,没有考研的压力,有了很多玩乐的时间,也有了可以自己支配的收入,虽然不是很多,但是生活和娱乐已经够用。

              不过当了社畜,算是脱离了象牙塔进入了社会,也听到了各种各样在学校听不见的声音,引发了蛮多思考🤔。

              同时新的一年也看了更多的书、学到了很多新的知识,Modern C++、Rust、Swift、SwiftUI、Vue3 等等,拓宽了自己知识面。无限进步,无论什么时候都要坚持读书,我感觉读书仍是目前收益非常高的一个选择,即使读一些很久远的书,也能从中获得各种各样的启发,希望新的一年我也可以坚持不懈的读书

              \ No newline at end of file diff --git a/posts/summary-2023/index.html b/posts/summary-2023/index.html index b097701d..0bc6a2a3 100644 --- a/posts/summary-2023/index.html +++ b/posts/summary-2023/index.html @@ -1,60 +1,96 @@ 2023 年度总结 | Zs's Blog -

              2023 年度总结

              前言

              在回望过去时,我们常感叹时间飞逝,我想这或许是因为过去发生的无数大小事情最终在脑海中留存的只有寥寥几件。因此,撰写年度总结这件事似乎变得格外有意义,它能帮助我们更充分地回味过去的一年。可能正是因为如此,现在各大 APP 似乎都很喜欢推出年度总结,例如网易云、QQ音乐、知乎、飞书、京东、美团、支付宝等。为此,我写下了这篇 2023 年度总结。

              仔细回味我这过去的一年,我想用几个关键词来概括:#消费升级、#数码科技、#大模型、#老友重逢。

              #消费升级:这一年是我消费升级的一年,尽管今年「消费降级」这个词似乎很火,但我似乎与大众走上了一条相反的道路。可能是因为我以往的消费水平本就不高,所以「降级」更是无从谈起。

              #数码科技:这一年我购入了一些新的数码设备,虽然数量不多,但每一件都还挺满意的。同时今年由于消费观念的转变,也支持了很多正版软件,因此今年在软件上的开销也不小。

              #大模型:这一年也是我被大模型深刻影响的一年。虽然去年 ChatGPT 就已经面世,但各种大模型热潮的真正兴起还是在今年。仅短短一年的时间,大模型就已经渗透到了我日常生活和工作的方方面面,无论是电脑上的生产力工具(HapiGo)、编程使用的 IDE(JetBrains CLion)、浏览网页使用的浏览器(Microsoft Edge)还是日常娱乐使用的流媒体软件(Bilibili),都有着大模型的加持,让我的生活和工作流效率倍增。

              #老友重逢:看完下面就知道了~

              下面,还是照例按月份盘点下发生的大小事:

              一月

              这一个月包含了回家过年和返回深圳的往返之旅。在老家见了几个老同学,很开心。古人言人生四件快意的事 ——「久旱逢甘雨,他乡遇故知,洞房花烛夜,金榜挂名时」。虽然不是在「他乡」相遇,但仅是久别重逢就已足够令人欣喜。

              二月

              二月和朋友二刷了《流浪地球2》,这可能是我第一部影院二刷的电影,感觉细节满满,二刷还是有很多没注意到的点。

              同时这一月 Microsoft 联合 OpenAI 推出了 ChatGPT 加持的 New Bing,刚出时感觉很震撼,参见这个知乎回答,真的像有感情一样,有点细思极恐的感觉。虽然后续 Microsoft 对其进行了「改善」让他更少的表述情感,导致它现在变得有些弱智,远远比不上 GPT4,但它之前的表示还是很让我印象深刻。同时我想也正是这种 ChatGPT 对现有设施的加持和增强让 ChatGPT 彻底出圈,也算是后续大模型浪潮兴起的起点了。

              同时二月家里还来了个新朋友 —— 波妞,是只公布偶猫(虽然一开始以为是母的)。虽然是朋友养的,当时偶尔寄养在这边。但怎么说我也是短暂的成为了拥有两只猫的人了,值得记录一下。

              二者同框

              三月

              三月购入了新的显示器 —— LG 27UP850N-W,很满意,虽然感觉 27 寸用来办公还是稍大。但我购入的时候价格是 2599,这才短短一年时间就降到了 1999,太不保值了!但也只能用「早买早享受,晚买享折扣」来安慰自己了。

              哦还有一个就是三月开始尝试着健身了,深圳好吃的太多了,一直在不停的变肥。因此在周围一个健身房办了年卡,虽然没有几个月这个健身房就跑路了…不过这是后话了。

              加入新显示器后的桌面

              四月

              这个月入坑了《原神》,比较神奇的是几乎在同一时间也有个朋友 @HuaDeity 入坑。

              五月

              五月似乎是相对平淡的一月,在继续社畜日常的同时开始写毕设了。

              六月

              月初和朋友去海底捞过了生日,属于是 404 的「企业文化」了。然后终于把毕设给忙完了,返校进行了答辩,结果还算顺利。因为返校了也见了很多老朋友,舍友、基地的伙伴们、学弟们(是的应该是没有学妹),约了数不清次数的饭。

              基地的大伙聚会

              七月

              我正式本科毕业了。

              就像开头说的,回望过去总是很快。感觉开学和父母踏进工大校园的那一天还历历在目,转眼间就要毕业了。纵有万般不舍,但还是不得不和朋友们分别了,最后一晚大家一起在 KTV 合唱《朋友》的时候,忍不住泪奔。

              再见,工大

              八月

              相对平淡的一月,学弟来深圳参加夏令营,顺便过来找我玩,一起逛了腾讯大厦和华强北,看完感觉大厂平常的这些福利确实还是很不错的(不过确实加班严重)。

              九月

              九月病了一场,还把同寝的大伙给传染了,虽然最后没查出来是什么病,既不是甲流乙流也不是新冠,但是跟新冠的症状很像。生病了才发现这种穿戴设备(例如 Apple Watch)还是蛮有用的,可以量化一些健康相关的数据,例如深度睡眠时间、心率变异性指数(HRV)、静息心率,通过这些可以稍微早一些发现自己身体存在的问题。

              一些软件上的体现,从左往右依次是 AutoSleep、压力自测、Apple Health

              这月还规划了国庆假期游玩的路线,因此还从学长那里收了一个二手的 Nikon Z FC + NIKKOR 16-50mm 套机,同时还买了一颗长焦镜头 NIKKOR 50-250mm,不过国庆回来就把这颗镜头出掉了。凭心而论,相机体验还是很不错的,虽说只是个半画幅相机,但成像质量感觉还是要比目前的手机好一大截,在川西拿着它拍了很多照片,还发了条 小红书 记录。

              Nikon Z FC(熊猫热靴版)

              十月

              国庆假期狠狠的去川西自驾游了,大概是我人生中第一次这么「酣畅淋漓」的旅游。见到了贡嘎雪山和雅拉雪山的日照金山,体验了在冷嘎措 4600 米海拔徒步的感觉,不虚此行!当然最重要的,还是有这么多伙伴一起。

              这个月还看了广受好评的、被安利了无数次、感觉身边人都看过的《进击的巨人》,确实好看!感觉立体机动装置这个设定还挺不错的,可以画出来很多很帅的镜头,就像是人均蜘蛛侠一样。

              太美丽啦,贡嘎

              十一月

              十一月去北京参加了奇绩创坛的2023秋季路演。同时也见了在北京的老同学们,又是「他乡遇故知」!这大概也算是第一次在北京游玩了。

              还有一个不得不提的点是这月换了新的 Mac,其实本来是想换 M3 的 Macbook Air 的,但是今年的发布会没有发布 Air 只发布了 Pro,实在有点等不及了。但是 Pro 的话、感觉今年 M3 和 M3 Pro 提升比较小,甚至 M3 Pro 有牙膏倒吸的情况,导致性价比较低。所以最终换了一个官翻的 M2 Max 芯片的 Macbook Pro 版本,预计可以服役很久了,虽然实在是不便宜,但也是真的好用!这应该是今年我最满意的一件数码产品了,Mac 真的很好用!

              同时也正是从这个月双十一开始倒腾很多软件,一个直接原因是 数码荔枝 双十一有很多正版软件打折。关于 macOS 上的软件还有一个 未完成的总结帖 ,希望新的一年可以填上这个坑。

              购买的一些 Lifetime 软件

              十二月

              这个月我想想,大概是见到了八个许久未见的朋友,我愿称之为最幸福的一月。

              月中见到了一位了许久未见的老同学,来深圳好久了,但这个月才第一次见。相约一起去爬了塘朗山,第一次在深圳爬山,选了个比较小的山,还蛮轻松的。后续还见了一位许久未见的学弟。

              月底一个好兄弟考完研之后来我们这边住了一周,然后在月底也一起参加了公司的团建和跨年,乐爷也来一起团建来着。这个元旦假期真的可以说是爽玩了。

              这个月还冲动之下换了新的手机,之前的 iPhone 13 更新到 iOS 17 以后真的是卡爆了,可能是因为 iPhone 13 是 4GB 内存的原因,导致这个杀后台和卡顿的问题变得格外突出。不过一个神奇点是,我这个用了近两年的手机居然还可以在官方抵扣 3300,感觉血赚,很保值。

              新年快乐!

              总结

              写完回望一年,欢乐时光似乎大多与老友重逢相伴。感觉是因为今年大伙很多都离开了学校、分散在了世界各地,无论去哪里出差都能遇到老同学,分隔许久再见总是令人格外开心,仿佛有说不完的话。我想说,谢谢朋友们,新的一年也要多多联系&见面!

              这一年「置办」了几个新的大件,LG 显示器、Nikon Z FC、Macbook Pro、 iPhone 15 Pro,购买数码产品令我心情愉悦。现在持有的消费观念就是喜欢就冲,在自己力所能及的范围内尽可能的支持正版,不吝啬在于兴趣爱好方面的消费。

              同时今年虽然入坑了《原神》,但是玩了半年左右,通关了剧情就退坑了,游戏还是很不错的,就是长草期有点过于无聊了。感觉自己目前除了对数码相关的东西还有些兴趣,对其他的貌似都很兴致缺缺的样子,不知道算是好事还是坏事。

              新一年的希冀

              除了总结上一年,也对新的一年有一些希冀:

              1. 在年末辞旧迎新之际,少数派开始了「放轻松」系列征文活动,看到了一篇参选文章:放轻松 | 累了就休息,放松一下没关系,感觉很不错。里面提到了很多观点,例如放过自己、关注当下等让我感触颇深。

                这一年似乎可能是因为 All in 创业的原因,似乎无时无刻都在觉得自己太菜了(当然也不只有这一个原因),无法「堪当大任」,总是不由自主的焦虑,非常浮躁。这个时间看到这个文章,可能正是提醒我新的一年要更加关注自己的内心、关注当下、放过自己,让自己不再那么浮躁,学会 Take it easy。当然,有适当的压力可能也是好事,希望新的一年也可以多读书、多看报、少吃零食多睡觉,多多提升自己,最好也让自己更 E 一些,无限进步。

              关注当下大意就是:喝一杯茶就认真去品味这杯茶,总想着喝完茶之后的事情,这茶也就饮之无味,属于你的饮茶时间也就被偷走了。夜晚想着明天的事情难以入眠,那就关注躺在床上的自己,此刻的你不可能爬起来去做明天的事,想到这里便可以安心入睡;疼痛的时候就去感知疼痛,去关照你身体此刻的感受,不去想别的,它反而就没那么痛了。

              原来看问题还有这种角度?长久以来我做事确实都是魂不附体,思绪永远快于肉体,刷着牙想着等下要洗脸,洗着脸想着马上要洗澡,洗着澡,魂早飘到一会躺床上刷手机用什么姿势?总是很急,急来急去俨然一副空壳子,对生活的细节毫无感知,其实就是浮躁,而关注当下就是浮躁的解药,也是我在病前期意外抓到的一根救命稻草。听人劝吃饱饭,得益于此书,我的心态开始转变,关注当下进而去关照自身,帮助自己真正放松了下来。

              1. 再就是三月份提到的办了年卡的健身房,六月份跑路了。在多次协调无果、12315 也不起作用的情况下,尝试起诉了健身房,第一次尝试当原告,最终在 12 月末成功立案,希望新的一年可以起诉成功,到时候可以总结一下发个经验帖供大家参考。
              终于立案成功了,太不容易了。
              1. 希望新的一年能多拿着手机、相机出去走走。做年终总结的时候深感照片和文字记录的重要性。如果没有照片、没有朋友圈的一些文字,我可能根本想不起来那个月、那一天发生了什么。但是有了照片的帮助,我瞬间就能回忆起来我当时拍这张照片时的心情和场景,籍此前前后后的事情也能够串起来。

                照片不仅可以「冻结」那一瞬间,也可以「存储」一段记忆。

              感谢 Apple Photos 的时间线整理助我完成这篇文章
              © 2024 Zs's Blog + +加入新显示器后的桌面 +四月 +这个月入坑了《原神》,比较神奇的是几乎在同一时间也有个朋友 @HuaDeity 入坑。 +五月 +五月似乎是相对平淡的一月,在继续社畜日常的同时开始写毕设了。 +六月 +月初和朋友去海底捞过了生日,属于是 404 的「企业文化」了。然后终于把毕设给忙完了,返校进行了答辩,结果还算顺利。因为返校了也见了很多老朋友,舍友、基地的伙伴们、学弟们(是的应该是没有学妹),约了数不清次数的饭。 + +基地的大伙聚会 +七月 +我正式本科毕业了。">

              2023 年度总结

              前言

              在回望过去时,我们常感叹时间飞逝,我想这或许是因为过去发生的无数大小事情最终在脑海中留存的只有寥寥几件。因此,撰写年度总结这件事似乎变得格外有意义,它能帮助我们更充分地回味过去的一年。可能正是因为如此,现在各大 APP 似乎都很喜欢推出年度总结,例如网易云、QQ音乐、知乎、飞书、京东、美团、支付宝等。为此,我写下了这篇 2023 年度总结。

              仔细回味我这过去的一年,我想用几个关键词来概括:#消费升级、#数码科技、#大模型、#老友重逢。

              #消费升级:这一年是我消费升级的一年,尽管今年「消费降级」这个词似乎很火,但我似乎与大众走上了一条相反的道路。可能是因为我以往的消费水平本就不高,所以「降级」更是无从谈起。

              #数码科技:这一年我购入了一些新的数码设备,虽然数量不多,但每一件都还挺满意的。同时今年由于消费观念的转变,也支持了很多正版软件,因此今年在软件上的开销也不小。

              #大模型:这一年也是我被大模型深刻影响的一年。虽然去年 ChatGPT 就已经面世,但各种大模型热潮的真正兴起还是在今年。仅短短一年的时间,大模型就已经渗透到了我日常生活和工作的方方面面,无论是电脑上的生产力工具(HapiGo)、编程使用的 IDE(JetBrains CLion)、浏览网页使用的浏览器(Microsoft Edge)还是日常娱乐使用的流媒体软件(Bilibili),都有着大模型的加持,让我的生活和工作流效率倍增。

              #老友重逢:看完下面就知道了~

              下面,还是照例按月份盘点下发生的大小事:

              一月

              这一个月包含了回家过年和返回深圳的往返之旅。在老家见了几个老同学,很开心。古人言人生四件快意的事 ——「久旱逢甘雨,他乡遇故知,洞房花烛夜,金榜挂名时」。虽然不是在「他乡」相遇,但仅是久别重逢就已足够令人欣喜。

              二月

              二月和朋友二刷了《流浪地球2》,这可能是我第一部影院二刷的电影,感觉细节满满,二刷还是有很多没注意到的点。

              同时这一月 Microsoft 联合 OpenAI 推出了 ChatGPT 加持的 New Bing,刚出时感觉很震撼,参见这个知乎回答,真的像有感情一样,有点细思极恐的感觉。虽然后续 Microsoft 对其进行了「改善」让他更少的表述情感,导致它现在变得有些弱智,远远比不上 GPT4,但它之前的表示还是很让我印象深刻。同时我想也正是这种 ChatGPT 对现有设施的加持和增强让 ChatGPT 彻底出圈,也算是后续大模型浪潮兴起的起点了。

              同时二月家里还来了个新朋友 —— 波妞,是只公布偶猫(虽然一开始以为是母的)。虽然是朋友养的,当时偶尔寄养在这边。但怎么说我也是短暂的成为了拥有两只猫的人了,值得记录一下。

              二者同框

              三月

              三月购入了新的显示器 —— LG 27UP850N-W,很满意,虽然感觉 27 寸用来办公还是稍大。但我购入的时候价格是 2599,这才短短一年时间就降到了 1999,太不保值了!但也只能用「早买早享受,晚买享折扣」来安慰自己了。

              哦还有一个就是三月开始尝试着健身了,深圳好吃的太多了,一直在不停的变肥。因此在周围一个健身房办了年卡,虽然没有几个月这个健身房就跑路了…不过这是后话了。

              加入新显示器后的桌面

              四月

              这个月入坑了《原神》,比较神奇的是几乎在同一时间也有个朋友 @HuaDeity 入坑。

              五月

              五月似乎是相对平淡的一月,在继续社畜日常的同时开始写毕设了。

              六月

              月初和朋友去海底捞过了生日,属于是 404 的「企业文化」了。然后终于把毕设给忙完了,返校进行了答辩,结果还算顺利。因为返校了也见了很多老朋友,舍友、基地的伙伴们、学弟们(是的应该是没有学妹),约了数不清次数的饭。

              基地的大伙聚会

              七月

              我正式本科毕业了。

              就像开头说的,回望过去总是很快。感觉开学和父母踏进工大校园的那一天还历历在目,转眼间就要毕业了。纵有万般不舍,但还是不得不和朋友们分别了,最后一晚大家一起在 KTV 合唱《朋友》的时候,忍不住泪奔。

              再见,工大

              八月

              相对平淡的一月,学弟来深圳参加夏令营,顺便过来找我玩,一起逛了腾讯大厦和华强北,看完感觉大厂平常的这些福利确实还是很不错的(不过确实加班严重)。

              九月

              九月病了一场,还把同寝的大伙给传染了,虽然最后没查出来是什么病,既不是甲流乙流也不是新冠,但是跟新冠的症状很像。生病了才发现这种穿戴设备(例如 Apple Watch)还是蛮有用的,可以量化一些健康相关的数据,例如深度睡眠时间、心率变异性指数(HRV)、静息心率,通过这些可以稍微早一些发现自己身体存在的问题。

              一些软件上的体现,从左往右依次是 AutoSleep、压力自测、Apple Health

              这月还规划了国庆假期游玩的路线,因此还从学长那里收了一个二手的 Nikon Z FC + NIKKOR 16-50mm 套机,同时还买了一颗长焦镜头 NIKKOR 50-250mm,不过国庆回来就把这颗镜头出掉了。凭心而论,相机体验还是很不错的,虽说只是个半画幅相机,但成像质量感觉还是要比目前的手机好一大截,在川西拿着它拍了很多照片,还发了条 小红书 记录。

              Nikon Z FC(熊猫热靴版)

              十月

              国庆假期狠狠的去川西自驾游了,大概是我人生中第一次这么「酣畅淋漓」的旅游。见到了贡嘎雪山和雅拉雪山的日照金山,体验了在冷嘎措 4600 米海拔徒步的感觉,不虚此行!当然最重要的,还是有这么多伙伴一起。

              这个月还看了广受好评的、被安利了无数次、感觉身边人都看过的《进击的巨人》,确实好看!感觉立体机动装置这个设定还挺不错的,可以画出来很多很帅的镜头,就像是人均蜘蛛侠一样。

              太美丽啦,贡嘎

              十一月

              十一月去北京参加了奇绩创坛的2023秋季路演。同时也见了在北京的老同学们,又是「他乡遇故知」!这大概也算是第一次在北京游玩了。

              还有一个不得不提的点是这月换了新的 Mac,其实本来是想换 M3 的 Macbook Air 的,但是今年的发布会没有发布 Air 只发布了 Pro,实在有点等不及了。但是 Pro 的话、感觉今年 M3 和 M3 Pro 提升比较小,甚至 M3 Pro 有牙膏倒吸的情况,导致性价比较低。所以最终换了一个官翻的 M2 Max 芯片的 Macbook Pro 版本,预计可以服役很久了,虽然实在是不便宜,但也是真的好用!这应该是今年我最满意的一件数码产品了,Mac 真的很好用!

              同时也正是从这个月双十一开始倒腾很多软件,一个直接原因是 数码荔枝 双十一有很多正版软件打折。关于 macOS 上的软件还有一个 未完成的总结帖 ,希望新的一年可以填上这个坑。

              购买的一些 Lifetime 软件

              十二月

              这个月我想想,大概是见到了八个许久未见的朋友,我愿称之为最幸福的一月。

              月中见到了一位了许久未见的老同学,来深圳好久了,但这个月才第一次见。相约一起去爬了塘朗山,第一次在深圳爬山,选了个比较小的山,还蛮轻松的。后续还见了一位许久未见的学弟。

              月底一个好兄弟考完研之后来我们这边住了一周,然后在月底也一起参加了公司的团建和跨年,乐爷也来一起团建来着。这个元旦假期真的可以说是爽玩了。

              这个月还冲动之下换了新的手机,之前的 iPhone 13 更新到 iOS 17 以后真的是卡爆了,可能是因为 iPhone 13 是 4GB 内存的原因,导致这个杀后台和卡顿的问题变得格外突出。不过一个神奇点是,我这个用了近两年的手机居然还可以在官方抵扣 3300,感觉血赚,很保值。

              新年快乐!

              总结

              写完回望一年,欢乐时光似乎大多与老友重逢相伴。感觉是因为今年大伙很多都离开了学校、分散在了世界各地,无论去哪里出差都能遇到老同学,分隔许久再见总是令人格外开心,仿佛有说不完的话。我想说,谢谢朋友们,新的一年也要多多联系&见面!

              这一年「置办」了几个新的大件,LG 显示器、Nikon Z FC、Macbook Pro、 iPhone 15 Pro,购买数码产品令我心情愉悦。现在持有的消费观念就是喜欢就冲,在自己力所能及的范围内尽可能的支持正版,不吝啬在于兴趣爱好方面的消费。

              同时今年虽然入坑了《原神》,但是玩了半年左右,通关了剧情就退坑了,游戏还是很不错的,就是长草期有点过于无聊了。感觉自己目前除了对数码相关的东西还有些兴趣,对其他的貌似都很兴致缺缺的样子,不知道算是好事还是坏事。

              新一年的希冀

              除了总结上一年,也对新的一年有一些希冀:

              1. 在年末辞旧迎新之际,少数派开始了「放轻松」系列征文活动,看到了一篇参选文章:放轻松 | 累了就休息,放松一下没关系,感觉很不错。里面提到了很多观点,例如放过自己、关注当下等让我感触颇深。

                这一年似乎可能是因为 All in 创业的原因,似乎无时无刻都在觉得自己太菜了(当然也不只有这一个原因),无法「堪当大任」,总是不由自主的焦虑,非常浮躁。这个时间看到这个文章,可能正是提醒我新的一年要更加关注自己的内心、关注当下、放过自己,让自己不再那么浮躁,学会 Take it easy。当然,有适当的压力可能也是好事,希望新的一年也可以多读书、多看报、少吃零食多睡觉,多多提升自己,最好也让自己更 E 一些,无限进步。

              关注当下大意就是:喝一杯茶就认真去品味这杯茶,总想着喝完茶之后的事情,这茶也就饮之无味,属于你的饮茶时间也就被偷走了。夜晚想着明天的事情难以入眠,那就关注躺在床上的自己,此刻的你不可能爬起来去做明天的事,想到这里便可以安心入睡;疼痛的时候就去感知疼痛,去关照你身体此刻的感受,不去想别的,它反而就没那么痛了。

              原来看问题还有这种角度?长久以来我做事确实都是魂不附体,思绪永远快于肉体,刷着牙想着等下要洗脸,洗着脸想着马上要洗澡,洗着澡,魂早飘到一会躺床上刷手机用什么姿势?总是很急,急来急去俨然一副空壳子,对生活的细节毫无感知,其实就是浮躁,而关注当下就是浮躁的解药,也是我在病前期意外抓到的一根救命稻草。听人劝吃饱饭,得益于此书,我的心态开始转变,关注当下进而去关照自身,帮助自己真正放松了下来。

              1. 再就是三月份提到的办了年卡的健身房,六月份跑路了。在多次协调无果、12315 也不起作用的情况下,尝试起诉了健身房,第一次尝试当原告,最终在 12 月末成功立案,希望新的一年可以起诉成功,到时候可以总结一下发个经验帖供大家参考。
              终于立案成功了,太不容易了。
              1. 希望新的一年能多拿着手机、相机出去走走。做年终总结的时候深感照片和文字记录的重要性。如果没有照片、没有朋友圈的一些文字,我可能根本想不起来那个月、那一天发生了什么。但是有了照片的帮助,我瞬间就能回忆起来我当时拍这张照片时的心情和场景,籍此前前后后的事情也能够串起来。

                照片不仅可以「冻结」那一瞬间,也可以「存储」一段记忆。

              感谢 Apple Photos 的时间线整理助我完成这篇文章
              + PaperMod | 鲁ICP备2020034310号
              \ No newline at end of file diff --git a/posts/why-should-boycott-pdd/index.html b/posts/why-should-boycott-pdd/index.html index c74009fd..60dc069c 100644 --- a/posts/why-should-boycott-pdd/index.html +++ b/posts/why-should-boycott-pdd/index.html @@ -1,58 +1,133 @@ 为什么应该抵制拼多多? | Zs's Blog -

              为什么应该抵制拼多多?

              TL;DR

              本文旨在结合一系列事实总结拼多多过去的一系列恶心行为,包括不限于

              • 虚假宣传
              • 砍一刀套路多
              • 拉人助力
              • 铺天盖地的广告
              • 利用漏洞

              希望大家抵制拼多多这种无良平台,非必要不使用拼多多。

              前言

              最近看了很多拼多多令人反感的操作以及看了很多拼多多的软广,如 拼多多,让谁不爽,看到这么一个无良平台逐渐壮大实在是令人恼火,因此我觉得有必要写一篇文章来总结一下拼多多各种恶心人的操作来让大家了解这个无良平台,来看看他到底为什么让人不爽,并呼吁大家可以联合抵制这个平台。

              本文会尽量客观理性,陈述已发生的事实而不是自己的观点,同时因为我不是商家,也不是拼多多的员工,本文只是作为用户角度评判。除了对用户方面的恶心行为,还有对员工及商家的压榨,这个后面有时间再写。欢迎大家补充、批评、指正。

              一、虚假宣传

              首先需要提到的就是拼多多的虚假宣传,主要是广告,相信大家都看到过,例如「为什么这些 Switch 游戏机只买 9.9 元都没人买,全部砸了算了」这种开头的,或者「你有 iPhone 13 吗,没有就打开拼多多抢一台」。铺天盖地的,无论是你看视频、还是刷QQ空间,还是刷朋友圈,总是能碰到这种广告,无非就是诱惑你点击下载拼多多,但是打开后却发现广告中说的点击就送、无门槛拿根本都是无稽之谈,要不就是限量两个,邀请最多的人才能领。下面是这类视频的合集,大家可能看到的时候都觉得尬和乐,但是却很少有人认识到这是虚假宣传,违规行为。

              根据百度百科对于虚假宣传的定义:

              虚假宣传是指在商业活动中经营者利用广告或其他方法对商品或者服务做出与实际内容不相符的虚假信息,导致客户或消费者误解的行为。

              这拼多多应该确实是符合的吧?虽然很多只是下载了 App 但是没有产生消费行为,但也可以归入其中。

              二、砍一刀套路多

              套路多是指,经过第一步的虚假宣传,让你下载了 App,你以为可以很轻松的拿到免单的商品,但实际他会给你放一堆的限制,就像十年前的页游,一堆过场动画,什么「你是砍价第一名」、「还差 0.01 即可砍成功」,但你一旦继续深入,你就会发现这是个无底洞,0.01 后面是 0.001,0.001 后面是 0.0001,0.0001 后面怕你看数字太小生气,他就会让你集几万个金币或者一些其他的东西,十万个金币兑换 0.001,这样无限循环,想砍成实在难如登天。

              拼多多曾公开表示1

              近日,“拼多多砍价,但始终差0.9%”话题受到广泛关注,去年3月,上海律师刘宇航参加了拼多多的“砍价免费拿”活动后,经多人砍价还是0.9%,在质疑数据有问题后,刘以使用虚假数据隐瞒规则已构成欺诈为由,向法院递交了起诉材料。在刘宇航随后释出的文件中得知,拼多多称是“因页面显示百分比位数有限,所以他们把一个至少小数点后有6位数以上的百分比,省略显示为0.9%,砍价页面显示的0.9%不是0.9%,而是0.9996427%。”

              当然这里也有砍成功的,不过是分价位的,你砍 100 元的红包,可能拉个七八个人就成功,如果都是新用户可能会更少,如果是砍 Switch、手机这种大件,需要砍的次数则就更多。当然砍 100 元的红包砍的多了,积累的价钱上去了,他也不会让你持续的薅,难度也是累加的。一个典型的案例可以看 超级小桀 之前的视频,如下:

              上面这个视频简单概括一下就是,小桀在直播间突发奇想带水友一起砍一部 IQOO 手机,前期很长的过场动画都在提示你,马上可以直接拿到,进度已经到达 0.00%,但是还是需要收集 10 多个金币,邀请两三个人即可,后来小桀把二维码分享出来,非常多的水友扫码砍,后来导致二维码提示被封禁,小桀又把链接分享给了群里的水友,当时在线的水友不完全统计 6-7W,至少有上千人参与,但最终也没有让那 10 多个金币归零,打电话给客服询问,客服给出理由如下:

              1. 每个人砍都是概率砍成功,可能 100 人砍有 50 个人、80 个人砍成功,不是 100% 成功。
              2. 像这么多人砍价,系统检测到会封禁。

              那我就有点疑问了,你这个东西本来就需要邀请很多人砍价才能成功,但是你人一多又要封禁,那么不邀请这么多人砍价,那么怎么成功呢?真的是「解释权归拼多多所有」。

              据小桀自己回应,直到3月17号下午2点40分左右下播,也没有砍成功,但是突然在4点40分左右莫名其妙的成功了,赠送了一张无门槛购物券可以下单此手机,随后客服回应:砍价不成功不属实,已经发放「特制」优惠券。这一通操作,实在是闻所未闻,谁也能看出来是事态发展到不可预料的地步搞了个东西出来封口的。

              实在是太像诈骗、传销了,即使这样广泛的虚假宣传,到现在也没有被整治,也还是随处可见。

              附小桀对这件事情的声明:

              三、拉人助力

              拼多多最特色的行为,应该就是这个拉人助力,可能算是拉人助力的始祖了,如今算是各个软件的标配了,美团、饿了么、携程旅行、智行中也都随处可见。好处显而易见,可以提高自己活动的参与率、提高 App 的下载率、提高品牌知名度、提高用户粘性。

              具体的规则就是加速某件任务进程,免单某一件物品、领取某个红包、浇灌某个植物,你都需要「拉人助力」。顾名思义就是要分享这个链接或者二维码给他人,让他来点击助力。

              这会迫使身边的亲戚、朋友、家人都会向你发送链接助力,如果大家都用拼多多,那还好,你助力我我助力你,皆大欢喜。而如果你不用拼多多,甚至可能因为拼多多垃圾广告多,App 臃肿、漠视用户隐私等问题反感厌恶拼多多,可能会想要拒绝对方,但是直接拒绝大家两方都不好看,可能会说个客气话:「抱歉,我没下拼多多」。你可能以为可以通过这句话逃过一劫,而你没想到,拼多多会区分新用户和老用户,新用户助力的多,老用户助力的少,长时间不用的人助力也会要比那些常用者多一些。对方听到这个更开心了,因为你可以帮他加快更多的进度。这时候你可能只能不情愿的下载助力,或者和对方直说,那可能就会让两边都闹的不愉快,对方可能觉得:「只是个简单的助力而已,有什么好计较的?下载以后删掉不就好了。」,而你可能不这么认为,就会让原来稳固的关系出现裂隙,让这个社会的人际关系变得更加的脆弱,让人与人之间的交心程度变得越来越低。

              甚至更别说那种在路边突然拦住你让你帮忙助力的人,虽然我没遇到过,但是听很多人说遇到过,想想就令人恶心。

              四、铺天盖地的广告

              不知从什么时候开始,拼多多的广告就到处都是了,远多于其他产品及平台的广告。

              广告分不同的类型以及投放方式:

              • 对于秒杀、拉人头类的广告,多出现在各种订阅号、QQ空间、小程序、小游戏广告中,内容就是上面提到的虚假宣传,例如什么「现在点击下方链接下载拼多多,即可立即 9.9 元秒杀 Switch 游戏机」。
              • 对于百亿补贴类型的广告,多出现在 Bilibili 以及微信公众号(可能还有抖音等位置,因为我不使用,故不得而知),每次看各种UP主视频的,就会突然说起来买什么东西太贵了或者什么东西太贵了,就开始推荐拼多多的百亿补贴。除此以外,还会几乎每周固定的一次的集体刷屏,超多UP主一起在动态发,超多公众号一起发,标题都是如「苹果又跌破历史新低」这种。

              这个可能是合法的,只是这种过量的宣发我认为很令人不适,容易引起反感。

              五、利用漏洞

              认可白帽黑客价值、走进安全社区,打造安全团队,借助黑客视角提升自身安全能力,这已经成为了行业最佳安全实践之一。

              但是,也有少数地下或隐蔽的公司通过招募黑客,用他们掌握的黑客技术寻找并利用漏洞,为自身牟取非法利益。

              2022 年,竟有巨头公司打破底线,将白帽黑客作为武器,指向了用户。

              2023年2月28日,DarkNavy深蓝 发布了一篇名为 「DarkNavy深蓝洞察」2022年度十大漏洞与利用:最“不可赦”漏洞利用 的文章,文章指出有一个互联网厂商利用了安卓手机中的高危漏洞,在其看似合法的 App 背后,达到了:

              • 隐蔽安装,提升装机量
              • 伪造提升 DAU/MAU
              • 用户无法卸载
              • 攻击竞争对手 App
              • 窃取用户隐私数据
              • 逃避隐私合规监管

              等各种涉嫌违规违法目的,但并未点名该 App 是谁。

              此文一出,持续发酵,各种线索均指向了一个 App —— 拼多多。

              随着研究的深入,基本已经实锤拼多多,包括不限于各种行内安全大佬的分析2,谷歌在 Google Play 下架拼多多,并提示他为恶意软件,最终在2023年3月27号,卡巴斯基实验室的安全研究人员证实拼多多 App 包含恶意代码3。在对恶意代码的首批公开报告之一中,卡巴斯基阐述了该应用程序如何提升自身权限以破坏用户隐私和数据安全。它测试了通过中国本地应用商店分发的应用版本 —— 包含来自华为、腾讯和小米的应用市场。

              同时更令人恶心的是,「目前没有证据表明 Google Play Store 和苹果 App Store 的版本含有恶意代码,通过 Google 和苹果官方商店下载的拼多多应用是安全的。但通过第三方市场下载的 Android 用户则没有那么幸运了,鉴于拼多多有数亿用户,受影响的用户数量可能是非常惊人」,也就是说拼多多这还是定向打击、定向投毒,是看咱们国人好欺负?大家可能对于这种事情向来是不关心,能用就行可能就是大多数人奉行的宗旨,管他对我做了什么,管他有没有什么违法的事情,一味的这样只会助长拼多多这种恶心平台与 App 的气焰。

              img

              目前拼多多已经替换了利用漏洞 App 以及解散了漏洞挖掘与利用相关的团队,不过也有消息称仍有部份人留任继续挖掘。

              被谷歌下架半个月后,拼多多平台内的恶意功能逐渐浮出水面。根据公开资料显示,近日匿名拼多多员工称,公司在 2020 年组建了一支由大约 100 名工程师和产品经理组成的团队,致力于挖掘 Android 手机漏洞,开发漏洞利用方法,将其转化为利润。

              此外,消息源称,拼多多应用的恶意功能最初只针对农村和小城镇的用户,避开北京上海之类大都市的用户,此举旨在降低被暴露的风险。通过收集用户活动的大量数据,拼多多能全面了解用户习惯、兴趣和偏好,改进其机器学习模型,提供更具有个性化的推送通知和广告,吸引用户打开应用并下单。在被曝光之后该团队于三月初被解散。

              同时,截止目前为止,网信办也没有公布任何对拼多多不法行为的追责。一个人要转头多少次,还假装视而不见。315晚会上也没有拼多多,都是些不痛不痒的事情,加起来也没拼多多恶心。法律没有惩治拼多多,反而拼多多自己在用着这些法律武器来追责那些对他「抹黑」的人,明明事实都已经摆在台面上了,还是可以嘴硬,就好像只要自己一味的否定自己做过的事情,就真的可以当作事情没发生过,谎话说多了自己都信了。

              昨日,OSCHINA 微信公众号此前报道的相关文章《某国产电商 APP 利用 Android 漏洞细节曝光:内嵌提权代码、动态下发 Dex》收到了来自拼多多主体公司的投诉,投诉类型是 “内容侵犯名誉 / 商誉 / 隐私 / 肖像”。然而那篇文章从头到尾都没有指名道姓地说是哪家公司、哪款 APP。3

              img

              结语

              可能有人会说,拼多多就那么一无是处,一点优点都没有吗?

              要说优点,还是有的,例如百亿补贴、小物件免邮、新鲜水果便宜、签到打卡浇水领各种东西、支持仅退款,相对利好消费者、用户下沉做得好,利好农村的人们。但这不是本文讨论的范围,我只是总结他的恶行,你也可以去多了解拼多多的好处,用不用还是需要自己权衡。

              即使如此,但是我仍想说,他做了好事不代表你要忘记了他的恶,如果不用实际行动去抵制它,一味的迁就它,那这样它只会觉得大家好欺负,继续肆无忌惮的做恶心的事情。希望看到文章的大家都可以在使用拼多多前想想,我是不是必须要用它才行,如果不是,那么就应该用其他平台,而不是——拼多多。

              \ No newline at end of file diff --git a/posts/why-use-condition-variable/index.html b/posts/why-use-condition-variable/index.html index d30991c1..01c057e8 100644 --- a/posts/why-use-condition-variable/index.html +++ b/posts/why-use-condition-variable/index.html @@ -1,17 +1,362 @@ 为什么要使用条件变量? | Zs's Blog - #include #include #include #include #include int main() { std::queue produced_nums; std::mutex mtx; // 生产者 auto producer = [&]() { for (int i = 0; ; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(900)); std::unique_lock lock(mtx); std::cout << "producing " << i << std::endl; produced_nums.push(i); } }; // 消费者 auto consumer = [&]() { while (true) { { std::unique_lock lock(mtx); if(produced_nums.'>

              为什么要使用条件变量?

              为什么要使用条件变量?

              前言

              最近看了很多与线程有关的 C++ 新特性,条件变量是见的比较多的一个特性。

              看的时候我发现,想要理解一个新的特性,关键的要看它的引入到底解决了哪些问题,没有什么特性我们要实现相同的功能要怎么做?

              以我的理解来看,条件变量是一个线程间互相同步与通知的手段,他通过主动唤醒的方式减小了各个线程的开销,取代了简单但是消耗较大的一直被动循环检验与等待

              没有条件变量我们如何实现相同的需求?

              这里采用现代C++教程1 中关于条件变量的一个例子作为基础:

              不使用条件变量版本

              #include <queue>
              +没有条件变量我们如何实现相同的需求?
              +这里采用现代C++教程1 中关于条件变量的一个例子作为基础:
              +不使用条件变量版本
              +#include 
              +#include 
              +#include 
              +#include 
              +#include 
              +#include 
              +
              +
              +int main() {
              +    std::queue produced_nums;
              +    std::mutex mtx;
              +
              +    // 生产者
              +    auto producer = [&]() {
              +        for (int i = 0; ; i++) {
              +            std::this_thread::sleep_for(std::chrono::milliseconds(900));
              +            std::unique_lock lock(mtx);
              +            std::cout << "producing " << i << std::endl;
              +            produced_nums.push(i);
              +        }
              +    };
              +    // 消费者
              +    auto consumer = [&]() {
              +        while (true) {
              +            {
              +              std::unique_lock lock(mtx);
              +              if(produced_nums.empty()) continue;
              +            }
              +            std::unique_lock lock(mtx);
              +            // 短暂取消锁,使得生产者有机会在消费者消费空前继续生产
              +            lock.unlock();
              +            // 消费者慢于生产者
              +            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
              +            lock.lock();
              +            while (!produced_nums.empty()) {
              +                std::cout << "consuming " << produced_nums.front() << std::endl;
              +                produced_nums.pop();
              +            }
              +        }
              +    };
              +
              +    // 分别在不同的线程中运行
              +    std::thread p(producer);
              +    std::thread cs[2];
              +    for (int i = 0; i < 2; ++i) {
              +        cs[i] = std::thread(consumer);
              +    }
              +    p.join();
              +    for (int i = 0; i < 2; ++i) {
              +        cs[i].join();
              +    }
              +    return 0;
              +}
              +使用条件变量版本
              +#include 
              +#include 
              +#include 
              +#include 
              +#include 
              +#include 
              +
              +
              +int main() {
              +    std::queue produced_nums;
              +    std::mutex mtx;
              +    std::condition_variable cv;
              +    bool notified = false;  // 通知信号
              +
              +    // 生产者
              +    auto producer = [&]() {
              +        for (int i = 0; ; i++) {
              +            std::this_thread::sleep_for(std::chrono::milliseconds(900));
              +            std::unique_lock lock(mtx);
              +            std::cout << "producing " << i << std::endl;
              +            produced_nums.push(i);
              +            notified = true;
              +            cv.notify_all(); // 此处也可以使用 notify_one
              +        }
              +    };
              +    // 消费者
              +    auto consumer = [&]() {
              +        while (true) {
              +            std::unique_lock lock(mtx);
              +            while (!notified) {  // 避免虚假唤醒
              +                cv.wait(lock);
              +            }
              +            // 短暂取消锁,使得生产者有机会在消费者消费空前继续生产
              +            lock.unlock();
              +            // 消费者慢于生产者
              +            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
              +            lock.lock();
              +            while (!produced_nums.empty()) {
              +                std::cout << "consuming " << produced_nums.front() << std::endl;
              +                produced_nums.pop();
              +            }
              +            notified = false;
              +        }
              +    };
              +
              +    // 分别在不同的线程中运行
              +    std::thread p(producer);
              +    std::thread cs[2];
              +    for (int i = 0; i < 2; ++i) {
              +        cs[i] = std::thread(consumer);
              +    }
              +    p.join();
              +    for (int i = 0; i < 2; ++i) {
              +        cs[i].join();
              +    }
              +    return 0;
              +}
              +这两段代码在效果上是等效的,都是一个生产者两个消费者。'>

              为什么要使用条件变量?

              为什么要使用条件变量?

              前言

              最近看了很多与线程有关的 C++ 新特性,条件变量是见的比较多的一个特性。

              看的时候我发现,想要理解一个新的特性,关键的要看它的引入到底解决了哪些问题,没有什么特性我们要实现相同的功能要怎么做?

              以我的理解来看,条件变量是一个线程间互相同步与通知的手段,他通过主动唤醒的方式减小了各个线程的开销,取代了简单但是消耗较大的一直被动循环检验与等待

              没有条件变量我们如何实现相同的需求?

              这里采用现代C++教程1 中关于条件变量的一个例子作为基础:

              不使用条件变量版本

              #include <queue>
               #include <chrono>
               #include <mutex>
               #include <thread>
              @@ -141,5 +486,5 @@
               
              + PaperMod | 鲁ICP备2020034310号
              \ No newline at end of file diff --git a/search/index.html b/search/index.html index c9b07193..979dbab7 100644 --- a/search/index.html +++ b/search/index.html @@ -1,6 +1,6 @@ Search | Zs's Blog -
              © 2024 Zs's Blog +
              + PaperMod | 鲁ICP备2020034310号
              \ No newline at end of file diff --git a/series/index.html b/series/index.html index 69977466..c6ec1c1d 100644 --- a/series/index.html +++ b/series/index.html @@ -1,6 +1,6 @@ Series | Zs's Blog -
                © 2024 Zs's Blog +
                  + PaperMod | 鲁ICP备2020034310号
                  \ No newline at end of file diff --git a/tags/academia/index.html b/tags/academia/index.html index 77c0c43a..c2b98125 100644 --- a/tags/academia/index.html +++ b/tags/academia/index.html @@ -1,6 +1,6 @@ Academia | Zs's Blog -

                  一个基于 Hugo 的个人主页主题

                  背景 之前看到过学长学姐做过个人主页,多是用来申请一些学校的夏令营使用的,觉得非常的 Nice,自己也想搞一个。 +

                  一个基于 Hugo 的个人主页主题

                  背景 之前看到过学长学姐做过个人主页,多是用来申请一些学校的夏令营使用的,觉得非常的 Nice,自己也想搞一个。 大家之前好像大多用的是基于 Hexo 的一个主题 — hexo-theme-academia,但是由于之前我用过 Hexo,觉得他有一些比较明显的弊端,例如环境配置比较麻烦、需要安装 Nodejs、npm 等环境,然后再安装 Hexo。其次它的构建速度比较慢,用起来感觉比较僵硬。 后来随着了解增多,尝试了 Typecho、WordPress,Hugo 等主题后,目前还是决定使用 Hugo。它构建速度快,而且安装简单,在 Ubuntu 上只需要一行 sudo apt install hugo 即可,不可谓不简单。因此萌生了移植一个 Hugo 版本主题的想法,刚好可以锻炼一下自己。 欢迎点击 这里 查看我的个人主页。 @@ -18,5 +18,5 @@ 中文效果图:

                  May 3, 2022 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/app/index.html b/tags/app/index.html index 2904e8e4..fe2ae103 100644 --- a/tags/app/index.html +++ b/tags/app/index.html @@ -1,12 +1,13 @@ App | Zs's Blog -

                  App 使用体会记录 - macOS 篇

                  平时很喜欢倒腾各种 Apple 平台的各种软件,所以体验了很多 iOS/iPadOS/macOS 上的软件,所以计划汇总一下自己的一些简短的使用体验和评价等,希望能在大家后续选择软件的时候起到一些参考和帮助。 +

                  App 使用体会记录 - macOS 篇

                  平时很喜欢倒腾各种 Apple 平台的各种软件,所以体验了很多 iOS/iPadOS/macOS 上的软件,所以计划汇总一下自己的一些简短的使用体验和评价等,希望能在大家后续选择软件的时候起到一些参考和帮助。 由于软件可能较多,不能一次性写完。同时,因为我也在不断体验新的软件,有新的感受,因此这篇博客应该是持续更新的,欢迎常来看看。 -速览表 App 名称 简短描述 功能限制 订阅形式 价格 购入时间 购入渠道 同类型产品 AIDente 电池电量管理 有免费使用功能,但有共功能需要收费 买断 Free Battery, BatFi AdGuard 广告拦截软件 AltTab 增强 macOS App 切换 Command-Tab Plus, Contexts,HyperSwitch, Bartender 5 Menubar 管理 Bob 大概是最好用翻译软件 EasyDict BuhoCleaner 垃圾清理器/软件卸载器 CleanMyMac, Sensei Clash X / Clash X Pro 代理 Surge, Stash CleanBuddy 键盘锁定清理 Cleaner CleanShot X 大概最好用的截图软件 Cleaner 键盘屏幕锁定清理 CleanBuddy Dash 文档利器 Dato Menubar 日历软件 Fantastical, Itsycal DevUtils 开发小工具合集 Downie 4 各类视频下载器 VDown HapiGo 启动器 Alfred, Raycast HazeOver 生产力工具,突出重点 Hazel 自动清理集合 JetBrains 全家桶 包含 Clion/IDEA 等 VSCode, Eclipse Lunar 显示器管理 MonitorControl, DisplayBuddy, Better Display Maccy 开源免费的剪切板管理工具 Paste, PasteNow, PastePal Manico 快速启动器 Command-Tab Plus MimeStram Gmail 客户端 MonitorControl 开源显示器管理,很够用 Lunar, DisplayBuddy, Better Display NetNewsWire 全平台 RSS 阅读器 Obsidian 笔记软件 Omnivore 稍后读软件 Pocket, MarkMark, Only Switch 一键完成各种任务 One Switch OpenImageOptim 图片压缩 TinyPNG OrbStack 容器管理,平替 Docker Desktop Docker Desktop, Podman, lima, colima Permute 3 图片/视频格式转换工具,类似于格式工厂 HandBrake, Omni Converter, Video Converter X2 Pixea 图片查看器 Viso, Picsee Pixelmator Pro 图片编辑器,80% 平替 PhotoShop Adobe PhotoShop, Darkroom, Photomator, Capture One, Adobe LightRoom Classic PopClip 划词增强 Proxyman 大概是舒服的抓包工具,略贵 Charles Rectangle 分屏软件 Magnet, Swish Swish 触控板手势增强 Stats Menubar 状态监控 iStats Menu, Sensei Subscriptions 订阅管理 Pandora on iOS Surge 代理工具 Clash X, Stash TinyPNG 图片压缩 OpenImageOptim Typora Markdown 文本编辑器 Obsidian Upscayl AI 图片超分 AI Photo Enhancer by Pictura, Pixelmator Pro Viso 6 图片查看器 Pixea, Xee Zotero 文献管理,就是界面一般 coconutBattery iPhone/iPad/Mac 电池信息查看 iRightMenu 右键增强 超级右键, iMouse, iTerm2 终端模拟器 Alacritty, Warp, Wezterm, Terminal 详细信息 AIDente 介绍:可以限制充电上限,据称电池电量维持在 70-80% 是比较健康的,不适宜过高。...

                  December 3, 2023 · 2 min · zzsqwq

                  My App Defaults - 2023 Fall

                  After seeing Duel of the Defaults and App Defaults, I’d like to share here some of my app defaults at the end of 2023. +速览表 App 名称 简短描述 功能限制 订阅形式 价格 购入时间 购入渠道 同类型产品 AIDente 电池电量管理 有免费使用功能,但有共功能需要收费 买断 Free Battery, BatFi AdGuard 广告拦截软件 AltTab 增强 macOS App 切换 Command-Tab Plus, Contexts,HyperSwitch, Bartender 5 Menubar 管理 Bob 大概是最好用翻译软件 EasyDict BuhoCleaner 垃圾清理器/软件卸载器 CleanMyMac, Sensei Clash X / Clash X Pro 代理 Surge, Stash CleanBuddy 键盘锁定清理 Cleaner CleanShot X 大概最好用的截图软件 Cleaner 键盘屏幕锁定清理 CleanBuddy Dash 文档利器 Dato Menubar 日历软件 Fantastical, Itsycal DevUtils 开发小工具合集 Downie 4 各类视频下载器 VDown HapiGo 启动器 Alfred, Raycast HazeOver 生产力工具,突出重点 Hazel 自动清理集合 JetBrains 全家桶 包含 Clion/IDEA 等 VSCode, Eclipse Lunar 显示器管理 MonitorControl, DisplayBuddy, Better Display Maccy 开源免费的剪切板管理工具 Paste, PasteNow, PastePal Manico 快速启动器 Command-Tab Plus MimeStram Gmail 客户端 MonitorControl 开源显示器管理,很够用 Lunar, DisplayBuddy, Better Display NetNewsWire 全平台 RSS 阅读器 Obsidian 笔记软件 Omnivore 稍后读软件 Pocket, MarkMark, Only Switch 一键完成各种任务 One Switch OpenImageOptim 图片压缩 TinyPNG OrbStack 容器管理,平替 Docker Desktop Docker Desktop, Podman, lima, colima Permute 3 图片/视频格式转换工具,类似于格式工厂 HandBrake, Omni Converter, Video Converter X2 Pixea 图片查看器 Viso, Picsee Pixelmator Pro 图片编辑器,80% 平替 PhotoShop Adobe PhotoShop, Darkroom, Photomator, Capture One, Adobe LightRoom Classic PopClip 划词增强 Proxyman 大概是舒服的抓包工具,略贵 Charles Rectangle 分屏软件 Magnet, Swish Swish 触控板手势增强 Stats Menubar 状态监控 iStats Menu, Sensei Subscriptions 订阅管理 Pandora on iOS Surge 代理工具 Clash X, Stash TinyPNG 图片压缩 OpenImageOptim Typora Markdown 文本编辑器 Obsidian Upscayl AI 图片超分 AI Photo Enhancer by Pictura, Pixelmator Pro Viso 6 图片查看器 Pixea, Xee Zotero 文献管理,就是界面一般 coconutBattery iPhone/iPad/Mac 电池信息查看 iRightMenu 右键增强 超级右键, iMouse, iTerm2 终端模拟器 Alacritty, Warp, Wezterm, Terminal 详细信息 AIDente 介绍:可以限制充电上限,据称电池电量维持在 70-80% 是比较健康的,不适宜过高。 +...

                  December 3, 2023 · 2 min · zzsqwq

                  My App Defaults - 2023 Fall

                  After seeing Duel of the Defaults and App Defaults, I’d like to share here some of my app defaults at the end of 2023. Since I am from China, some apps may not be suitable to everyone, such as WeChat, NeteaseMusic, etc. The software built-in on iPhone or Mac will have the .app extension. -📨 Mail Client:Gmail, Mail.app 📮 Mail Server:Gmail 📝 Notes:Obsidian, Typora, Notes.app ✅ To-Do:Reminders.app 📷 iPhone Photo Shooting: Camera....

                  December 3, 2023 · 1 min · zzsqwq
                  © 2024 Zs's Blog +📨 Mail Client:Gmail, Mail.app 📮 Mail Server:Gmail 📝 Notes:Obsidian, Typora, Notes.app ✅ To-Do:Reminders.app 📷 iPhone Photo Shooting: Camera.app 📸 Photo Shooting: Nikon ZFC, iPhone 13 🟦 Photo Management & Editing: Photos.app, Capture One, Pixelmator Pro 📆 Calendar: Dato, Calendar.app 📁 Cloud File Storage: iCloud Drive 📖 RSS Client: NetNewsWire 📖 RSS Server: FreshRSS with RSSHub 🙍🏻‍♂️ Contacts: Contacts.app 🌐 Browser: Microsoft Edge 💬 Chat: Telegram, WeChat(Not recommended, unless absolutely necessary.), iMeesage.app? 🔖 Bookmarks: Microsoft Edge 📑 Read It Later: Omnivore 📜 Word Processing: Lark Docs, Microsoft 365 📈 Spreadsheets: N/A 📊 Presentations: Microsoft PowerPoint 🛒 Shopping Lists: N/A 🍴 Meal Planning: N/A 💰 Budgeting and Personal Finance: iCost, Subscriptions 📰 News: Channels on Telegram, RSS, Web 🎵 Music: NeteaseMusic, Music.app 🎤 Podcasts: N/A 🔐 Password Management: iCloud Keychain 🧑‍💻 Code Editor: JetBrains Series, VS Code, Vim 🪄 Launcher: HapiGo 😘 Blog Platform: Hugo

                  December 3, 2023 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/app/index.xml b/tags/app/index.xml index a8babdda..00d25899 100644 --- a/tags/app/index.xml +++ b/tags/app/index.xml @@ -17,490 +17,490 @@ <p>由于软件可能较多,不能一次性写完。同时,因为我也在不断体验新的软件,有新的感受,因此这篇博客应该是持续更新的,欢迎常来看看。</p> <h2 id="速览表">速览表</h2> <table> -<thead> -<tr> -<th>App 名称</th> -<th>简短描述</th> -<th>功能限制</th> -<th>订阅形式</th> -<th>价格</th> -<th>购入时间</th> -<th>购入渠道</th> -<th>同类型产品</th> -</tr> -</thead> -<tbody> -<tr> -<td>AIDente</td> -<td>电池电量管理</td> -<td>有免费使用功能,但有共功能需要收费</td> -<td>买断</td> -<td>Free</td> -<td></td> -<td></td> -<td>Battery, BatFi</td> -</tr> -<tr> -<td>AdGuard</td> -<td>广告拦截软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>AltTab</td> -<td>增强 macOS App 切换</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Command-Tab Plus, Contexts,HyperSwitch,</td> -</tr> -<tr> -<td>Bartender 5</td> -<td>Menubar 管理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Bob</td> -<td>大概是最好用翻译软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>EasyDict</td> -</tr> -<tr> -<td>BuhoCleaner</td> -<td>垃圾清理器/软件卸载器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>CleanMyMac, Sensei</td> -</tr> -<tr> -<td>Clash X / Clash X Pro</td> -<td>代理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Surge, Stash</td> -</tr> -<tr> -<td>CleanBuddy</td> -<td>键盘锁定清理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Cleaner</td> -</tr> -<tr> -<td>CleanShot X</td> -<td>大概最好用的截图软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Cleaner</td> -<td>键盘屏幕锁定清理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>CleanBuddy</td> -</tr> -<tr> -<td>Dash</td> -<td>文档利器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Dato</td> -<td>Menubar 日历软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Fantastical, Itsycal</td> -</tr> -<tr> -<td>DevUtils</td> -<td>开发小工具合集</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Downie 4</td> -<td>各类视频下载器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>VDown</td> -</tr> -<tr> -<td>HapiGo</td> -<td>启动器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Alfred, Raycast</td> -</tr> -<tr> -<td>HazeOver</td> -<td>生产力工具,突出重点</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Hazel</td> -<td>自动清理集合</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>JetBrains 全家桶</td> -<td>包含 Clion/IDEA 等</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>VSCode, Eclipse</td> -</tr> -<tr> -<td>Lunar</td> -<td>显示器管理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>MonitorControl, DisplayBuddy, Better Display</td> -</tr> -<tr> -<td>Maccy</td> -<td>开源免费的剪切板管理工具</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Paste, PasteNow, PastePal</td> -</tr> -<tr> -<td>Manico</td> -<td>快速启动器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Command-Tab Plus</td> -</tr> -<tr> -<td>MimeStram</td> -<td>Gmail 客户端</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>MonitorControl</td> -<td>开源显示器管理,很够用</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Lunar, DisplayBuddy, Better Display</td> -</tr> -<tr> -<td>NetNewsWire</td> -<td>全平台 RSS 阅读器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Obsidian</td> -<td>笔记软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Omnivore</td> -<td>稍后读软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Pocket, MarkMark,</td> -</tr> -<tr> -<td>Only Switch</td> -<td>一键完成各种任务</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>One Switch</td> -</tr> -<tr> -<td>OpenImageOptim</td> -<td>图片压缩</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>TinyPNG</td> -</tr> -<tr> -<td>OrbStack</td> -<td>容器管理,平替 Docker Desktop</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Docker Desktop, Podman, lima, colima</td> -</tr> -<tr> -<td>Permute 3</td> -<td>图片/视频格式转换工具,类似于格式工厂</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>HandBrake, Omni Converter, Video Converter X2</td> -</tr> -<tr> -<td>Pixea</td> -<td>图片查看器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Viso, Picsee</td> -</tr> -<tr> -<td>Pixelmator Pro</td> -<td>图片编辑器,80% 平替 PhotoShop</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Adobe PhotoShop, Darkroom, Photomator, Capture One, Adobe LightRoom Classic</td> -</tr> -<tr> -<td>PopClip</td> -<td>划词增强</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Proxyman</td> -<td>大概是舒服的抓包工具,略贵</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Charles</td> -</tr> -<tr> -<td>Rectangle</td> -<td>分屏软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Magnet, Swish</td> -</tr> -<tr> -<td>Swish</td> -<td>触控板手势增强</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Stats</td> -<td>Menubar 状态监控</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>iStats Menu, Sensei</td> -</tr> -<tr> -<td>Subscriptions</td> -<td>订阅管理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Pandora on iOS</td> -</tr> -<tr> -<td>Surge</td> -<td>代理工具</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Clash X, Stash</td> -</tr> -<tr> -<td>TinyPNG</td> -<td>图片压缩</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>OpenImageOptim</td> -</tr> -<tr> -<td>Typora</td> -<td>Markdown 文本编辑器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Obsidian</td> -</tr> -<tr> -<td>Upscayl</td> -<td>AI 图片超分</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>AI Photo Enhancer by Pictura, Pixelmator Pro</td> -</tr> -<tr> -<td>Viso 6</td> -<td>图片查看器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Pixea, Xee</td> -</tr> -<tr> -<td>Zotero</td> -<td>文献管理,就是界面一般</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>coconutBattery</td> -<td>iPhone/iPad/Mac 电池信息查看</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>iRightMenu</td> -<td>右键增强</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>超级右键, iMouse,</td> -</tr> -<tr> -<td>iTerm2</td> -<td>终端模拟器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Alacritty, Warp, Wezterm, Terminal</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">App 名称</th> + <th style="text-align: left">简短描述</th> + <th style="text-align: left">功能限制</th> + <th style="text-align: left">订阅形式</th> + <th style="text-align: left">价格</th> + <th style="text-align: left">购入时间</th> + <th style="text-align: left">购入渠道</th> + <th style="text-align: left">同类型产品</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">AIDente</td> + <td style="text-align: left">电池电量管理</td> + <td style="text-align: left">有免费使用功能,但有共功能需要收费</td> + <td style="text-align: left">买断</td> + <td style="text-align: left">Free</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Battery, BatFi</td> + </tr> + <tr> + <td style="text-align: left">AdGuard</td> + <td style="text-align: left">广告拦截软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">AltTab</td> + <td style="text-align: left">增强 macOS App 切换</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Command-Tab Plus, Contexts,HyperSwitch,</td> + </tr> + <tr> + <td style="text-align: left">Bartender 5</td> + <td style="text-align: left">Menubar 管理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Bob</td> + <td style="text-align: left">大概是最好用翻译软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">EasyDict</td> + </tr> + <tr> + <td style="text-align: left">BuhoCleaner</td> + <td style="text-align: left">垃圾清理器/软件卸载器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">CleanMyMac, Sensei</td> + </tr> + <tr> + <td style="text-align: left">Clash X / Clash X Pro</td> + <td style="text-align: left">代理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Surge, Stash</td> + </tr> + <tr> + <td style="text-align: left">CleanBuddy</td> + <td style="text-align: left">键盘锁定清理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Cleaner</td> + </tr> + <tr> + <td style="text-align: left">CleanShot X</td> + <td style="text-align: left">大概最好用的截图软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Cleaner</td> + <td style="text-align: left">键盘屏幕锁定清理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">CleanBuddy</td> + </tr> + <tr> + <td style="text-align: left">Dash</td> + <td style="text-align: left">文档利器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Dato</td> + <td style="text-align: left">Menubar 日历软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Fantastical, Itsycal</td> + </tr> + <tr> + <td style="text-align: left">DevUtils</td> + <td style="text-align: left">开发小工具合集</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Downie 4</td> + <td style="text-align: left">各类视频下载器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">VDown</td> + </tr> + <tr> + <td style="text-align: left">HapiGo</td> + <td style="text-align: left">启动器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Alfred, Raycast</td> + </tr> + <tr> + <td style="text-align: left">HazeOver</td> + <td style="text-align: left">生产力工具,突出重点</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Hazel</td> + <td style="text-align: left">自动清理集合</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">JetBrains 全家桶</td> + <td style="text-align: left">包含 Clion/IDEA 等</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">VSCode, Eclipse</td> + </tr> + <tr> + <td style="text-align: left">Lunar</td> + <td style="text-align: left">显示器管理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">MonitorControl, DisplayBuddy, Better Display</td> + </tr> + <tr> + <td style="text-align: left">Maccy</td> + <td style="text-align: left">开源免费的剪切板管理工具</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Paste, PasteNow, PastePal</td> + </tr> + <tr> + <td style="text-align: left">Manico</td> + <td style="text-align: left">快速启动器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Command-Tab Plus</td> + </tr> + <tr> + <td style="text-align: left">MimeStram</td> + <td style="text-align: left">Gmail 客户端</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">MonitorControl</td> + <td style="text-align: left">开源显示器管理,很够用</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Lunar, DisplayBuddy, Better Display</td> + </tr> + <tr> + <td style="text-align: left">NetNewsWire</td> + <td style="text-align: left">全平台 RSS 阅读器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Obsidian</td> + <td style="text-align: left">笔记软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Omnivore</td> + <td style="text-align: left">稍后读软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Pocket, MarkMark,</td> + </tr> + <tr> + <td style="text-align: left">Only Switch</td> + <td style="text-align: left">一键完成各种任务</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">One Switch</td> + </tr> + <tr> + <td style="text-align: left">OpenImageOptim</td> + <td style="text-align: left">图片压缩</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">TinyPNG</td> + </tr> + <tr> + <td style="text-align: left">OrbStack</td> + <td style="text-align: left">容器管理,平替 Docker Desktop</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Docker Desktop, Podman, lima, colima</td> + </tr> + <tr> + <td style="text-align: left">Permute 3</td> + <td style="text-align: left">图片/视频格式转换工具,类似于格式工厂</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">HandBrake, Omni Converter, Video Converter X2</td> + </tr> + <tr> + <td style="text-align: left">Pixea</td> + <td style="text-align: left">图片查看器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Viso, Picsee</td> + </tr> + <tr> + <td style="text-align: left">Pixelmator Pro</td> + <td style="text-align: left">图片编辑器,80% 平替 PhotoShop</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Adobe PhotoShop, Darkroom, Photomator, Capture One, Adobe LightRoom Classic</td> + </tr> + <tr> + <td style="text-align: left">PopClip</td> + <td style="text-align: left">划词增强</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Proxyman</td> + <td style="text-align: left">大概是舒服的抓包工具,略贵</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Charles</td> + </tr> + <tr> + <td style="text-align: left">Rectangle</td> + <td style="text-align: left">分屏软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Magnet, Swish</td> + </tr> + <tr> + <td style="text-align: left">Swish</td> + <td style="text-align: left">触控板手势增强</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Stats</td> + <td style="text-align: left">Menubar 状态监控</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">iStats Menu, Sensei</td> + </tr> + <tr> + <td style="text-align: left">Subscriptions</td> + <td style="text-align: left">订阅管理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Pandora on iOS</td> + </tr> + <tr> + <td style="text-align: left">Surge</td> + <td style="text-align: left">代理工具</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Clash X, Stash</td> + </tr> + <tr> + <td style="text-align: left">TinyPNG</td> + <td style="text-align: left">图片压缩</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">OpenImageOptim</td> + </tr> + <tr> + <td style="text-align: left">Typora</td> + <td style="text-align: left">Markdown 文本编辑器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Obsidian</td> + </tr> + <tr> + <td style="text-align: left">Upscayl</td> + <td style="text-align: left">AI 图片超分</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">AI Photo Enhancer by Pictura, Pixelmator Pro</td> + </tr> + <tr> + <td style="text-align: left">Viso 6</td> + <td style="text-align: left">图片查看器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Pixea, Xee</td> + </tr> + <tr> + <td style="text-align: left">Zotero</td> + <td style="text-align: left">文献管理,就是界面一般</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">coconutBattery</td> + <td style="text-align: left">iPhone/iPad/Mac 电池信息查看</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">iRightMenu</td> + <td style="text-align: left">右键增强</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">超级右键, iMouse,</td> + </tr> + <tr> + <td style="text-align: left">iTerm2</td> + <td style="text-align: left">终端模拟器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Alacritty, Warp, Wezterm, Terminal</td> + </tr> + </tbody> </table> <h2 id="详细信息">详细信息</h2> <h3 id="aidente">AIDente</h3> diff --git a/tags/beauty/index.html b/tags/beauty/index.html index 2df1d9d9..8b8dff75 100644 --- a/tags/beauty/index.html +++ b/tags/beauty/index.html @@ -1,6 +1,6 @@ Beauty | Zs's Blog -

                  关于美的一些思考

                  楔子 昨天听了学弟们关于博客搭建的一些教程,在听的过程中,也想起了我之前对于博客的种种尝试,发现整体的趋势就是,简约再简约。 +

                  关于美的一些思考

                  楔子 昨天听了学弟们关于博客搭建的一些教程,在听的过程中,也想起了我之前对于博客的种种尝试,发现整体的趋势就是,简约再简约。 这引发了我对我过去几年的审视,感觉自己的审美一直在变化,对于美的认识和感受也是一直在变的,故写此文来记一些我对美认识的思考。 简约是我最终的归宿 遥记得我还在小学和初中时,非常迷恋 QQ飞车 这款游戏,这款游戏里面有一个虚拟人物,人物可以搭配各种装饰,包括但不限于上衣、裤子、发型、发饰、翅膀等,起初我是喜欢要多花哨有多花哨造型,各种发饰、翅膀、脸部特效搞的飞起,现在想起来真是非常搞笑,而且喜欢五颜六色的,当时觉得,真的是太好看了。 但是过了一段时间,就开始感觉不对劲了,这么花哨,这么丑,这怎么可能是我当时亲手选择的造型。后来就逐渐向简约范靠拢,装饰越简单,色调越单一越喜欢。 @@ -20,8 +20,9 @@ 我觉得美这个东西,很不像生活中常见的发展规律,例如芯片的研发,需要数学、物理、化学等学科实际理论的支持。 2001 年的人是没有办法设计出 Apple M2 的芯片的,因为受到了各种硬件的制约。而 2001 年的设计师有没有可能设计出最新版 Mac QQ 这样的界面呢,如果不能,是什么制约着它呢?如果能,为什么没有出现这种设计,是因为当时大家觉得他不好看吗? 因为我不是学设计和美术等专业的,并且这种很很直觉的东西我不知道该怎么去搜索,因此想在这里和大家探讨一下。如果有已经相对成熟的理论,还请大家能够告知与我,解答困扰我好久的疑问。 -AI 绘图 看网上有人调侃说,愿意称 2022 年为 AI 绘图元年。...

                  October 30, 2022 · 1 min · zzsqwq
                  © 2024 Zs's Blog +AI 绘图 看网上有人调侃说,愿意称 2022 年为 AI 绘图元年。 +...

                  October 30, 2022 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/c++/index.html b/tags/c++/index.html index 11ea5d50..4f1bba8b 100644 --- a/tags/c++/index.html +++ b/tags/c++/index.html @@ -1,14 +1,17 @@ C++ | Zs's Blog -

                  C++ 类使用注意事项

                  前言 本文包含一些在使用 C++ 类时的注意事项,可避免一些常见问题,并能让你在写代码时更加自信。 +

                  C++ 类使用注意事项

                  前言 本文包含一些在使用 C++ 类时的注意事项,可避免一些常见问题,并能让你在写代码时更加自信。 因为目前我使用的是 C++ 17,所以仅保证以下内容在 C++ 17 中正确。 -构造函数 对于单个参数的构造函数,推荐添加 explicit 关键字,防止隐式转换错误调用构造函数。 class DemoClass { explicit DemoClass(int test) { this->test_ = test; } } 显式声明有参构造函数后,编译器不会自动生成无参构造函数,若需要,请添加 DemoClass() = default; class DemoClass { explicit DemoClass(int test) { this->test_ = test; } DemoClass() = default; } 若子类中没有显式调用父类的构造函数,子类会默认调用父类的无参构造函数,如果父类没有无参构造函数,会报错。 析构函数 基类析构函数应该声明为 virtual,这样可以防止子类无法正确的析构。 由于基类析构函数为 virtual,派生类的析构函数应该显式的 override。 class DemoClass { virtual ~DemoClass() = default; } class ChildClass: public DemoClass { ~ChildClass() override { xxx; } } 成员变量默认值 对于类或局部作用域中未明确指定默认值的成员变量,其值遵循以下规则:...

                  November 9, 2022 · 2 min · zzsqwq

                  为什么要使用条件变量?

                  为什么要使用条件变量? 前言 最近看了很多与线程有关的 C++ 新特性,条件变量是见的比较多的一个特性。 +构造函数 对于单个参数的构造函数,推荐添加 explicit 关键字,防止隐式转换错误调用构造函数。 class DemoClass { explicit DemoClass(int test) { this->test_ = test; } } 显式声明有参构造函数后,编译器不会自动生成无参构造函数,若需要,请添加 DemoClass() = default; class DemoClass { explicit DemoClass(int test) { this->test_ = test; } DemoClass() = default; } 若子类中没有显式调用父类的构造函数,子类会默认调用父类的无参构造函数,如果父类没有无参构造函数,会报错。 析构函数 基类析构函数应该声明为 virtual,这样可以防止子类无法正确的析构。 由于基类析构函数为 virtual,派生类的析构函数应该显式的 override。 class DemoClass { virtual ~DemoClass() = default; } class ChildClass: public DemoClass { ~ChildClass() override { xxx; } } 成员变量默认值 对于类或局部作用域中未明确指定默认值的成员变量,其值遵循以下规则: +对于原生类型(primitive types),即 int、float、int*、string* 等,默认值为随机的脏数据。 对于对象(objects),例如自定义类、或 std::string 等,会调用默认(无参)构造函数,若没有默认(无参)构造函数,则报错。 对于引用(reference)类型,例如 std::string&,必须赋初始值或在构造函数中初始化,若为初始化,则报错。 float age; // 脏数据、随机值(无意义),此时访问会出现未定义行为 int *ptr; // 脏数据、随机值(无意义),此时访问会出现未定义行为 string name; // 调用默认构造函数,对于 std::string 来说为空字符串 "" DemoClass demo; // 若 DemoClass 存在无参构造函数,则调用,否则编译错误 string *pname; // 脏数据、随机值(无意义),此时访问会出现未定义行为 string &rname; // 编译错误,必须显式初始化 const string &crname; // 同上,编译错误 成员变量初始化方式 初始化成员变量一般而言有四种方式,一般而言第二种和第四种方式为等价的,不过在下面我们会看到一种例外: +...

                  November 9, 2022 · 2 min · zzsqwq

                  为什么要使用条件变量?

                  为什么要使用条件变量? 前言 最近看了很多与线程有关的 C++ 新特性,条件变量是见的比较多的一个特性。 看的时候我发现,想要理解一个新的特性,关键的要看它的引入到底解决了哪些问题,没有什么特性我们要实现相同的功能要怎么做? 以我的理解来看,条件变量是一个线程间互相同步与通知的手段,他通过主动唤醒的方式减小了各个线程的开销,取代了简单但是消耗较大的一直被动循环检验与等待。 没有条件变量我们如何实现相同的需求? 这里采用现代C++教程1 中关于条件变量的一个例子作为基础: -不使用条件变量版本 #include <queue> #include <chrono> #include <mutex> #include <thread> #include <iostream> #include <condition_variable> int main() { std::queue<int> produced_nums; std::mutex mtx; // 生产者 auto producer = [&]() { for (int i = 0; ; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(900)); std::unique_lock<std::mutex> lock(mtx); std::cout << "producing " << i << std::endl; produced_nums.push(i); } }; // 消费者 auto consumer = [&]() { while (true) { { std::unique_lock<std::mutex> lock(mtx); if(produced_nums....

                  August 24, 2022 · 2 min · zzsqwq

                  C++大数类的实现

                  C++大数类设计思路 洛谷大数类的评测结果(开了氧气优化) 这个第四个点真的优化不过去了QAQ,24W的数据,丧心病狂 +不使用条件变量版本 #include <queue> #include <chrono> #include <mutex> #include <thread> #include <iostream> #include <condition_variable> int main() { std::queue<int> produced_nums; std::mutex mtx; // 生产者 auto producer = [&]() { for (int i = 0; ; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(900)); std::unique_lock<std::mutex> lock(mtx); std::cout << "producing " << i << std::endl; produced_nums.push(i); } }; // 消费者 auto consumer = [&]() { while (true) { { std::unique_lock<std::mutex> lock(mtx); if(produced_nums.empty()) continue; } std::unique_lock<std::mutex> lock(mtx); // 短暂取消锁,使得生产者有机会在消费者消费空前继续生产 lock.unlock(); // 消费者慢于生产者 std::this_thread::sleep_for(std::chrono::milliseconds(1000)); lock.lock(); while (!produced_nums.empty()) { std::cout << "consuming " << produced_nums.front() << std::endl; produced_nums.pop(); } } }; // 分别在不同的线程中运行 std::thread p(producer); std::thread cs[2]; for (int i = 0; i < 2; ++i) { cs[i] = std::thread(consumer); } p.join(); for (int i = 0; i < 2; ++i) { cs[i].join(); } return 0; } 使用条件变量版本 #include <queue> #include <chrono> #include <mutex> #include <thread> #include <iostream> #include <condition_variable> int main() { std::queue<int> produced_nums; std::mutex mtx; std::condition_variable cv; bool notified = false; // 通知信号 // 生产者 auto producer = [&]() { for (int i = 0; ; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(900)); std::unique_lock<std::mutex> lock(mtx); std::cout << "producing " << i << std::endl; produced_nums.push(i); notified = true; cv.notify_all(); // 此处也可以使用 notify_one } }; // 消费者 auto consumer = [&]() { while (true) { std::unique_lock<std::mutex> lock(mtx); while (!notified) { // 避免虚假唤醒 cv.wait(lock); } // 短暂取消锁,使得生产者有机会在消费者消费空前继续生产 lock.unlock(); // 消费者慢于生产者 std::this_thread::sleep_for(std::chrono::milliseconds(1000)); lock.lock(); while (!produced_nums.empty()) { std::cout << "consuming " << produced_nums.front() << std::endl; produced_nums.pop(); } notified = false; } }; // 分别在不同的线程中运行 std::thread p(producer); std::thread cs[2]; for (int i = 0; i < 2; ++i) { cs[i] = std::thread(consumer); } p.join(); for (int i = 0; i < 2; ++i) { cs[i].join(); } return 0; } 这两段代码在效果上是等效的,都是一个生产者两个消费者。 +...

                  August 24, 2022 · 2 min · zzsqwq

                  C++大数类的实现

                  C++大数类设计思路 洛谷大数类的评测结果(开了氧气优化) 这个第四个点真的优化不过去了QAQ,24W的数据,丧心病狂 ...

                  April 6, 2020 · 5 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/centernet/index.html b/tags/centernet/index.html index 5c8ee275..fc02d26e 100644 --- a/tags/centernet/index.html +++ b/tags/centernet/index.html @@ -1,6 +1,6 @@ CenterNet | Zs's Blog -

                  如何使用CenterNet做3D目标检测测试

                  CenterNet—Objects as Points介绍 ​CenterNet是一个anchor-free的目标检测网络,与YOLOv3相比,精度有所提升,此外他不仅能够用于2D目标检测,也能够用于人体姿态识别,3D目标检测等··· +

                  如何使用CenterNet做3D目标检测测试

                  CenterNet—Objects as Points介绍 ​CenterNet是一个anchor-free的目标检测网络,与YOLOv3相比,精度有所提升,此外他不仅能够用于2D目标检测,也能够用于人体姿态识别,3D目标检测等··· 安装CenterNet ​其实安装CenterNet的过程就是一个配置环境的问题,直接跟着官方给出的这里Install.md配置一下即可,十分推荐使用Conda来管理环境,这里给出我的环境给大家参考一下: Ubuntu = 18.04 LTS pytorch = 1.2.0 @@ -13,8 +13,12 @@ python demo.py ctdet --demo ${CenterNet_Root}/images/17790319373_bd19b24cfc_k.jpg --load_model ../models/ctdet_coco_dla_2x.pth ​这里需要注意的是 --demo 后面的 ${CenterNet_Root}/images/17790319373_bd19b24cfc_k.jpg ,这里我使用的是官方给出的实例图片,它位于CenterNet根目录的images文件夹中,前面的 ${CenterNet_Root} 代表的是 CenterNet根目录,好比我的就位于 /home/zs/CenterNet 。 ​如果不出意外的话效果应该如下图所示: 运行CenterNet的3D目标检测 配置数据集和模型 ​我们可以直接参考官方的 DATA.md 来配置我们的数据集。 -​然后到 Model zoo 下载3D检测使用的模型 ddd_3dop....

                  January 27, 2021 · 2 min · zzsqwq
                  © 2024 Zs's Blog +​然后到 Model zoo 下载3D检测使用的模型 ddd_3dop.pth 。 +​这里说一下遇到的几个坑: +首先是配置数据集的过程中,我们需要配置的目录结构如图所示(官方给出的结构树有点模糊不清的感觉) +. ├── ImageSets_3dop │ ├── test.txt │ ├── train.txt │ ├── trainval.txt │ └── val.txt ├── ImageSets_subcnn │ ├── test.txt │ ├── train.txt │ ├── trainval.txt │ └── val.txt └── training ├── calib ├── image_2 └── label_2 然后去到 ${CenterNet_ROOT}/src/tools目录下,运行 python convert_kitti_to_coco.py 将 kitti 数据集转换为 coco 数据集的格式,不出意外应该会报错如下: +...

                  January 27, 2021 · 2 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/class/index.html b/tags/class/index.html index 5a1cb9bc..deb94d2b 100644 --- a/tags/class/index.html +++ b/tags/class/index.html @@ -1,9 +1,11 @@ Class | Zs's Blog -

                  C++ 类使用注意事项

                  前言 本文包含一些在使用 C++ 类时的注意事项,可避免一些常见问题,并能让你在写代码时更加自信。 +

                  C++ 类使用注意事项

                  前言 本文包含一些在使用 C++ 类时的注意事项,可避免一些常见问题,并能让你在写代码时更加自信。 因为目前我使用的是 C++ 17,所以仅保证以下内容在 C++ 17 中正确。 -构造函数 对于单个参数的构造函数,推荐添加 explicit 关键字,防止隐式转换错误调用构造函数。 class DemoClass { explicit DemoClass(int test) { this->test_ = test; } } 显式声明有参构造函数后,编译器不会自动生成无参构造函数,若需要,请添加 DemoClass() = default; class DemoClass { explicit DemoClass(int test) { this->test_ = test; } DemoClass() = default; } 若子类中没有显式调用父类的构造函数,子类会默认调用父类的无参构造函数,如果父类没有无参构造函数,会报错。 析构函数 基类析构函数应该声明为 virtual,这样可以防止子类无法正确的析构。 由于基类析构函数为 virtual,派生类的析构函数应该显式的 override。 class DemoClass { virtual ~DemoClass() = default; } class ChildClass: public DemoClass { ~ChildClass() override { xxx; } } 成员变量默认值 对于类或局部作用域中未明确指定默认值的成员变量,其值遵循以下规则:...

                  November 9, 2022 · 2 min · zzsqwq
                  © 2024 Zs's Blog +构造函数 对于单个参数的构造函数,推荐添加 explicit 关键字,防止隐式转换错误调用构造函数。 class DemoClass { explicit DemoClass(int test) { this->test_ = test; } } 显式声明有参构造函数后,编译器不会自动生成无参构造函数,若需要,请添加 DemoClass() = default; class DemoClass { explicit DemoClass(int test) { this->test_ = test; } DemoClass() = default; } 若子类中没有显式调用父类的构造函数,子类会默认调用父类的无参构造函数,如果父类没有无参构造函数,会报错。 析构函数 基类析构函数应该声明为 virtual,这样可以防止子类无法正确的析构。 由于基类析构函数为 virtual,派生类的析构函数应该显式的 override。 class DemoClass { virtual ~DemoClass() = default; } class ChildClass: public DemoClass { ~ChildClass() override { xxx; } } 成员变量默认值 对于类或局部作用域中未明确指定默认值的成员变量,其值遵循以下规则: +对于原生类型(primitive types),即 int、float、int*、string* 等,默认值为随机的脏数据。 对于对象(objects),例如自定义类、或 std::string 等,会调用默认(无参)构造函数,若没有默认(无参)构造函数,则报错。 对于引用(reference)类型,例如 std::string&,必须赋初始值或在构造函数中初始化,若为初始化,则报错。 float age; // 脏数据、随机值(无意义),此时访问会出现未定义行为 int *ptr; // 脏数据、随机值(无意义),此时访问会出现未定义行为 string name; // 调用默认构造函数,对于 std::string 来说为空字符串 "" DemoClass demo; // 若 DemoClass 存在无参构造函数,则调用,否则编译错误 string *pname; // 脏数据、随机值(无意义),此时访问会出现未定义行为 string &rname; // 编译错误,必须显式初始化 const string &crname; // 同上,编译错误 成员变量初始化方式 初始化成员变量一般而言有四种方式,一般而言第二种和第四种方式为等价的,不过在下面我们会看到一种例外: +...

                  November 9, 2022 · 2 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/codeforces/index.html b/tags/codeforces/index.html index 887db854..b4b53042 100644 --- a/tags/codeforces/index.html +++ b/tags/codeforces/index.html @@ -1,6 +1,6 @@ Codeforces | Zs's Blog -

                  Codeforces#620 (Div.2)

                  A. Two Rabbits 题意 两个兔子分别位于 $(x,0)$ 和 $(y,0)$ ,两个人对头蹦,前者往前蹦 $a$ ,后者往前蹦 $b$ ,问两人是否能恰好相遇。 +

                  Codeforces#620 (Div.2)

                  A. Two Rabbits 题意 两个兔子分别位于 $(x,0)$ 和 $(y,0)$ ,两个人对头蹦,前者往前蹦 $a$ ,后者往前蹦 $b$ ,问两人是否能恰好相遇。 ...

                  February 19, 2020 · 2 min · zzsqwq

                  杂题训练

                  A. 配对 题意 给定含有 $n$ 个正整数的集合 $A$ 和 $B$ ,你需要建立他们之间的一一映射。将配对的两个数相加可以得到 $n$ 个和,问第 $k$ 大的和最大为多少。 ...

                  February 15, 2020 · 2 min · zzsqwq

                  Codeforces#619 (Div.2)

                  A. Three Strings 题意 给定三个长度为 $n$ 的字符串 $a$ , $b$ , $c$ ,遍历每个 $c$ 中每个字符 $c_i$,可以将其替换成 $a_i$ 或者 $b_i$ ,必须操作其中一个,问能否通过此操作使得字符串 $a$ , $b$ 相同。 ...

                  February 14, 2020 · 2 min · zzsqwq

                  Codeforces #618 (Div.2)

                  A. Non-zero 题意 给出一段含有 $n$ 个数的序列 $a$ ,可以对其中任何数加一,问最少操作多少次让每一个数和序列和都不为0。 @@ -9,5 +9,5 @@ ...

                  February 5, 2020 · 2 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/codeforces/page/2/index.html b/tags/codeforces/page/2/index.html index 2ff56c20..293e126b 100644 --- a/tags/codeforces/page/2/index.html +++ b/tags/codeforces/page/2/index.html @@ -1,8 +1,8 @@ Codeforces | Zs's Blog -

                  CodeforcesER #81

                  A : Display The Number 题意 用一定数目的灯管,显示尽可能大的数 +

                  CodeforcesER #81

                  A : Display The Number 题意 用一定数目的灯管,显示尽可能大的数 ...

                  February 2, 2020 · 2 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/conda/index.html b/tags/conda/index.html index 03f7b9d1..a1537d40 100644 --- a/tags/conda/index.html +++ b/tags/conda/index.html @@ -1,6 +1,6 @@ Conda | Zs's Blog -

                  关于Anaconda中pip路径指向问题

                  前言 最近使用Anaconda的时候遇到了一个很奇怪的问题,如当我新建环境 condatest 后,使用 pip -V 查看pip的路径指向,会发现pip指向的是另一个环境 CenterNet 的路径。搜索了很久得到一个有一些用的解决方法 +

                  关于Anaconda中pip路径指向问题

                  前言 最近使用Anaconda的时候遇到了一个很奇怪的问题,如当我新建环境 condatest 后,使用 pip -V 查看pip的路径指向,会发现pip指向的是另一个环境 CenterNet 的路径。搜索了很久得到一个有一些用的解决方法 解决方案 设有问题的环境为 condatest ,python版本为 3.6 然后进入 ~/anaconda3/envs/condatest/lib/python3.6 编辑目录下的 site.py 文件,将其中的 USER_SITE 的值修改为 /home/zs/anaconda3/envs/condatest ,注意这里路径里面的 zs 是你的当前用户名, USER_BASE 的值修改为 /home/zs/anaconda3/envs/condatest/lib/python3.6/site.py,然后问题应该就解决了。 @@ -8,5 +8,5 @@ 参考链接 更改conda环境中的pip包安装的默认路径

                  March 6, 2021 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/condition-variable/index.html b/tags/condition-variable/index.html index 2bb081d1..d6262316 100644 --- a/tags/condition-variable/index.html +++ b/tags/condition-variable/index.html @@ -1,11 +1,12 @@ Condition Variable | Zs's Blog -

                  为什么要使用条件变量?

                  为什么要使用条件变量? 前言 最近看了很多与线程有关的 C++ 新特性,条件变量是见的比较多的一个特性。 +

                  为什么要使用条件变量?

                  为什么要使用条件变量? 前言 最近看了很多与线程有关的 C++ 新特性,条件变量是见的比较多的一个特性。 看的时候我发现,想要理解一个新的特性,关键的要看它的引入到底解决了哪些问题,没有什么特性我们要实现相同的功能要怎么做? 以我的理解来看,条件变量是一个线程间互相同步与通知的手段,他通过主动唤醒的方式减小了各个线程的开销,取代了简单但是消耗较大的一直被动循环检验与等待。 没有条件变量我们如何实现相同的需求? 这里采用现代C++教程1 中关于条件变量的一个例子作为基础: -不使用条件变量版本 #include <queue> #include <chrono> #include <mutex> #include <thread> #include <iostream> #include <condition_variable> int main() { std::queue<int> produced_nums; std::mutex mtx; // 生产者 auto producer = [&]() { for (int i = 0; ; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(900)); std::unique_lock<std::mutex> lock(mtx); std::cout << "producing " << i << std::endl; produced_nums.push(i); } }; // 消费者 auto consumer = [&]() { while (true) { { std::unique_lock<std::mutex> lock(mtx); if(produced_nums....

                  August 24, 2022 · 2 min · zzsqwq
                  © 2024 Zs's Blog +不使用条件变量版本 #include <queue> #include <chrono> #include <mutex> #include <thread> #include <iostream> #include <condition_variable> int main() { std::queue<int> produced_nums; std::mutex mtx; // 生产者 auto producer = [&]() { for (int i = 0; ; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(900)); std::unique_lock<std::mutex> lock(mtx); std::cout << "producing " << i << std::endl; produced_nums.push(i); } }; // 消费者 auto consumer = [&]() { while (true) { { std::unique_lock<std::mutex> lock(mtx); if(produced_nums.empty()) continue; } std::unique_lock<std::mutex> lock(mtx); // 短暂取消锁,使得生产者有机会在消费者消费空前继续生产 lock.unlock(); // 消费者慢于生产者 std::this_thread::sleep_for(std::chrono::milliseconds(1000)); lock.lock(); while (!produced_nums.empty()) { std::cout << "consuming " << produced_nums.front() << std::endl; produced_nums.pop(); } } }; // 分别在不同的线程中运行 std::thread p(producer); std::thread cs[2]; for (int i = 0; i < 2; ++i) { cs[i] = std::thread(consumer); } p.join(); for (int i = 0; i < 2; ++i) { cs[i].join(); } return 0; } 使用条件变量版本 #include <queue> #include <chrono> #include <mutex> #include <thread> #include <iostream> #include <condition_variable> int main() { std::queue<int> produced_nums; std::mutex mtx; std::condition_variable cv; bool notified = false; // 通知信号 // 生产者 auto producer = [&]() { for (int i = 0; ; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(900)); std::unique_lock<std::mutex> lock(mtx); std::cout << "producing " << i << std::endl; produced_nums.push(i); notified = true; cv.notify_all(); // 此处也可以使用 notify_one } }; // 消费者 auto consumer = [&]() { while (true) { std::unique_lock<std::mutex> lock(mtx); while (!notified) { // 避免虚假唤醒 cv.wait(lock); } // 短暂取消锁,使得生产者有机会在消费者消费空前继续生产 lock.unlock(); // 消费者慢于生产者 std::this_thread::sleep_for(std::chrono::milliseconds(1000)); lock.lock(); while (!produced_nums.empty()) { std::cout << "consuming " << produced_nums.front() << std::endl; produced_nums.pop(); } notified = false; } }; // 分别在不同的线程中运行 std::thread p(producer); std::thread cs[2]; for (int i = 0; i < 2; ++i) { cs[i] = std::thread(consumer); } p.join(); for (int i = 0; i < 2; ++i) { cs[i].join(); } return 0; } 这两段代码在效果上是等效的,都是一个生产者两个消费者。 +...

                  August 24, 2022 · 2 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/tags/c\350\257\255\350\250\200/index.html" "b/tags/c\350\257\255\350\250\200/index.html" index 3fd17c04..7ccf9933 100644 --- "a/tags/c\350\257\255\350\250\200/index.html" +++ "b/tags/c\350\257\255\350\250\200/index.html" @@ -1,14 +1,15 @@ C语言 | Zs's Blog -

                  “程序星编程之路”第二次作业题解

                  “程序星编程之路”第二次作业题解 A. Zs的回文质数 题目描述 读入一个整数 $n$ ,输出 $[1,n]$ 的所有回文质数,我们规定 $1\sim9$ 也是回文数。 +

                  “程序星编程之路”第二次作业题解

                  “程序星编程之路”第二次作业题解 A. Zs的回文质数 题目描述 读入一个整数 $n$ ,输出 $[1,n]$ 的所有回文质数,我们规定 $1\sim9$ 也是回文数。 思路 首先我们需要了解什么是回文数,以及什么是质数。 简单点说,回文数就是正着读反着读都是一样的,也就是对称的,形如 $abcba $ 或者 $123321$ 这样的。 质数的话,对于一个数 $n$ ,如果他是质数,那它除了 $1$ 和 $n$ 没有其他因子。例如 $2,3,5,7,11$ 这样的。 那么接下来我们考虑一下解决这个问题应该怎么做,首先我们看一下数据范围,$[1,100000]$ ,还是挺小的,我们可以考虑直接枚举每一个数来判断它是不是回文数,然后再判断一下是不是质数,如果两个都满足,我们就输出它。 判断回文数,我们可以考虑到 NOJ05 幸运数 一题的解题思路,也就是说我们把一个数倒置过来,好比一个数 $xyz$ 倒置成 $zyx$ ,然后判断是否 $xyz == zyx$ ,如果相等的话就是回文数,如果不相等就不是。 判断质数,我们可以在 $[2,\lfloor\sqrt{n}\rfloor]$ 枚举它的因子,这个的完备性我上课的时候证明过,不再赘述。这里需要注意 $1,2$ 需要特判一下。 -代码 #include<stdio.h> #include<math.h> //我们需要用到sqrt函数,因此需要引入数学库 int main() { int n; bool flag = false; // 标记 i 是否满足条件 scanf("%d",&n); for(int i=1;i<=n;i++) { flag = true; int p=i,j=0; while(p) // 将 p 反转为 j { j=j*10+p%10; p/=10; } if(j==i) { if(j==1) continue; // 特判 1 if(j==2) // 特判 2 { printf("2\n"); continue; } int sqrtj = sqrt(j); for(int k=2;k<=sqrtj;k++) // 枚举 [2,sqrt(n)] { if(j%k==0) // 如果能够整除(余数为0),那么是 j 的因子 { flag = false; break; } } if(flag) { printf("%d\n",j); } } } } 其他 因为我们讲到这里的时候,我们没讲函数,但是这道题如果我们把判断是否为回文数,判断是否为质数,都另成一个函数模块,将使得程序变得更加简洁。我在这里也将函数版本的贴出来,有兴趣的可以看一下。...

                  November 12, 2020 · 3 min · zzsqwq
                  © 2024 Zs's Blog +代码 #include<stdio.h> #include<math.h> //我们需要用到sqrt函数,因此需要引入数学库 int main() { int n; bool flag = false; // 标记 i 是否满足条件 scanf("%d",&n); for(int i=1;i<=n;i++) { flag = true; int p=i,j=0; while(p) // 将 p 反转为 j { j=j*10+p%10; p/=10; } if(j==i) { if(j==1) continue; // 特判 1 if(j==2) // 特判 2 { printf("2\n"); continue; } int sqrtj = sqrt(j); for(int k=2;k<=sqrtj;k++) // 枚举 [2,sqrt(n)] { if(j%k==0) // 如果能够整除(余数为0),那么是 j 的因子 { flag = false; break; } } if(flag) { printf("%d\n",j); } } } } 其他 因为我们讲到这里的时候,我们没讲函数,但是这道题如果我们把判断是否为回文数,判断是否为质数,都另成一个函数模块,将使得程序变得更加简洁。我在这里也将函数版本的贴出来,有兴趣的可以看一下。 +...

                  November 12, 2020 · 3 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/database/index.html b/tags/database/index.html index fca53b27..1cdf1b01 100644 --- a/tags/database/index.html +++ b/tags/database/index.html @@ -1,6 +1,6 @@ Database | Zs's Blog -

                  数据库的一些基础知识总结

                  了解SQL 一.什么是SQL SQL是结构化查询语言(Structured Query Language)的缩写。是一种专门用来与数据库通信的语言。 +

                  数据库的一些基础知识总结

                  了解SQL 一.什么是SQL SQL是结构化查询语言(Structured Query Language)的缩写。是一种专门用来与数据库通信的语言。 二.什么是数据库? 数据库(Database):保存有组织的数据的容器(通常是一个文件或一组文件)。 ​[scode type = “yellow”]需要注意的是,有时候我们把数据库软件也简称为数据库,但是数据库软件和数据库有本质区别,数据库软件应称为DBMS(数据库管理系统),我们通过数据库软件对数据库进行删减等操作,他代替你操作和访问数据库。[/scode] 三.数据库的组成 表 数据库中通常有多张表,这类似于一个清单。就好像我们管理两个班级就可以用两个表单。 @@ -37,5 +37,5 @@ 参考链接 数据库设计三大范式_dosthing 数据库设计三大范式_张龙豪 mysql必知必会

                  September 11, 2020 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/defaults/index.html b/tags/defaults/index.html index 91796e7e..7a11a4f4 100644 --- a/tags/defaults/index.html +++ b/tags/defaults/index.html @@ -1,10 +1,10 @@ Defaults | Zs's Blog -

                  My App Defaults - 2023 Fall

                  After seeing Duel of the Defaults and App Defaults, I’d like to share here some of my app defaults at the end of 2023. +

                  My App Defaults - 2023 Fall

                  After seeing Duel of the Defaults and App Defaults, I’d like to share here some of my app defaults at the end of 2023. Since I am from China, some apps may not be suitable to everyone, such as WeChat, NeteaseMusic, etc. The software built-in on iPhone or Mac will have the .app extension. -📨 Mail Client:Gmail, Mail.app 📮 Mail Server:Gmail 📝 Notes:Obsidian, Typora, Notes.app ✅ To-Do:Reminders.app 📷 iPhone Photo Shooting: Camera....

                  December 3, 2023 · 1 min · zzsqwq
                  © 2024 Zs's Blog +📨 Mail Client:Gmail, Mail.app 📮 Mail Server:Gmail 📝 Notes:Obsidian, Typora, Notes.app ✅ To-Do:Reminders.app 📷 iPhone Photo Shooting: Camera.app 📸 Photo Shooting: Nikon ZFC, iPhone 13 🟦 Photo Management & Editing: Photos.app, Capture One, Pixelmator Pro 📆 Calendar: Dato, Calendar.app 📁 Cloud File Storage: iCloud Drive 📖 RSS Client: NetNewsWire 📖 RSS Server: FreshRSS with RSSHub 🙍🏻‍♂️ Contacts: Contacts.app 🌐 Browser: Microsoft Edge 💬 Chat: Telegram, WeChat(Not recommended, unless absolutely necessary.), iMeesage.app? 🔖 Bookmarks: Microsoft Edge 📑 Read It Later: Omnivore 📜 Word Processing: Lark Docs, Microsoft 365 📈 Spreadsheets: N/A 📊 Presentations: Microsoft PowerPoint 🛒 Shopping Lists: N/A 🍴 Meal Planning: N/A 💰 Budgeting and Personal Finance: iCost, Subscriptions 📰 News: Channels on Telegram, RSS, Web 🎵 Music: NeteaseMusic, Music.app 🎤 Podcasts: N/A 🔐 Password Management: iCloud Keychain 🧑‍💻 Code Editor: JetBrains Series, VS Code, Vim 🪄 Launcher: HapiGo 😘 Blog Platform: Hugo

                  December 3, 2023 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/docker/index.html b/tags/docker/index.html index a86ff0e0..69e7128b 100644 --- a/tags/docker/index.html +++ b/tags/docker/index.html @@ -1,12 +1,13 @@ Docker | Zs's Blog -

                  Docker-Gitlab 与主机共用 ssh 的 22 端口

                  背景 在使用 Docker 搭建 Gitlab/Gitee 会导致无法与主机端共用 22 端口,这导致 ssh 连接的时候会使用形如 ssh://git@git.xxxx.cn:4022/zs/zsblog.git 的 ssh 链接,而不是像官方 Gitlab 那种非常干净的 git@git.xxxx.cn/zs/zsblog.git 链接。这对于我这种强迫症而言非常的难受啊,但因为主机的 22 端口已经被占用了,无法共用,所以需要考虑两者共享端口的问题。 +

                  Docker-Gitlab 与主机共用 ssh 的 22 端口

                  背景 在使用 Docker 搭建 Gitlab/Gitee 会导致无法与主机端共用 22 端口,这导致 ssh 连接的时候会使用形如 ssh://git@git.xxxx.cn:4022/zs/zsblog.git 的 ssh 链接,而不是像官方 Gitlab 那种非常干净的 git@git.xxxx.cn/zs/zsblog.git 链接。这对于我这种强迫症而言非常的难受啊,但因为主机的 22 端口已经被占用了,无法共用,所以需要考虑两者共享端口的问题。 虽说是两者共用,但其实还是使用类似于端口转发的特点,简单说就是在主机设置 git 用户,然后通过一个脚本将 git 用户的所有 ssh 流量转发到 Gitlab 容器中,从而完成对应的事情。 关于 Gitee 的设置,Gitee 官方的 Docker 部署教程1已经说的很清楚了,按照该步骤执行完全没问题。 而关于 Gitlab 貌似没有比较详尽的教程,搜索后发现了一个 Issue2 以及一篇博文3,后者讲的比较清楚,但是经过实践后发现存在一定问题,因此决定将可行的方案记录下来。 具体步骤 一、初始设置 在开始之前,docker-compose.yml 中设置比较关键的几个配置如下: -gitlab-web: image: 'gitlab/gitlab-ce:latest' container_name: 'gitlab' restart: always environment: GITLAB_OMNIBUS_CONFIG: | gitlab_rails['gitlab_shell_ssh_port'] = 4022 ports: - '3090:80' - '4022:22' - '6060:6060' volumes: - '/srv/gitlab/config:/etc/gitlab' - '/srv/gitlab/logs:/var/log/gitlab' - '/srv/gitlab/data:/var/opt/gitlab' - ....

                  April 24, 2022 · 3 min · zzsqwq
                  © 2024 Zs's Blog +gitlab-web: image: 'gitlab/gitlab-ce:latest' container_name: 'gitlab' restart: always environment: GITLAB_OMNIBUS_CONFIG: | gitlab_rails['gitlab_shell_ssh_port'] = 4022 ports: - '3090:80' - '4022:22' - '6060:6060' volumes: - '/srv/gitlab/config:/etc/gitlab' - '/srv/gitlab/logs:/var/log/gitlab' - '/srv/gitlab/data:/var/opt/gitlab' - .... #一些其他的配置 如上设置基本可以确保 Gitlab 形如 ssh://git@git.xxxx.cn:4022/zs/zsblog.git 的链接可以使用。 +...

                  April 24, 2022 · 3 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/dp/index.html b/tags/dp/index.html index 04d83c98..13252692 100644 --- a/tags/dp/index.html +++ b/tags/dp/index.html @@ -1,6 +1,6 @@ Dp | Zs's Blog -

                  树形dp例题

                  前言 学OI的时候就做过树形dp的题,不过那时候全在划水。看了看题解还不太懂就直接照着题解写了,现在再回来看还是不会QAQ,所以就再看看然后自己写了一遍。 +

                  树形dp例题

                  前言 学OI的时候就做过树形dp的题,不过那时候全在划水。看了看题解还不太懂就直接照着题解写了,现在再回来看还是不会QAQ,所以就再看看然后自己写了一遍。 ...

                  February 20, 2020 · 2 min · zzsqwq

                  dp练习

                  A. 矩阵取数游戏 题意 给定一个 $n\times m$ 的矩阵,其中每个元素为非负整数。每次你可以从每行的行首或行末取一个元素,得到的分数为当前元素的值 $a_{ij}\times 2^k$ ,$k$ 为当前是第几次取该行上的元素。 问最大得分为多少。 ...

                  February 18, 2020 · 2 min · zzsqwq

                  dp习题练习

                  A. 方格取数 题意 有一个 $N*N$ 的整数方阵,每个点初始值为0,在一些点上放上数,一个人从左上角走到右下角,规定只能向下或向右走,当他经过的点上有数时会取走它,问走两遍最多能取的数的和最大为多少。 ...

                  February 12, 2020 · 2 min · zzsqwq

                  背包进阶

                  1. 分组背包 题意 在01背包基础上,将其中的物体分成 $k$ 组,每组内的物品相互冲突,即只能取其中一个,问最大价值。 @@ -9,5 +9,5 @@ ...

                  February 8, 2020 · 2 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/dp/index.xml b/tags/dp/index.xml index 718ace3c..74116006 100644 --- a/tags/dp/index.xml +++ b/tags/dp/index.xml @@ -1116,58 +1116,58 @@ <li>碱基配对时相似度的定义如下</li> </ul> <table> -<thead> -<tr> -<th style="text-align:center"></th> -<th style="text-align:center">A</th> -<th style="text-align:center">C</th> -<th style="text-align:center">G</th> -<th style="text-align:center">T</th> -<th style="text-align:center">空</th> -</tr> -</thead> -<tbody> -<tr> -<td style="text-align:center">A</td> -<td style="text-align:center">5</td> -<td style="text-align:center">-1</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-1</td> -<td style="text-align:center">-3</td> -</tr> -<tr> -<td style="text-align:center">C</td> -<td style="text-align:center">-1</td> -<td style="text-align:center">5</td> -<td style="text-align:center">-3</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-4</td> -</tr> -<tr> -<td style="text-align:center">G</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-3</td> -<td style="text-align:center">5</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-2</td> -</tr> -<tr> -<td style="text-align:center">T</td> -<td style="text-align:center">-1</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">5</td> -<td style="text-align:center">-1</td> -</tr> -<tr> -<td style="text-align:center">空</td> -<td style="text-align:center">-3</td> -<td style="text-align:center">-4</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-1</td> -<td style="text-align:center">非法</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: center"></th> + <th style="text-align: center">A</th> + <th style="text-align: center">C</th> + <th style="text-align: center">G</th> + <th style="text-align: center">T</th> + <th style="text-align: center">空</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: center">A</td> + <td style="text-align: center">5</td> + <td style="text-align: center">-1</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-1</td> + <td style="text-align: center">-3</td> + </tr> + <tr> + <td style="text-align: center">C</td> + <td style="text-align: center">-1</td> + <td style="text-align: center">5</td> + <td style="text-align: center">-3</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-4</td> + </tr> + <tr> + <td style="text-align: center">G</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-3</td> + <td style="text-align: center">5</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-2</td> + </tr> + <tr> + <td style="text-align: center">T</td> + <td style="text-align: center">-1</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">5</td> + <td style="text-align: center">-1</td> + </tr> + <tr> + <td style="text-align: center">空</td> + <td style="text-align: center">-3</td> + <td style="text-align: center">-4</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-1</td> + <td style="text-align: center">非法</td> + </tr> + </tbody> </table> <hr> <h4 id="思路-2">思路</h4> diff --git a/tags/dp/page/2/index.html b/tags/dp/page/2/index.html index 42edd45b..c9b1b359 100644 --- a/tags/dp/page/2/index.html +++ b/tags/dp/page/2/index.html @@ -1,10 +1,10 @@ Dp | Zs's Blog -

                  基础线性dp例题 #2

                  1. 石子归并 题意 $N$ 堆石子摆成一条线。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价。计算将 $N$ 堆石子合并成一堆的最小代价。 思路 很经典的区间dp例题,我们可以用 $dp[i][j]$ 来表示合并 $i\sim j$ 所需的最小代价,通过枚举中间的断点,来通过方程 $dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+cost[i][j])$ ,其中 $cost[i][j]$ 表示从 $i\sim j$ 的石子总数,通过前缀和很容易计算。在进行状态转移时需要前面状态已知,因为是枚举中间断点,所以断开区间的长度一定要小于原区间,因此在转移之前需要确保比他短的区间都已经达到了最小代价,因此我们可以通过枚举区间长度从 $2\sim N$ 来实现。 +

                  基础线性dp例题 #2

                  1. 石子归并 题意 $N$ 堆石子摆成一条线。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价。计算将 $N$ 堆石子合并成一堆的最小代价。 思路 很经典的区间dp例题,我们可以用 $dp[i][j]$ 来表示合并 $i\sim j$ 所需的最小代价,通过枚举中间的断点,来通过方程 $dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+cost[i][j])$ ,其中 $cost[i][j]$ 表示从 $i\sim j$ 的石子总数,通过前缀和很容易计算。在进行状态转移时需要前面状态已知,因为是枚举中间断点,所以断开区间的长度一定要小于原区间,因此在转移之前需要确保比他短的区间都已经达到了最小代价,因此我们可以通过枚举区间长度从 $2\sim N$ 来实现。 ...

                  February 7, 2020 · 2 min · zzsqwq

                  基础线性dp例题

                  前言 某位大佬曾经说过,dp不会没问题,想不到状态转移方程没问题,多做题就会了。所以,我打算多刷点dp题。那么,先从基础刷起吧。 1. P1091 合唱队形 题意 已知序列 $a$ 有 $n$ 个数,通过取出其中一些数可以使他满足严格的先增再减序列,问最少取出几个。 ...

                  February 6, 2020 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/fcos/index.html b/tags/fcos/index.html index ac11075f..4cbe03a7 100644 --- a/tags/fcos/index.html +++ b/tags/fcos/index.html @@ -1,6 +1,6 @@ FCOS | Zs's Blog -

                  基于地平线 HAT 训练与部署 FCOS 全流程

                  前言 最近想要使用自己采集与标注的数据集来训练与部署一下地平线微调过的 FCOS 网络,在询问和查看文档后发现如果想基于官方微调的模型训练,需要使用提供 HAT(Horizon Algorithm Toolkit,海图) 来进行,具体的文档可以查看:Horizon Algorithm Toolkit 文档,这是在线的版本,版本可能会比较旧,想看最新版的可以查看离线的版本,位置在 OE(Open Explorer,天工开物) 包的 doc 目录下,如下图: +

                  基于地平线 HAT 训练与部署 FCOS 全流程

                  前言 最近想要使用自己采集与标注的数据集来训练与部署一下地平线微调过的 FCOS 网络,在询问和查看文档后发现如果想基于官方微调的模型训练,需要使用提供 HAT(Horizon Algorithm Toolkit,海图) 来进行,具体的文档可以查看:Horizon Algorithm Toolkit 文档,这是在线的版本,版本可能会比较旧,想看最新版的可以查看离线的版本,位置在 OE(Open Explorer,天工开物) 包的 doc 目录下,如下图: 想要方便的查看离线文档可以通过 Python 来实现,在 doc 目录下执行: python3 -m http.server 3000 这样就可以在本地的 0.0.0.0:3000 地址开启一个 http server,随后可以在本地浏览器使用 localhost:3000 或者其他电脑浏览器使用 {ip}:3000 来访问文档。 但是查看 文档 过后会发现,文档其实也没有那么的全面,讲的比较简单,尝试了一下中间坑还挺多的,社区里面关于这方面的帖子也不多12,因此想记录下我尝试的全流程,也可以作为对上面教程文档的补充。 @@ -15,8 +15,10 @@ Nvidia Docker: 2.11.0-1 GPU: RTX3090 NVIDIA Driver Version: 515.65.01 -CUDA Version: 11....

                  February 25, 2023 · 9 min · zzsqwq
                  © 2024 Zs's Blog +CUDA Version: 11.7 +OE Version: v2.4.2( gcc-9.3.0 For XJ3 ) +...

                  February 25, 2023 · 9 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/git/index.html b/tags/git/index.html index 578d9ece..8df2d3fd 100644 --- a/tags/git/index.html +++ b/tags/git/index.html @@ -1,6 +1,6 @@ Git | Zs's Blog -

                  关于Git的一些理解

                  前言 前段时间在 Github 学完了关于 git 的小游戏 learnGitBranching ,受益匪浅。 +

                  关于Git的一些理解

                  前言 前段时间在 Github 学完了关于 git 的小游戏 learnGitBranching ,受益匪浅。 它通过可视化的方式将分支的关系,每条命令的作用等都明明白白的体现出来,可以很直观的感受到你每条命令对整个分支树,每一个 ref 的作用。 通过这种学习感觉自己对 Git 的理解更加深入一步,能够理解其中的原理,而不是浅尝辄止,照猫画虎。 学习中记了一些零零散散的思路,想要写一篇笔记记录出来,之前已经写过一个简单的 Git 教程,这篇教程将会更加深入,希望可以帮助大家更好的掌握 Git。 @@ -8,7 +8,8 @@ Git中的分区 首先,Git中存在三大分区,分别是工作区、暂存区、版本库。其中, 工作区即我们工作的目录,暂存区是我们执行 git add 后文件存在的区域。 我们可以通过 git status 对两种状态进行查看,例如: -~/test master* base ❯ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: test Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>....

                  July 23, 2021 · 3 min · zzsqwq

                  Git的简易教程

                  前言 最近在复习Git,因此顺手做个笔记分享出来,方便大家学习和查阅。相信无论是以后的课程作业还是工作,我们都会或多或少的接触/用到Git。 +~/test master* base ❯ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: test Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: test 上图中存在两部分, 分别为 Changes to be committed 这里是表示的版本库与暂存区的区别,还有Changes not staged for commit ,它表示的是工作区与暂存区的区别。 +...

                  July 23, 2021 · 3 min · zzsqwq

                  Git的简易教程

                  前言 最近在复习Git,因此顺手做个笔记分享出来,方便大家学习和查阅。相信无论是以后的课程作业还是工作,我们都会或多或少的接触/用到Git。 什么是Git? Git你可能没听说过,但是我相信你应该听说过Github,毕竟是全球最大的同性交友网站。他和Git有着密不可分的联系,我们后续再详细介绍。 Git的中文全称叫 分布式版本控制系统 ,版本控制系统是什么意思呢?我们举一个简单的例子,你在做一个大作业,很可能要写上千行的代码,但是你可能写完一个功能以后,对他不够满意,但是又害怕改了以后后悔了,又找不回来了,所以你可能就有很多版本,版本1,版本2,版本3等等等。Git就是解决这个问题的,让你文件能够保持最新,但是又能恢复到之前的版本。 那么既然有分布式版本控制系统,就有 集中式版本控制系统,前者的代表是 Git ,后者的代表有 SVN、CVS 等。 @@ -31,8 +32,9 @@ git init 顾名思义这就是一个初始化的过程,运行以后在当前目录生成一个 .git 文件夹,里面是我们版本控制的数据,一般不要修改。 把文件添加到Git的暂存区 这里出现了 暂存区 这个名词,Git内部的逻辑大概把我们工作的过程分为了三部分 -一个是 工作区 ,这个就是我们本地的文件夹。 一个是 暂存区 ,这是我们把文件暂时放到暂存区里,没有决定更新我们的版本。 一个是 最终分支,这就是我们最终的版本存放的位置。 贴一张廖雪峰老师教程中的一张图,我觉得还挺形象的。...

                  December 5, 2020 · 2 min · zzsqwq
                  © 2024 Zs's Blog +一个是 工作区 ,这个就是我们本地的文件夹。 一个是 暂存区 ,这是我们把文件暂时放到暂存区里,没有决定更新我们的版本。 一个是 最终分支,这就是我们最终的版本存放的位置。 贴一张廖雪峰老师教程中的一张图,我觉得还挺形象的。 +...

                  December 5, 2020 · 2 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/github/index.html b/tags/github/index.html index 2d6ad4aa..0a9b0f0c 100644 --- a/tags/github/index.html +++ b/tags/github/index.html @@ -1,14 +1,15 @@ Github | Zs's Blog -

                  记一次 GitHub 账号突然被 suspended 的经历

                  TL;DR 我在 2023.11.07 凌晨被 GitHub 封禁了账号,GitHub 账号被 suspended 后会在 GitHub 上完全除名(只有自建创建的组织不会消失)。 +

                  记一次 GitHub 账号突然被 suspended 的经历

                  TL;DR 我在 2023.11.07 凌晨被 GitHub 封禁了账号,GitHub 账号被 suspended 后会在 GitHub 上完全除名(只有自建创建的组织不会消失)。 被封禁后我首先通过 Google 查找了相关的文章。 根据博主 @phith0n 的指引首先通过 API:https://api.github.com/users/[username]/starred 备份了自己 star 过的项目,同时通过 Can’t sign-in form 来在无法登陆的情况下发起 GitHub Support 工单来询问/请求解封/询问原因等,一般在两天内收到了回复。最终账号顺利恢复。 我此次被封禁的原因是由于管理的组织内部有成员被盗号,在组织内创建了违法仓库,因此管理员和被盗号的成员都被封禁了,但后续都被解除了封禁。同时也有可能因为创建违反 DMCA 条款 的仓库、fork 违反 DMCA 条款的仓库、贩卖学生/教师教育包等原因被封禁。 背景 大约在 2023.11.07 凌晨 00:30 左右,在 GitHub 上看到了一个不错的项目想要 Star,被提示没有登陆。当时我还在想:“怎么这次 session 过期的这么快?” 就当我边疑惑边重新登录后,突然收到了下图的提示我的账号「Account suspended」: 确认无法登录后,查看邮箱没有任何相关通知。同时我查看了其他内容是否还存在,最后综合表现如下: 没有任何邮件/信息通知被封禁及更加具体的封禁原因,只告诉违反了 ToS 个人页面(https://github.com/zzsqwq)无法访问,访问显示 404 提的相关 Issue 全部被删除(隐藏),无法找到 个人创建的所有项目,访问全部 404,也无法拉取 自己参与的项目,被除名 自己加入的组织,被除名 自己创建的组织,访问 404 简单说就是跟这个账号从来没存在过一样,除了仍可以登陆,但是显示 suspended。接下来开始尝试找办法恢复。 -恢复经过 试图查找封禁原因 首先看提示上显示违反了 Github Terms of Service,快速的看了一眼 ToS 没发现我有什么明显违规的地方。...

                  November 12, 2023 · 4 min · zzsqwq
                  © 2024 Zs's Blog +恢复经过 试图查找封禁原因 首先看提示上显示违反了 Github Terms of Service,快速的看了一眼 ToS 没发现我有什么明显违规的地方。 +...

                  November 12, 2023 · 4 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/gitlab/index.html b/tags/gitlab/index.html index 35eed809..2e0adc9a 100644 --- a/tags/gitlab/index.html +++ b/tags/gitlab/index.html @@ -1,12 +1,13 @@ Gitlab | Zs's Blog -

                  Docker-Gitlab 与主机共用 ssh 的 22 端口

                  背景 在使用 Docker 搭建 Gitlab/Gitee 会导致无法与主机端共用 22 端口,这导致 ssh 连接的时候会使用形如 ssh://git@git.xxxx.cn:4022/zs/zsblog.git 的 ssh 链接,而不是像官方 Gitlab 那种非常干净的 git@git.xxxx.cn/zs/zsblog.git 链接。这对于我这种强迫症而言非常的难受啊,但因为主机的 22 端口已经被占用了,无法共用,所以需要考虑两者共享端口的问题。 +

                  Docker-Gitlab 与主机共用 ssh 的 22 端口

                  背景 在使用 Docker 搭建 Gitlab/Gitee 会导致无法与主机端共用 22 端口,这导致 ssh 连接的时候会使用形如 ssh://git@git.xxxx.cn:4022/zs/zsblog.git 的 ssh 链接,而不是像官方 Gitlab 那种非常干净的 git@git.xxxx.cn/zs/zsblog.git 链接。这对于我这种强迫症而言非常的难受啊,但因为主机的 22 端口已经被占用了,无法共用,所以需要考虑两者共享端口的问题。 虽说是两者共用,但其实还是使用类似于端口转发的特点,简单说就是在主机设置 git 用户,然后通过一个脚本将 git 用户的所有 ssh 流量转发到 Gitlab 容器中,从而完成对应的事情。 关于 Gitee 的设置,Gitee 官方的 Docker 部署教程1已经说的很清楚了,按照该步骤执行完全没问题。 而关于 Gitlab 貌似没有比较详尽的教程,搜索后发现了一个 Issue2 以及一篇博文3,后者讲的比较清楚,但是经过实践后发现存在一定问题,因此决定将可行的方案记录下来。 具体步骤 一、初始设置 在开始之前,docker-compose.yml 中设置比较关键的几个配置如下: -gitlab-web: image: 'gitlab/gitlab-ce:latest' container_name: 'gitlab' restart: always environment: GITLAB_OMNIBUS_CONFIG: | gitlab_rails['gitlab_shell_ssh_port'] = 4022 ports: - '3090:80' - '4022:22' - '6060:6060' volumes: - '/srv/gitlab/config:/etc/gitlab' - '/srv/gitlab/logs:/var/log/gitlab' - '/srv/gitlab/data:/var/opt/gitlab' - ....

                  April 24, 2022 · 3 min · zzsqwq
                  © 2024 Zs's Blog +gitlab-web: image: 'gitlab/gitlab-ce:latest' container_name: 'gitlab' restart: always environment: GITLAB_OMNIBUS_CONFIG: | gitlab_rails['gitlab_shell_ssh_port'] = 4022 ports: - '3090:80' - '4022:22' - '6060:6060' volumes: - '/srv/gitlab/config:/etc/gitlab' - '/srv/gitlab/logs:/var/log/gitlab' - '/srv/gitlab/data:/var/opt/gitlab' - .... #一些其他的配置 如上设置基本可以确保 Gitlab 形如 ssh://git@git.xxxx.cn:4022/zs/zsblog.git 的链接可以使用。 +...

                  April 24, 2022 · 3 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/hat/index.html b/tags/hat/index.html index c9b058da..718ffbf9 100644 --- a/tags/hat/index.html +++ b/tags/hat/index.html @@ -1,6 +1,6 @@ HAT | Zs's Blog -

                  基于地平线 HAT 训练与部署 FCOS 全流程

                  前言 最近想要使用自己采集与标注的数据集来训练与部署一下地平线微调过的 FCOS 网络,在询问和查看文档后发现如果想基于官方微调的模型训练,需要使用提供 HAT(Horizon Algorithm Toolkit,海图) 来进行,具体的文档可以查看:Horizon Algorithm Toolkit 文档,这是在线的版本,版本可能会比较旧,想看最新版的可以查看离线的版本,位置在 OE(Open Explorer,天工开物) 包的 doc 目录下,如下图: +

                  基于地平线 HAT 训练与部署 FCOS 全流程

                  前言 最近想要使用自己采集与标注的数据集来训练与部署一下地平线微调过的 FCOS 网络,在询问和查看文档后发现如果想基于官方微调的模型训练,需要使用提供 HAT(Horizon Algorithm Toolkit,海图) 来进行,具体的文档可以查看:Horizon Algorithm Toolkit 文档,这是在线的版本,版本可能会比较旧,想看最新版的可以查看离线的版本,位置在 OE(Open Explorer,天工开物) 包的 doc 目录下,如下图: 想要方便的查看离线文档可以通过 Python 来实现,在 doc 目录下执行: python3 -m http.server 3000 这样就可以在本地的 0.0.0.0:3000 地址开启一个 http server,随后可以在本地浏览器使用 localhost:3000 或者其他电脑浏览器使用 {ip}:3000 来访问文档。 但是查看 文档 过后会发现,文档其实也没有那么的全面,讲的比较简单,尝试了一下中间坑还挺多的,社区里面关于这方面的帖子也不多12,因此想记录下我尝试的全流程,也可以作为对上面教程文档的补充。 @@ -15,8 +15,10 @@ Nvidia Docker: 2.11.0-1 GPU: RTX3090 NVIDIA Driver Version: 515.65.01 -CUDA Version: 11....

                  February 25, 2023 · 9 min · zzsqwq
                  © 2024 Zs's Blog +CUDA Version: 11.7 +OE Version: v2.4.2( gcc-9.3.0 For XJ3 ) +...

                  February 25, 2023 · 9 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/horizon-robotics/index.html b/tags/horizon-robotics/index.html index c1be5b8f..28876373 100644 --- a/tags/horizon-robotics/index.html +++ b/tags/horizon-robotics/index.html @@ -1,6 +1,6 @@ Horizon Robotics | Zs's Blog -

                  基于地平线 HAT 训练与部署 FCOS 全流程

                  前言 最近想要使用自己采集与标注的数据集来训练与部署一下地平线微调过的 FCOS 网络,在询问和查看文档后发现如果想基于官方微调的模型训练,需要使用提供 HAT(Horizon Algorithm Toolkit,海图) 来进行,具体的文档可以查看:Horizon Algorithm Toolkit 文档,这是在线的版本,版本可能会比较旧,想看最新版的可以查看离线的版本,位置在 OE(Open Explorer,天工开物) 包的 doc 目录下,如下图: +

                  基于地平线 HAT 训练与部署 FCOS 全流程

                  前言 最近想要使用自己采集与标注的数据集来训练与部署一下地平线微调过的 FCOS 网络,在询问和查看文档后发现如果想基于官方微调的模型训练,需要使用提供 HAT(Horizon Algorithm Toolkit,海图) 来进行,具体的文档可以查看:Horizon Algorithm Toolkit 文档,这是在线的版本,版本可能会比较旧,想看最新版的可以查看离线的版本,位置在 OE(Open Explorer,天工开物) 包的 doc 目录下,如下图: 想要方便的查看离线文档可以通过 Python 来实现,在 doc 目录下执行: python3 -m http.server 3000 这样就可以在本地的 0.0.0.0:3000 地址开启一个 http server,随后可以在本地浏览器使用 localhost:3000 或者其他电脑浏览器使用 {ip}:3000 来访问文档。 但是查看 文档 过后会发现,文档其实也没有那么的全面,讲的比较简单,尝试了一下中间坑还挺多的,社区里面关于这方面的帖子也不多12,因此想记录下我尝试的全流程,也可以作为对上面教程文档的补充。 @@ -15,8 +15,10 @@ Nvidia Docker: 2.11.0-1 GPU: RTX3090 NVIDIA Driver Version: 515.65.01 -CUDA Version: 11....

                  February 25, 2023 · 9 min · zzsqwq
                  © 2024 Zs's Blog +CUDA Version: 11.7 +OE Version: v2.4.2( gcc-9.3.0 For XJ3 ) +...

                  February 25, 2023 · 9 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/hp-laserjet/index.html b/tags/hp-laserjet/index.html index 8f8cb9d1..5e8105ac 100644 --- a/tags/hp-laserjet/index.html +++ b/tags/hp-laserjet/index.html @@ -1,6 +1,6 @@ HP LaserJet | Zs's Blog -

                  利用树莓派为HP LaserJet 1020配置无线打印功能

                  前言 最近基地的打印机突然又好起来了。 +

                  利用树莓派为HP LaserJet 1020配置无线打印功能

                  前言 最近基地的打印机突然又好起来了。 因为基地的打印机型号比较老——HP LaserJet 1020,没有无线打印的功能。所以之前一位学长1 用树莓派配置了打印机的无线打印功能,但是后来发现有一些问题,有时候发送打印请求树莓派无法接收,而且不知道为何,学长之前用的是树莓派自己创建WiFi,连接对应WiFi才能打印,但是这个显然不是最优的解决办法。 考虑到之间已经配置好基地WiFi,我决定重新配置一下打印功能,使其连接基地WiFi即可实现局域网打印。 配置过程 查看树莓派内容 通过ssh连接树莓派,发现里面除了Github上的一个开源项目create_ap ,就没有什么其他的内容了,连接屏幕后发现没有任何图像信号,无从下手,因此考虑重新刷机。 @@ -14,8 +14,9 @@ $ sudo ifconfig 查看WiFi对应的IP,至此,树莓派可以摆脱屏幕,我们可以使用电脑进行使用 ssh 连接。 这里也可以使用网线进行连接,具体操作如下 用网线连接树莓派和自己的电脑。 -在树莓派的利用 nmtui 选择 Edit a connection ,Add一个Ethernet connect,对IPv4 CONFIGURATION进行设置,首先讲 Automatic 设置为 Manual,设置 Address 为 静态IP 如 192....

                  July 18, 2021 · 2 min · zzsqwq
                  © 2024 Zs's Blog +在树莓派的利用 nmtui 选择 Edit a connection ,Add一个Ethernet connect,对IPv4 CONFIGURATION进行设置,首先讲 Automatic 设置为 Manual,设置 Address 为 静态IP 如 192.168.3.2 ,Gateway 设置为 192.168.3.1 。 +...

                  July 18, 2021 · 2 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/hugo/index.html b/tags/hugo/index.html index 48bce9d9..b6d76242 100644 --- a/tags/hugo/index.html +++ b/tags/hugo/index.html @@ -1,6 +1,6 @@ Hugo | Zs's Blog -

                  一个基于 Hugo 的个人主页主题

                  背景 之前看到过学长学姐做过个人主页,多是用来申请一些学校的夏令营使用的,觉得非常的 Nice,自己也想搞一个。 +

                  一个基于 Hugo 的个人主页主题

                  背景 之前看到过学长学姐做过个人主页,多是用来申请一些学校的夏令营使用的,觉得非常的 Nice,自己也想搞一个。 大家之前好像大多用的是基于 Hexo 的一个主题 — hexo-theme-academia,但是由于之前我用过 Hexo,觉得他有一些比较明显的弊端,例如环境配置比较麻烦、需要安装 Nodejs、npm 等环境,然后再安装 Hexo。其次它的构建速度比较慢,用起来感觉比较僵硬。 后来随着了解增多,尝试了 Typecho、WordPress,Hugo 等主题后,目前还是决定使用 Hugo。它构建速度快,而且安装简单,在 Ubuntu 上只需要一行 sudo apt install hugo 即可,不可谓不简单。因此萌生了移植一个 Hugo 版本主题的想法,刚好可以锻炼一下自己。 欢迎点击 这里 查看我的个人主页。 @@ -18,5 +18,5 @@ 中文效果图:

                  May 3, 2022 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/index.html b/tags/index.html index 16aab273..ba42babe 100644 --- a/tags/index.html +++ b/tags/index.html @@ -1,6 +1,6 @@ Tags | Zs's Blog -
                  \ No newline at end of file diff --git a/tags/iris/index.html b/tags/iris/index.html index 9c6e4d21..0d0c6477 100644 --- a/tags/iris/index.html +++ b/tags/iris/index.html @@ -1,6 +1,6 @@ Iris | Zs's Blog -

                  2021版小新Pro14 Ubuntu 20.04 配置指南

                  2021版小新Pro14 Ubuntu 20.04 配置指南 补充 最近重装了 Ubuntu 20.04,又找了相关的一些帖子,发现 聯想Yoga 14s 2021款裝機小記 中提到了下文中提到的屏幕闪烁的问题,解决办法是:只需要在内核参数中加入 i915.enable_psr=0 即可。 +

                  2021版小新Pro14 Ubuntu 20.04 配置指南

                  2021版小新Pro14 Ubuntu 20.04 配置指南 补充 最近重装了 Ubuntu 20.04,又找了相关的一些帖子,发现 聯想Yoga 14s 2021款裝機小記 中提到了下文中提到的屏幕闪烁的问题,解决办法是:只需要在内核参数中加入 i915.enable_psr=0 即可。 具体操作步骤如下: $ sudo vim /etc/default/grub 在 GRUB_CMDLINE_LINUX_DEFAULT 这一行的最后添加 i915.enable_psr=0,保存后终端运行: $ sudo update-grub 然后重启即可。 @@ -8,8 +8,9 @@ CPU:酷睿 i5-11300H 显卡:集成显卡 Intel 锐炬Iris Xe 内存:16G 外存:512 SSD 屏幕:分辨率 2880x1800、400nits、100%sRGB 这里需要注意的是,不同时间出的小新Pro14配置是不太一样的,所以我这里列了一下配置。主要区别在于有一部分是2.2K分辨率+MX450显卡,而我这个是2.8K分辨率+锐炬Iris Xe显卡。 为了工作的需要,要装一个Ubuntu,先是装了之前用过的 Ubuntu 18.04,安装后发现触摸板无法使用,一系列探索后无果,在朋友的推荐下,还是决定安装 Ubuntu 20.04 试一下,踩了一些坑,在这里记录一下。 问题列表 如果你遇到了以下问题,那么这篇文章的方法可能会对你有益处: -Ubuntu 18.04 相关 Ubuntu 18.04 无法使用触摸板 Ubuntu 18.04 无法使用内置键盘 Ubuntu 18.04 无法调节亮 Ubuntu 18.04 查看GPU发现是llvm,而不是Iris Xe Ubuntu 20.04 相关 Ubuntu 20....

                  November 2, 2021 · 2 min · zzsqwq
                  © 2024 Zs's Blog +Ubuntu 18.04 相关 Ubuntu 18.04 无法使用触摸板 Ubuntu 18.04 无法使用内置键盘 Ubuntu 18.04 无法调节亮 Ubuntu 18.04 查看GPU发现是llvm,而不是Iris Xe Ubuntu 20.04 相关 Ubuntu 20.04 进入后屏幕花屏、黑屏 Ubuntu 20.04 查看GPU发现是llvm,而不是Iris Xe 现在达成的效果 Ubuntu 20.04 能够正常使用,触摸板以及外界屏幕,亮度调节均无问题。 +...

                  November 2, 2021 · 2 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/javascript/index.html b/tags/javascript/index.html index 2678ee51..ca04ce44 100644 --- a/tags/javascript/index.html +++ b/tags/javascript/index.html @@ -1,6 +1,6 @@ Javascript | Zs's Blog -

                  一个 Javascript 中异步的小技巧

                  前言 最近看了一些 js 有关的知识,其中令我这种初学者感到很头疼的一个问题就是异步问题。 +

                  一个 Javascript 中异步的小技巧

                  前言 最近看了一些 js 有关的知识,其中令我这种初学者感到很头疼的一个问题就是异步问题。 今天就我碰到的一个小问题详解一个关于异步的小技巧。 背景 我在程序中需要鉴权,来判断一个用户是普通用户还是管理员,针对不同的用户渲染不同的页面。 每个用户具有唯一的 ID,因此我只需要将管理员的 ID 放到数据库,然后加载程序的时候一一比对即可。 @@ -15,8 +15,9 @@ 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 所以此处加入 callback 以防止这种情况 这里判断了主程序内是否含有 userInfoReadyCallback 这个函数,如果有的话就执行。 -qq.getSetting({ success: res => { if (res.authSetting['scope.userInfo']) { // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框 qq.getUserInfo({ success: res => { // 可以将 res 发送给后台解码出 unionId this.globalData.userInfo = res.userInfo // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 if (this....

                  January 19, 2022 · 1 min · zzsqwq
                  © 2024 Zs's Blog +qq.getSetting({ success: res => { if (res.authSetting['scope.userInfo']) { // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框 qq.getUserInfo({ success: res => { // 可以将 res 发送给后台解码出 unionId this.globalData.userInfo = res.userInfo // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 if (this.userInfoReadyCallback) { this.userInfoReadyCallback(res) } } }) } } }) 页面初始化部分代码: +...

                  January 19, 2022 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/latex/index.html b/tags/latex/index.html index b17a5ee6..7bf49628 100644 --- a/tags/latex/index.html +++ b/tags/latex/index.html @@ -1,7 +1,7 @@ LaTeX | Zs's Blog -

                  LaTeX的一些总结

                  希腊字母表 ...

                  February 4, 2020 · 2 min · zzsqwq
                  © 2024 Zs's Blog +

                  LaTeX的一些总结

                  希腊字母表 ...

                  February 4, 2020 · 2 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号
                  \ No newline at end of file diff --git a/tags/linux/index.html b/tags/linux/index.html index 59c577c4..60851493 100644 --- a/tags/linux/index.html +++ b/tags/linux/index.html @@ -1,6 +1,6 @@ Linux | Zs's Blog -

                  Ubuntu18.04优化教程

                  前言 因为最近Ubuntu用的比较频繁,所以前一阵把Ubuntu16.04换成Ubuntu18.04了,并且囿于机械硬盘那启动速度,我忍痛割爱把我80G的固态硬盘分给了Ubuntu。 +

                  Ubuntu18.04优化教程

                  前言 因为最近Ubuntu用的比较频繁,所以前一阵把Ubuntu16.04换成Ubuntu18.04了,并且囿于机械硬盘那启动速度,我忍痛割爱把我80G的固态硬盘分给了Ubuntu。 后来,用着用着就觉得这个Ubuntu的原始界面确实不是特别的好看,配色偏基佬紫的感觉。“工欲善其事,必先利其器“,我们只有将自己的工作环境布置的舒心一些才能有做下去的动力!所以我想给Ubuntu换一个看起来舒服点的界面,然后上网找教程乱七八糟的倒腾了一会,感觉换完以后完全不一样了,这个界面真的好看!!用起来也特别的舒心,感觉自己马上就要告别Windows投奔Linux的怀抱了。后续还有一些其他的优化,例如装QQ、微信、配置终端等,一并写在这里吧。 Ubuntu界面的优化 具体效果 先放几张效果图上来,是我改后的界面。大概就是这样(自我感觉挺好看的),当然也有其他的主题可供选择。 1.安装GNOME桌面环境主题配置工具 如果要改主题,那么首先要有一个利器,这里我用的Ubuntu18.04,桌面环境为 GNOME 3.28.2 ,因为我目前接触的只有GNOME桌面环境的,Ubuntu18.04本来的桌面环境就是GNOME,但是Ubuntu16.04好像没有自带,但是可以安装,这里大家可以自行百度了解。 @@ -15,9 +15,10 @@ 然后我们回到 GNOME Tweaks 软件中就可以发现,我们已经可以在主题\图标\光标\Shell清单中找到我们移动到文件夹中的文件了,然后选择就可以切换了。这里需要注意的,很多主题都是自带Shell的,你下了一个主题,那么你可以在Shell和主题这两个栏目中都找到他们,是一个配套的。 4.一些后续的调整 我们后续可以改变左边收藏夹的位置,我觉得放在左边有一丢丢的丑,所以我选择把它放在的下面。 我们去Ubuntu软件中搜索 Dash to dock,然后安装这个拓展,然后打开 GNOME Tweaks 软件在拓展中找到他就可以随心所欲的调我们的收藏夹的位置了。 -5.我自己的配置 theme&shell Canta-light-compact icons 01-McMojave-circle 6.界面修改的参考链接 Ubuntu18.04美化主题(mac主题) Ubuntu18.04美化主题(完整版) GNOME-LOOK.ORG 30个非常不错的Ubuntu主题供你选择 ubuntu18....

                  December 4, 2020 · 1 min · zzsqwq

                  Linux和Vim入门

                  Linux系统常见命令 基本操作 **cd (Change Directory)**命令:跳转目录 +5.我自己的配置 theme&shell Canta-light-compact icons 01-McMojave-circle 6.界面修改的参考链接 Ubuntu18.04美化主题(mac主题) Ubuntu18.04美化主题(完整版) GNOME-LOOK.ORG 30个非常不错的Ubuntu主题供你选择 ubuntu18.04更换鼠标游标主题 配置终端 前言 唔,终端本来用起来感觉也还行,感觉终端就是linux的灵魂,啥都能干。 +...

                  December 4, 2020 · 1 min · zzsqwq

                  Linux和Vim入门

                  Linux系统常见命令 基本操作 **cd (Change Directory)**命令:跳转目录 cd path : path为路径,进入相应目录 cd # 或 cd ~ :回到主目录 cd - : 回到上次所在目录 cd !$ :将上个命令的参数做为输入 cd .. :回到上层目录 ...

                  March 30, 2020 · 2 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/linux/index.xml b/tags/linux/index.xml index 0596877c..3a072ecb 100644 --- a/tags/linux/index.xml +++ b/tags/linux/index.xml @@ -213,34 +213,34 @@ prompt pure <p><strong>tar</strong> 命令:压缩或解压命令。<code>tar [参数] 打包文件名 要打包的各个文件 </code> 。</p> <p>参数表:</p> <table> -<thead> -<tr> -<th>参数</th> -<th>含义</th> -</tr> -</thead> -<tbody> -<tr> -<td>-c</td> -<td>生成档案文件,创建打包文件</td> -</tr> -<tr> -<td>-v</td> -<td>列出归档解档的详细过程,显示进度</td> -</tr> -<tr> -<td>-f</td> -<td>指定档案文件名称,f后面一定是.tar文件,所以放选项最后</td> -</tr> -<tr> -<td>-t</td> -<td>列出档案中包含的文件</td> -</tr> -<tr> -<td>-x</td> -<td>解开档案文件</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">参数</th> + <th style="text-align: left">含义</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">-c</td> + <td style="text-align: left">生成档案文件,创建打包文件</td> + </tr> + <tr> + <td style="text-align: left">-v</td> + <td style="text-align: left">列出归档解档的详细过程,显示进度</td> + </tr> + <tr> + <td style="text-align: left">-f</td> + <td style="text-align: left">指定档案文件名称,f后面一定是.tar文件,所以放选项最后</td> + </tr> + <tr> + <td style="text-align: left">-t</td> + <td style="text-align: left">列出档案中包含的文件</td> + </tr> + <tr> + <td style="text-align: left">-x</td> + <td style="text-align: left">解开档案文件</td> + </tr> + </tbody> </table> <p>打包实例: <code>tar -cvf 文件名 要打包的文件</code> 解压实例:<code>tar -xvf 压缩包名</code></p> </li> diff --git a/tags/luogu/index.html b/tags/luogu/index.html index dd729b84..ec55958e 100644 --- a/tags/luogu/index.html +++ b/tags/luogu/index.html @@ -1,6 +1,6 @@ Luogu | Zs's Blog -

                  树形dp例题

                  前言 学OI的时候就做过树形dp的题,不过那时候全在划水。看了看题解还不太懂就直接照着题解写了,现在再回来看还是不会QAQ,所以就再看看然后自己写了一遍。 +

                  树形dp例题

                  前言 学OI的时候就做过树形dp的题,不过那时候全在划水。看了看题解还不太懂就直接照着题解写了,现在再回来看还是不会QAQ,所以就再看看然后自己写了一遍。 ...

                  February 20, 2020 · 2 min · zzsqwq

                  dp练习

                  A. 矩阵取数游戏 题意 给定一个 $n\times m$ 的矩阵,其中每个元素为非负整数。每次你可以从每行的行首或行末取一个元素,得到的分数为当前元素的值 $a_{ij}\times 2^k$ ,$k$ 为当前是第几次取该行上的元素。 问最大得分为多少。 ...

                  February 18, 2020 · 2 min · zzsqwq

                  dp习题练习

                  A. 方格取数 题意 有一个 $N*N$ 的整数方阵,每个点初始值为0,在一些点上放上数,一个人从左上角走到右下角,规定只能向下或向右走,当他经过的点上有数时会取走它,问走两遍最多能取的数的和最大为多少。 ...

                  February 12, 2020 · 2 min · zzsqwq

                  背包进阶

                  1. 分组背包 题意 在01背包基础上,将其中的物体分成 $k$ 组,每组内的物品相互冲突,即只能取其中一个,问最大价值。 @@ -9,5 +9,5 @@ ...

                  February 8, 2020 · 2 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/luogu/index.xml b/tags/luogu/index.xml index e1cd4761..4807b3c1 100644 --- a/tags/luogu/index.xml +++ b/tags/luogu/index.xml @@ -1116,58 +1116,58 @@ <li>碱基配对时相似度的定义如下</li> </ul> <table> -<thead> -<tr> -<th style="text-align:center"></th> -<th style="text-align:center">A</th> -<th style="text-align:center">C</th> -<th style="text-align:center">G</th> -<th style="text-align:center">T</th> -<th style="text-align:center">空</th> -</tr> -</thead> -<tbody> -<tr> -<td style="text-align:center">A</td> -<td style="text-align:center">5</td> -<td style="text-align:center">-1</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-1</td> -<td style="text-align:center">-3</td> -</tr> -<tr> -<td style="text-align:center">C</td> -<td style="text-align:center">-1</td> -<td style="text-align:center">5</td> -<td style="text-align:center">-3</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-4</td> -</tr> -<tr> -<td style="text-align:center">G</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-3</td> -<td style="text-align:center">5</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-2</td> -</tr> -<tr> -<td style="text-align:center">T</td> -<td style="text-align:center">-1</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">5</td> -<td style="text-align:center">-1</td> -</tr> -<tr> -<td style="text-align:center">空</td> -<td style="text-align:center">-3</td> -<td style="text-align:center">-4</td> -<td style="text-align:center">-2</td> -<td style="text-align:center">-1</td> -<td style="text-align:center">非法</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: center"></th> + <th style="text-align: center">A</th> + <th style="text-align: center">C</th> + <th style="text-align: center">G</th> + <th style="text-align: center">T</th> + <th style="text-align: center">空</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: center">A</td> + <td style="text-align: center">5</td> + <td style="text-align: center">-1</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-1</td> + <td style="text-align: center">-3</td> + </tr> + <tr> + <td style="text-align: center">C</td> + <td style="text-align: center">-1</td> + <td style="text-align: center">5</td> + <td style="text-align: center">-3</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-4</td> + </tr> + <tr> + <td style="text-align: center">G</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-3</td> + <td style="text-align: center">5</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-2</td> + </tr> + <tr> + <td style="text-align: center">T</td> + <td style="text-align: center">-1</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">5</td> + <td style="text-align: center">-1</td> + </tr> + <tr> + <td style="text-align: center">空</td> + <td style="text-align: center">-3</td> + <td style="text-align: center">-4</td> + <td style="text-align: center">-2</td> + <td style="text-align: center">-1</td> + <td style="text-align: center">非法</td> + </tr> + </tbody> </table> <hr> <h4 id="思路-2">思路</h4> diff --git a/tags/luogu/page/2/index.html b/tags/luogu/page/2/index.html index 209cdd24..a5244add 100644 --- a/tags/luogu/page/2/index.html +++ b/tags/luogu/page/2/index.html @@ -1,11 +1,11 @@ Luogu | Zs's Blog -

                  基础线性dp例题 #2

                  1. 石子归并 题意 $N$ 堆石子摆成一条线。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价。计算将 $N$ 堆石子合并成一堆的最小代价。 思路 很经典的区间dp例题,我们可以用 $dp[i][j]$ 来表示合并 $i\sim j$ 所需的最小代价,通过枚举中间的断点,来通过方程 $dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+cost[i][j])$ ,其中 $cost[i][j]$ 表示从 $i\sim j$ 的石子总数,通过前缀和很容易计算。在进行状态转移时需要前面状态已知,因为是枚举中间断点,所以断开区间的长度一定要小于原区间,因此在转移之前需要确保比他短的区间都已经达到了最小代价,因此我们可以通过枚举区间长度从 $2\sim N$ 来实现。 +

                  基础线性dp例题 #2

                  1. 石子归并 题意 $N$ 堆石子摆成一条线。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价。计算将 $N$ 堆石子合并成一堆的最小代价。 思路 很经典的区间dp例题,我们可以用 $dp[i][j]$ 来表示合并 $i\sim j$ 所需的最小代价,通过枚举中间的断点,来通过方程 $dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+cost[i][j])$ ,其中 $cost[i][j]$ 表示从 $i\sim j$ 的石子总数,通过前缀和很容易计算。在进行状态转移时需要前面状态已知,因为是枚举中间断点,所以断开区间的长度一定要小于原区间,因此在转移之前需要确保比他短的区间都已经达到了最小代价,因此我们可以通过枚举区间长度从 $2\sim N$ 来实现。 ...

                  February 7, 2020 · 2 min · zzsqwq

                  基础线性dp例题

                  前言 某位大佬曾经说过,dp不会没问题,想不到状态转移方程没问题,多做题就会了。所以,我打算多刷点dp题。那么,先从基础刷起吧。 1. P1091 合唱队形 题意 已知序列 $a$ 有 $n$ 个数,通过取出其中一些数可以使他满足严格的先增再减序列,问最少取出几个。 ...

                  February 6, 2020 · 1 min · zzsqwq

                  洛谷的一些搜索题

                  1. P1378 油滴扩展 题意 在长方形框中,最多有 n ($0\le{n}\le6$)个相异点,在框中点上依次放置可扩展的油滴,当碰到其他油滴边界或者长方形边框时会停止,扩展呈圆形展开。放置下一个时会确保上一个已经扩展完成。问通过变换放置顺序可使得最终框中剩下的面积最小为多少。 ...

                  February 4, 2020 · 2 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/macos/index.html b/tags/macos/index.html index 5abc9953..f5416f38 100644 --- a/tags/macos/index.html +++ b/tags/macos/index.html @@ -1,9 +1,10 @@ MacOS | Zs's Blog -

                  App 使用体会记录 - macOS 篇

                  平时很喜欢倒腾各种 Apple 平台的各种软件,所以体验了很多 iOS/iPadOS/macOS 上的软件,所以计划汇总一下自己的一些简短的使用体验和评价等,希望能在大家后续选择软件的时候起到一些参考和帮助。 +

                  App 使用体会记录 - macOS 篇

                  平时很喜欢倒腾各种 Apple 平台的各种软件,所以体验了很多 iOS/iPadOS/macOS 上的软件,所以计划汇总一下自己的一些简短的使用体验和评价等,希望能在大家后续选择软件的时候起到一些参考和帮助。 由于软件可能较多,不能一次性写完。同时,因为我也在不断体验新的软件,有新的感受,因此这篇博客应该是持续更新的,欢迎常来看看。 -速览表 App 名称 简短描述 功能限制 订阅形式 价格 购入时间 购入渠道 同类型产品 AIDente 电池电量管理 有免费使用功能,但有共功能需要收费 买断 Free Battery, BatFi AdGuard 广告拦截软件 AltTab 增强 macOS App 切换 Command-Tab Plus, Contexts,HyperSwitch, Bartender 5 Menubar 管理 Bob 大概是最好用翻译软件 EasyDict BuhoCleaner 垃圾清理器/软件卸载器 CleanMyMac, Sensei Clash X / Clash X Pro 代理 Surge, Stash CleanBuddy 键盘锁定清理 Cleaner CleanShot X 大概最好用的截图软件 Cleaner 键盘屏幕锁定清理 CleanBuddy Dash 文档利器 Dato Menubar 日历软件 Fantastical, Itsycal DevUtils 开发小工具合集 Downie 4 各类视频下载器 VDown HapiGo 启动器 Alfred, Raycast HazeOver 生产力工具,突出重点 Hazel 自动清理集合 JetBrains 全家桶 包含 Clion/IDEA 等 VSCode, Eclipse Lunar 显示器管理 MonitorControl, DisplayBuddy, Better Display Maccy 开源免费的剪切板管理工具 Paste, PasteNow, PastePal Manico 快速启动器 Command-Tab Plus MimeStram Gmail 客户端 MonitorControl 开源显示器管理,很够用 Lunar, DisplayBuddy, Better Display NetNewsWire 全平台 RSS 阅读器 Obsidian 笔记软件 Omnivore 稍后读软件 Pocket, MarkMark, Only Switch 一键完成各种任务 One Switch OpenImageOptim 图片压缩 TinyPNG OrbStack 容器管理,平替 Docker Desktop Docker Desktop, Podman, lima, colima Permute 3 图片/视频格式转换工具,类似于格式工厂 HandBrake, Omni Converter, Video Converter X2 Pixea 图片查看器 Viso, Picsee Pixelmator Pro 图片编辑器,80% 平替 PhotoShop Adobe PhotoShop, Darkroom, Photomator, Capture One, Adobe LightRoom Classic PopClip 划词增强 Proxyman 大概是舒服的抓包工具,略贵 Charles Rectangle 分屏软件 Magnet, Swish Swish 触控板手势增强 Stats Menubar 状态监控 iStats Menu, Sensei Subscriptions 订阅管理 Pandora on iOS Surge 代理工具 Clash X, Stash TinyPNG 图片压缩 OpenImageOptim Typora Markdown 文本编辑器 Obsidian Upscayl AI 图片超分 AI Photo Enhancer by Pictura, Pixelmator Pro Viso 6 图片查看器 Pixea, Xee Zotero 文献管理,就是界面一般 coconutBattery iPhone/iPad/Mac 电池信息查看 iRightMenu 右键增强 超级右键, iMouse, iTerm2 终端模拟器 Alacritty, Warp, Wezterm, Terminal 详细信息 AIDente 介绍:可以限制充电上限,据称电池电量维持在 70-80% 是比较健康的,不适宜过高。...

                  December 3, 2023 · 2 min · zzsqwq
                  © 2024 Zs's Blog +速览表 App 名称 简短描述 功能限制 订阅形式 价格 购入时间 购入渠道 同类型产品 AIDente 电池电量管理 有免费使用功能,但有共功能需要收费 买断 Free Battery, BatFi AdGuard 广告拦截软件 AltTab 增强 macOS App 切换 Command-Tab Plus, Contexts,HyperSwitch, Bartender 5 Menubar 管理 Bob 大概是最好用翻译软件 EasyDict BuhoCleaner 垃圾清理器/软件卸载器 CleanMyMac, Sensei Clash X / Clash X Pro 代理 Surge, Stash CleanBuddy 键盘锁定清理 Cleaner CleanShot X 大概最好用的截图软件 Cleaner 键盘屏幕锁定清理 CleanBuddy Dash 文档利器 Dato Menubar 日历软件 Fantastical, Itsycal DevUtils 开发小工具合集 Downie 4 各类视频下载器 VDown HapiGo 启动器 Alfred, Raycast HazeOver 生产力工具,突出重点 Hazel 自动清理集合 JetBrains 全家桶 包含 Clion/IDEA 等 VSCode, Eclipse Lunar 显示器管理 MonitorControl, DisplayBuddy, Better Display Maccy 开源免费的剪切板管理工具 Paste, PasteNow, PastePal Manico 快速启动器 Command-Tab Plus MimeStram Gmail 客户端 MonitorControl 开源显示器管理,很够用 Lunar, DisplayBuddy, Better Display NetNewsWire 全平台 RSS 阅读器 Obsidian 笔记软件 Omnivore 稍后读软件 Pocket, MarkMark, Only Switch 一键完成各种任务 One Switch OpenImageOptim 图片压缩 TinyPNG OrbStack 容器管理,平替 Docker Desktop Docker Desktop, Podman, lima, colima Permute 3 图片/视频格式转换工具,类似于格式工厂 HandBrake, Omni Converter, Video Converter X2 Pixea 图片查看器 Viso, Picsee Pixelmator Pro 图片编辑器,80% 平替 PhotoShop Adobe PhotoShop, Darkroom, Photomator, Capture One, Adobe LightRoom Classic PopClip 划词增强 Proxyman 大概是舒服的抓包工具,略贵 Charles Rectangle 分屏软件 Magnet, Swish Swish 触控板手势增强 Stats Menubar 状态监控 iStats Menu, Sensei Subscriptions 订阅管理 Pandora on iOS Surge 代理工具 Clash X, Stash TinyPNG 图片压缩 OpenImageOptim Typora Markdown 文本编辑器 Obsidian Upscayl AI 图片超分 AI Photo Enhancer by Pictura, Pixelmator Pro Viso 6 图片查看器 Pixea, Xee Zotero 文献管理,就是界面一般 coconutBattery iPhone/iPad/Mac 电池信息查看 iRightMenu 右键增强 超级右键, iMouse, iTerm2 终端模拟器 Alacritty, Warp, Wezterm, Terminal 详细信息 AIDente 介绍:可以限制充电上限,据称电池电量维持在 70-80% 是比较健康的,不适宜过高。 +...

                  December 3, 2023 · 2 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/macos/index.xml b/tags/macos/index.xml index 43c71cb5..4b45bb21 100644 --- a/tags/macos/index.xml +++ b/tags/macos/index.xml @@ -17,490 +17,490 @@ <p>由于软件可能较多,不能一次性写完。同时,因为我也在不断体验新的软件,有新的感受,因此这篇博客应该是持续更新的,欢迎常来看看。</p> <h2 id="速览表">速览表</h2> <table> -<thead> -<tr> -<th>App 名称</th> -<th>简短描述</th> -<th>功能限制</th> -<th>订阅形式</th> -<th>价格</th> -<th>购入时间</th> -<th>购入渠道</th> -<th>同类型产品</th> -</tr> -</thead> -<tbody> -<tr> -<td>AIDente</td> -<td>电池电量管理</td> -<td>有免费使用功能,但有共功能需要收费</td> -<td>买断</td> -<td>Free</td> -<td></td> -<td></td> -<td>Battery, BatFi</td> -</tr> -<tr> -<td>AdGuard</td> -<td>广告拦截软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>AltTab</td> -<td>增强 macOS App 切换</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Command-Tab Plus, Contexts,HyperSwitch,</td> -</tr> -<tr> -<td>Bartender 5</td> -<td>Menubar 管理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Bob</td> -<td>大概是最好用翻译软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>EasyDict</td> -</tr> -<tr> -<td>BuhoCleaner</td> -<td>垃圾清理器/软件卸载器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>CleanMyMac, Sensei</td> -</tr> -<tr> -<td>Clash X / Clash X Pro</td> -<td>代理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Surge, Stash</td> -</tr> -<tr> -<td>CleanBuddy</td> -<td>键盘锁定清理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Cleaner</td> -</tr> -<tr> -<td>CleanShot X</td> -<td>大概最好用的截图软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Cleaner</td> -<td>键盘屏幕锁定清理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>CleanBuddy</td> -</tr> -<tr> -<td>Dash</td> -<td>文档利器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Dato</td> -<td>Menubar 日历软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Fantastical, Itsycal</td> -</tr> -<tr> -<td>DevUtils</td> -<td>开发小工具合集</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Downie 4</td> -<td>各类视频下载器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>VDown</td> -</tr> -<tr> -<td>HapiGo</td> -<td>启动器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Alfred, Raycast</td> -</tr> -<tr> -<td>HazeOver</td> -<td>生产力工具,突出重点</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Hazel</td> -<td>自动清理集合</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>JetBrains 全家桶</td> -<td>包含 Clion/IDEA 等</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>VSCode, Eclipse</td> -</tr> -<tr> -<td>Lunar</td> -<td>显示器管理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>MonitorControl, DisplayBuddy, Better Display</td> -</tr> -<tr> -<td>Maccy</td> -<td>开源免费的剪切板管理工具</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Paste, PasteNow, PastePal</td> -</tr> -<tr> -<td>Manico</td> -<td>快速启动器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Command-Tab Plus</td> -</tr> -<tr> -<td>MimeStram</td> -<td>Gmail 客户端</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>MonitorControl</td> -<td>开源显示器管理,很够用</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Lunar, DisplayBuddy, Better Display</td> -</tr> -<tr> -<td>NetNewsWire</td> -<td>全平台 RSS 阅读器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Obsidian</td> -<td>笔记软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Omnivore</td> -<td>稍后读软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Pocket, MarkMark,</td> -</tr> -<tr> -<td>Only Switch</td> -<td>一键完成各种任务</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>One Switch</td> -</tr> -<tr> -<td>OpenImageOptim</td> -<td>图片压缩</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>TinyPNG</td> -</tr> -<tr> -<td>OrbStack</td> -<td>容器管理,平替 Docker Desktop</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Docker Desktop, Podman, lima, colima</td> -</tr> -<tr> -<td>Permute 3</td> -<td>图片/视频格式转换工具,类似于格式工厂</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>HandBrake, Omni Converter, Video Converter X2</td> -</tr> -<tr> -<td>Pixea</td> -<td>图片查看器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Viso, Picsee</td> -</tr> -<tr> -<td>Pixelmator Pro</td> -<td>图片编辑器,80% 平替 PhotoShop</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Adobe PhotoShop, Darkroom, Photomator, Capture One, Adobe LightRoom Classic</td> -</tr> -<tr> -<td>PopClip</td> -<td>划词增强</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Proxyman</td> -<td>大概是舒服的抓包工具,略贵</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Charles</td> -</tr> -<tr> -<td>Rectangle</td> -<td>分屏软件</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Magnet, Swish</td> -</tr> -<tr> -<td>Swish</td> -<td>触控板手势增强</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>Stats</td> -<td>Menubar 状态监控</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>iStats Menu, Sensei</td> -</tr> -<tr> -<td>Subscriptions</td> -<td>订阅管理</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Pandora on iOS</td> -</tr> -<tr> -<td>Surge</td> -<td>代理工具</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Clash X, Stash</td> -</tr> -<tr> -<td>TinyPNG</td> -<td>图片压缩</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>OpenImageOptim</td> -</tr> -<tr> -<td>Typora</td> -<td>Markdown 文本编辑器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Obsidian</td> -</tr> -<tr> -<td>Upscayl</td> -<td>AI 图片超分</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>AI Photo Enhancer by Pictura, Pixelmator Pro</td> -</tr> -<tr> -<td>Viso 6</td> -<td>图片查看器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Pixea, Xee</td> -</tr> -<tr> -<td>Zotero</td> -<td>文献管理,就是界面一般</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>coconutBattery</td> -<td>iPhone/iPad/Mac 电池信息查看</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -</tr> -<tr> -<td>iRightMenu</td> -<td>右键增强</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>超级右键, iMouse,</td> -</tr> -<tr> -<td>iTerm2</td> -<td>终端模拟器</td> -<td></td> -<td></td> -<td></td> -<td></td> -<td></td> -<td>Alacritty, Warp, Wezterm, Terminal</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">App 名称</th> + <th style="text-align: left">简短描述</th> + <th style="text-align: left">功能限制</th> + <th style="text-align: left">订阅形式</th> + <th style="text-align: left">价格</th> + <th style="text-align: left">购入时间</th> + <th style="text-align: left">购入渠道</th> + <th style="text-align: left">同类型产品</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">AIDente</td> + <td style="text-align: left">电池电量管理</td> + <td style="text-align: left">有免费使用功能,但有共功能需要收费</td> + <td style="text-align: left">买断</td> + <td style="text-align: left">Free</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Battery, BatFi</td> + </tr> + <tr> + <td style="text-align: left">AdGuard</td> + <td style="text-align: left">广告拦截软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">AltTab</td> + <td style="text-align: left">增强 macOS App 切换</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Command-Tab Plus, Contexts,HyperSwitch,</td> + </tr> + <tr> + <td style="text-align: left">Bartender 5</td> + <td style="text-align: left">Menubar 管理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Bob</td> + <td style="text-align: left">大概是最好用翻译软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">EasyDict</td> + </tr> + <tr> + <td style="text-align: left">BuhoCleaner</td> + <td style="text-align: left">垃圾清理器/软件卸载器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">CleanMyMac, Sensei</td> + </tr> + <tr> + <td style="text-align: left">Clash X / Clash X Pro</td> + <td style="text-align: left">代理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Surge, Stash</td> + </tr> + <tr> + <td style="text-align: left">CleanBuddy</td> + <td style="text-align: left">键盘锁定清理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Cleaner</td> + </tr> + <tr> + <td style="text-align: left">CleanShot X</td> + <td style="text-align: left">大概最好用的截图软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Cleaner</td> + <td style="text-align: left">键盘屏幕锁定清理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">CleanBuddy</td> + </tr> + <tr> + <td style="text-align: left">Dash</td> + <td style="text-align: left">文档利器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Dato</td> + <td style="text-align: left">Menubar 日历软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Fantastical, Itsycal</td> + </tr> + <tr> + <td style="text-align: left">DevUtils</td> + <td style="text-align: left">开发小工具合集</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Downie 4</td> + <td style="text-align: left">各类视频下载器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">VDown</td> + </tr> + <tr> + <td style="text-align: left">HapiGo</td> + <td style="text-align: left">启动器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Alfred, Raycast</td> + </tr> + <tr> + <td style="text-align: left">HazeOver</td> + <td style="text-align: left">生产力工具,突出重点</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Hazel</td> + <td style="text-align: left">自动清理集合</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">JetBrains 全家桶</td> + <td style="text-align: left">包含 Clion/IDEA 等</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">VSCode, Eclipse</td> + </tr> + <tr> + <td style="text-align: left">Lunar</td> + <td style="text-align: left">显示器管理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">MonitorControl, DisplayBuddy, Better Display</td> + </tr> + <tr> + <td style="text-align: left">Maccy</td> + <td style="text-align: left">开源免费的剪切板管理工具</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Paste, PasteNow, PastePal</td> + </tr> + <tr> + <td style="text-align: left">Manico</td> + <td style="text-align: left">快速启动器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Command-Tab Plus</td> + </tr> + <tr> + <td style="text-align: left">MimeStram</td> + <td style="text-align: left">Gmail 客户端</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">MonitorControl</td> + <td style="text-align: left">开源显示器管理,很够用</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Lunar, DisplayBuddy, Better Display</td> + </tr> + <tr> + <td style="text-align: left">NetNewsWire</td> + <td style="text-align: left">全平台 RSS 阅读器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Obsidian</td> + <td style="text-align: left">笔记软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Omnivore</td> + <td style="text-align: left">稍后读软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Pocket, MarkMark,</td> + </tr> + <tr> + <td style="text-align: left">Only Switch</td> + <td style="text-align: left">一键完成各种任务</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">One Switch</td> + </tr> + <tr> + <td style="text-align: left">OpenImageOptim</td> + <td style="text-align: left">图片压缩</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">TinyPNG</td> + </tr> + <tr> + <td style="text-align: left">OrbStack</td> + <td style="text-align: left">容器管理,平替 Docker Desktop</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Docker Desktop, Podman, lima, colima</td> + </tr> + <tr> + <td style="text-align: left">Permute 3</td> + <td style="text-align: left">图片/视频格式转换工具,类似于格式工厂</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">HandBrake, Omni Converter, Video Converter X2</td> + </tr> + <tr> + <td style="text-align: left">Pixea</td> + <td style="text-align: left">图片查看器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Viso, Picsee</td> + </tr> + <tr> + <td style="text-align: left">Pixelmator Pro</td> + <td style="text-align: left">图片编辑器,80% 平替 PhotoShop</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Adobe PhotoShop, Darkroom, Photomator, Capture One, Adobe LightRoom Classic</td> + </tr> + <tr> + <td style="text-align: left">PopClip</td> + <td style="text-align: left">划词增强</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Proxyman</td> + <td style="text-align: left">大概是舒服的抓包工具,略贵</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Charles</td> + </tr> + <tr> + <td style="text-align: left">Rectangle</td> + <td style="text-align: left">分屏软件</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Magnet, Swish</td> + </tr> + <tr> + <td style="text-align: left">Swish</td> + <td style="text-align: left">触控板手势增强</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">Stats</td> + <td style="text-align: left">Menubar 状态监控</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">iStats Menu, Sensei</td> + </tr> + <tr> + <td style="text-align: left">Subscriptions</td> + <td style="text-align: left">订阅管理</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Pandora on iOS</td> + </tr> + <tr> + <td style="text-align: left">Surge</td> + <td style="text-align: left">代理工具</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Clash X, Stash</td> + </tr> + <tr> + <td style="text-align: left">TinyPNG</td> + <td style="text-align: left">图片压缩</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">OpenImageOptim</td> + </tr> + <tr> + <td style="text-align: left">Typora</td> + <td style="text-align: left">Markdown 文本编辑器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Obsidian</td> + </tr> + <tr> + <td style="text-align: left">Upscayl</td> + <td style="text-align: left">AI 图片超分</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">AI Photo Enhancer by Pictura, Pixelmator Pro</td> + </tr> + <tr> + <td style="text-align: left">Viso 6</td> + <td style="text-align: left">图片查看器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Pixea, Xee</td> + </tr> + <tr> + <td style="text-align: left">Zotero</td> + <td style="text-align: left">文献管理,就是界面一般</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">coconutBattery</td> + <td style="text-align: left">iPhone/iPad/Mac 电池信息查看</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">iRightMenu</td> + <td style="text-align: left">右键增强</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">超级右键, iMouse,</td> + </tr> + <tr> + <td style="text-align: left">iTerm2</td> + <td style="text-align: left">终端模拟器</td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left"></td> + <td style="text-align: left">Alacritty, Warp, Wezterm, Terminal</td> + </tr> + </tbody> </table> <h2 id="详细信息">详细信息</h2> <h3 id="aidente">AIDente</h3> diff --git a/tags/markdown/index.html b/tags/markdown/index.html index 01c950d5..fe49f88b 100644 --- a/tags/markdown/index.html +++ b/tags/markdown/index.html @@ -1,6 +1,6 @@ Markdown | Zs's Blog -

                  Markdown 编辑器推荐

                  前言 近期著名 Markdown 编辑器 Typora 宣布收费了,起初感觉很难受,后来感慨之余也觉得算是合理,毕竟 Typora 用起来感觉是真的很良心,也在考虑是否买一份支持一下。 +

                  Markdown 编辑器推荐

                  前言 近期著名 Markdown 编辑器 Typora 宣布收费了,起初感觉很难受,后来感慨之余也觉得算是合理,毕竟 Typora 用起来感觉是真的很良心,也在考虑是否买一份支持一下。 已于2021/12/10购入,还是选择回归了 Typora 了哈哈哈 虽说左右分屏的设计可能更符合 Markdown 的初衷,但是像 Typora 这种所见即所得(WYSIWYG) 的书写体验确实是感觉习惯了就回不去了。 因此近期也搜集了 Markdown 编辑器作为 Typora 的替代品,在这里给大家分享一下。 @@ -15,8 +15,9 @@ 在我使用的一段时间内,他给我的感觉是,功能十分丰富的一个 Markdown 文件管理工具。如果你购买了他的同步服务,那你可以很轻松的在各平台同步你的 Markdown 文件夹,并且基于他强大的插件,可以很完成很多 Markdown 文件份外的事,例如待办清单、日历等等。 他虽没有所见即所得的模式,但是依靠其一款第三方插件,可以达成类似的效果,不过还是用起来不如 Typora 这种顺手。同时,它的各端同步如果不开启官方的服务,用起来还是挺麻烦的,经过我的一阵倒腾,我总结了如下几个方案: 使用第三方Git管理插件,可以定时推送文件夹中的内容到仓库,这样可以完成 linux 与 Windwos 平台的同步,只需要在某一方推送某一方拉取即可。而 Windows 平台与 iPad 平台的同步,可以借助 Apple 的 iCloud,Windows上有对应的客户端,这也是 Obsidian 官方支持的。不过在我使用的过程中我发现,这样异常的麻烦,使用 Git 来管理很可能会产生冲突,导致需要手动处理冲突,久而久之就会觉得很烦。 -使用自建云盘如 NextCloud + Obsidian,或者 Seafile + Obsidian。 这个是我觉得目前非常可行的一个方案,最近我也有在尝试 NextCloud,它的多端同步做的非常不错,依靠此可以在各个平台同步文件夹,加上 Obsidian 强悍的能力,是不错的组合!...

                  December 1, 2021 · 1 min · zzsqwq
                  © 2024 Zs's Blog +使用自建云盘如 NextCloud + Obsidian,或者 Seafile + Obsidian。 这个是我觉得目前非常可行的一个方案,最近我也有在尝试 NextCloud,它的多端同步做的非常不错,依靠此可以在各个平台同步文件夹,加上 Obsidian 强悍的能力,是不错的组合! +...

                  December 1, 2021 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/marktext/index.html b/tags/marktext/index.html index d9161232..6376b5ee 100644 --- a/tags/marktext/index.html +++ b/tags/marktext/index.html @@ -1,6 +1,6 @@ Marktext | Zs's Blog -

                  Markdown 编辑器推荐

                  前言 近期著名 Markdown 编辑器 Typora 宣布收费了,起初感觉很难受,后来感慨之余也觉得算是合理,毕竟 Typora 用起来感觉是真的很良心,也在考虑是否买一份支持一下。 +

                  Markdown 编辑器推荐

                  前言 近期著名 Markdown 编辑器 Typora 宣布收费了,起初感觉很难受,后来感慨之余也觉得算是合理,毕竟 Typora 用起来感觉是真的很良心,也在考虑是否买一份支持一下。 已于2021/12/10购入,还是选择回归了 Typora 了哈哈哈 虽说左右分屏的设计可能更符合 Markdown 的初衷,但是像 Typora 这种所见即所得(WYSIWYG) 的书写体验确实是感觉习惯了就回不去了。 因此近期也搜集了 Markdown 编辑器作为 Typora 的替代品,在这里给大家分享一下。 @@ -15,8 +15,9 @@ 在我使用的一段时间内,他给我的感觉是,功能十分丰富的一个 Markdown 文件管理工具。如果你购买了他的同步服务,那你可以很轻松的在各平台同步你的 Markdown 文件夹,并且基于他强大的插件,可以很完成很多 Markdown 文件份外的事,例如待办清单、日历等等。 他虽没有所见即所得的模式,但是依靠其一款第三方插件,可以达成类似的效果,不过还是用起来不如 Typora 这种顺手。同时,它的各端同步如果不开启官方的服务,用起来还是挺麻烦的,经过我的一阵倒腾,我总结了如下几个方案: 使用第三方Git管理插件,可以定时推送文件夹中的内容到仓库,这样可以完成 linux 与 Windwos 平台的同步,只需要在某一方推送某一方拉取即可。而 Windows 平台与 iPad 平台的同步,可以借助 Apple 的 iCloud,Windows上有对应的客户端,这也是 Obsidian 官方支持的。不过在我使用的过程中我发现,这样异常的麻烦,使用 Git 来管理很可能会产生冲突,导致需要手动处理冲突,久而久之就会觉得很烦。 -使用自建云盘如 NextCloud + Obsidian,或者 Seafile + Obsidian。 这个是我觉得目前非常可行的一个方案,最近我也有在尝试 NextCloud,它的多端同步做的非常不错,依靠此可以在各个平台同步文件夹,加上 Obsidian 强悍的能力,是不错的组合!...

                  December 1, 2021 · 1 min · zzsqwq
                  © 2024 Zs's Blog +使用自建云盘如 NextCloud + Obsidian,或者 Seafile + Obsidian。 这个是我觉得目前非常可行的一个方案,最近我也有在尝试 NextCloud,它的多端同步做的非常不错,依靠此可以在各个平台同步文件夹,加上 Obsidian 强悍的能力,是不错的组合! +...

                  December 1, 2021 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/matlab/index.html b/tags/matlab/index.html index 31b8fde5..cb767325 100644 --- a/tags/matlab/index.html +++ b/tags/matlab/index.html @@ -1,6 +1,6 @@ MATLAB | Zs's Blog -

                  专题四:MATLAB绘图

                  4.1 二维曲线 plot函数 基本用法:plot(x,y) ,x和y分别代表横纵坐标,plot函数会将各个点连接起来,形成线,x和y一般为长度相等的向量。 最简单的调用格式:plot(x) 当x为实向量时,则以该元素下表为横坐标,元素的值为纵坐标绘制曲线。 当x为复向量时,则以实部和虚部分别为横纵坐标绘制曲线。 ...

                  March 23, 2020 · 2 min · zzsqwq

                  专题三:MATLAB程序流程控制

                  3.1 顺序结构程序 程序设计的基本步骤 ...

                  March 18, 2020 · 2 min · zzsqwq

                  专题二:MATLAB矩阵处理

                  2.1 特殊矩阵 通用的特殊矩阵 zeros函数: 产生全0矩阵,即零矩阵。 +

                  专题四:MATLAB绘图

                  4.1 二维曲线 plot函数 基本用法:plot(x,y) ,x和y分别代表横纵坐标,plot函数会将各个点连接起来,形成线,x和y一般为长度相等的向量。 最简单的调用格式:plot(x) 当x为实向量时,则以该元素下表为横坐标,元素的值为纵坐标绘制曲线。 当x为复向量时,则以实部和虚部分别为横纵坐标绘制曲线。 ...

                  March 23, 2020 · 2 min · zzsqwq

                  专题三:MATLAB程序流程控制

                  3.1 顺序结构程序 程序设计的基本步骤 ...

                  March 18, 2020 · 2 min · zzsqwq

                  专题二:MATLAB矩阵处理

                  2.1 特殊矩阵 通用的特殊矩阵 zeros函数: 产生全0矩阵,即零矩阵。 ones函数: 产生全1函数,即幺矩阵。 eye函数: 产生对角线为1的矩阵,当矩阵为方针时,为单位矩阵。 rand函数: 产生 (0,1) 区间均匀分布的随机矩阵。 @@ -9,5 +9,5 @@ 通过 $\mu+\sigma x$ 来得到均值为 $\mu$ ,方差为 $\sigma{^2}$ 的随机数据。(高中数学知识,证明可百度) ...

                  March 15, 2020 · 2 min · zzsqwq

                  专题一:MATLAB基础知识

                  1.1 MATLAB系统环境 MATLAB操作界面的组成 MATLAB主窗口 命令行窗口 命令行窗口含有 >> 命令提示符,表示MATLAB处于准备状态,可以接受并执行命令,按下回车键后MATLAB会执行输入命令,并在后面显示执行结果 如果指令过长可以分行输入,在一行末尾写 ... 并按下回车键,在下个命令行继续输入,...称为续行符。 当前文件夹窗口 在MATLAB编程过程中生成的文件自动存放在当前文件夹,我们可以通过cd命令(例如我们要进入E盘下的work文件夹,可以cd e:\work)或者选择文件工具栏中的文件夹来设置当前文件夹。 工作区窗口 可用于变量的显示和操作,可显示你当前创建的变量。并且可对其保存,修改,删除。 ...

                  March 14, 2020 · 3 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/multithread/index.html b/tags/multithread/index.html index d040cb84..1b173043 100644 --- a/tags/multithread/index.html +++ b/tags/multithread/index.html @@ -1,11 +1,12 @@ Multithread | Zs's Blog -

                  为什么要使用条件变量?

                  为什么要使用条件变量? 前言 最近看了很多与线程有关的 C++ 新特性,条件变量是见的比较多的一个特性。 +

                  为什么要使用条件变量?

                  为什么要使用条件变量? 前言 最近看了很多与线程有关的 C++ 新特性,条件变量是见的比较多的一个特性。 看的时候我发现,想要理解一个新的特性,关键的要看它的引入到底解决了哪些问题,没有什么特性我们要实现相同的功能要怎么做? 以我的理解来看,条件变量是一个线程间互相同步与通知的手段,他通过主动唤醒的方式减小了各个线程的开销,取代了简单但是消耗较大的一直被动循环检验与等待。 没有条件变量我们如何实现相同的需求? 这里采用现代C++教程1 中关于条件变量的一个例子作为基础: -不使用条件变量版本 #include <queue> #include <chrono> #include <mutex> #include <thread> #include <iostream> #include <condition_variable> int main() { std::queue<int> produced_nums; std::mutex mtx; // 生产者 auto producer = [&]() { for (int i = 0; ; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(900)); std::unique_lock<std::mutex> lock(mtx); std::cout << "producing " << i << std::endl; produced_nums.push(i); } }; // 消费者 auto consumer = [&]() { while (true) { { std::unique_lock<std::mutex> lock(mtx); if(produced_nums....

                  August 24, 2022 · 2 min · zzsqwq
                  © 2024 Zs's Blog +不使用条件变量版本 #include <queue> #include <chrono> #include <mutex> #include <thread> #include <iostream> #include <condition_variable> int main() { std::queue<int> produced_nums; std::mutex mtx; // 生产者 auto producer = [&]() { for (int i = 0; ; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(900)); std::unique_lock<std::mutex> lock(mtx); std::cout << "producing " << i << std::endl; produced_nums.push(i); } }; // 消费者 auto consumer = [&]() { while (true) { { std::unique_lock<std::mutex> lock(mtx); if(produced_nums.empty()) continue; } std::unique_lock<std::mutex> lock(mtx); // 短暂取消锁,使得生产者有机会在消费者消费空前继续生产 lock.unlock(); // 消费者慢于生产者 std::this_thread::sleep_for(std::chrono::milliseconds(1000)); lock.lock(); while (!produced_nums.empty()) { std::cout << "consuming " << produced_nums.front() << std::endl; produced_nums.pop(); } } }; // 分别在不同的线程中运行 std::thread p(producer); std::thread cs[2]; for (int i = 0; i < 2; ++i) { cs[i] = std::thread(consumer); } p.join(); for (int i = 0; i < 2; ++i) { cs[i].join(); } return 0; } 使用条件变量版本 #include <queue> #include <chrono> #include <mutex> #include <thread> #include <iostream> #include <condition_variable> int main() { std::queue<int> produced_nums; std::mutex mtx; std::condition_variable cv; bool notified = false; // 通知信号 // 生产者 auto producer = [&]() { for (int i = 0; ; i++) { std::this_thread::sleep_for(std::chrono::milliseconds(900)); std::unique_lock<std::mutex> lock(mtx); std::cout << "producing " << i << std::endl; produced_nums.push(i); notified = true; cv.notify_all(); // 此处也可以使用 notify_one } }; // 消费者 auto consumer = [&]() { while (true) { std::unique_lock<std::mutex> lock(mtx); while (!notified) { // 避免虚假唤醒 cv.wait(lock); } // 短暂取消锁,使得生产者有机会在消费者消费空前继续生产 lock.unlock(); // 消费者慢于生产者 std::this_thread::sleep_for(std::chrono::milliseconds(1000)); lock.lock(); while (!produced_nums.empty()) { std::cout << "consuming " << produced_nums.front() << std::endl; produced_nums.pop(); } notified = false; } }; // 分别在不同的线程中运行 std::thread p(producer); std::thread cs[2]; for (int i = 0; i < 2; ++i) { cs[i] = std::thread(consumer); } p.join(); for (int i = 0; i < 2; ++i) { cs[i].join(); } return 0; } 这两段代码在效果上是等效的,都是一个生产者两个消费者。 +...

                  August 24, 2022 · 2 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/mysql/index.html b/tags/mysql/index.html index f2b72a97..712f229b 100644 --- a/tags/mysql/index.html +++ b/tags/mysql/index.html @@ -1,6 +1,6 @@ Mysql | Zs's Blog -

                  数据库的一些基础知识总结

                  了解SQL 一.什么是SQL SQL是结构化查询语言(Structured Query Language)的缩写。是一种专门用来与数据库通信的语言。 +

                  数据库的一些基础知识总结

                  了解SQL 一.什么是SQL SQL是结构化查询语言(Structured Query Language)的缩写。是一种专门用来与数据库通信的语言。 二.什么是数据库? 数据库(Database):保存有组织的数据的容器(通常是一个文件或一组文件)。 ​[scode type = “yellow”]需要注意的是,有时候我们把数据库软件也简称为数据库,但是数据库软件和数据库有本质区别,数据库软件应称为DBMS(数据库管理系统),我们通过数据库软件对数据库进行删减等操作,他代替你操作和访问数据库。[/scode] 三.数据库的组成 表 数据库中通常有多张表,这类似于一个清单。就好像我们管理两个班级就可以用两个表单。 @@ -37,5 +37,5 @@ 参考链接 数据库设计三大范式_dosthing 数据库设计三大范式_张龙豪 mysql必知必会

                  September 11, 2020 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/nowcoder/index.html b/tags/nowcoder/index.html index 843ba92f..0b5e18c5 100644 --- a/tags/nowcoder/index.html +++ b/tags/nowcoder/index.html @@ -1,10 +1,10 @@ Nowcoder | Zs's Blog -

                  排位三和四记录

                  Day 3 A. 黑妹的游戏Ⅰ 题意 给出三个不同的初始数字$a,b,c$,黑妹每次选择两个不同的数字,计算出差的绝对值后如果黑板上没有就写在黑板上。问黑妹最多能添加多少个数字。 +

                  排位三和四记录

                  Day 3 A. 黑妹的游戏Ⅰ 题意 给出三个不同的初始数字$a,b,c$,黑妹每次选择两个不同的数字,计算出差的绝对值后如果黑板上没有就写在黑板上。问黑妹最多能添加多少个数字。 ...

                  August 19, 2020 · 3 min · zzsqwq

                  排位一和二记录

                  Day 1 A. 兔子的区间密码 题意 给定一个区间$[L,R]$ ,求从这个区间任意取两个整数(可以相同),两者异或后能得到的最大值是多少? ...

                  August 17, 2020 · 3 min · zzsqwq

                  日常水题

                  前言 今天又是颓废的一天,被大佬拉去跟他一起做牛客网的题,QAQ…那我会点啥嘛,就只能替大佬写两道水题了··· ...

                  February 13, 2020 · 2 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/opencv/index.html b/tags/opencv/index.html index 4f30f35c..38bc0712 100644 --- a/tags/opencv/index.html +++ b/tags/opencv/index.html @@ -1,9 +1,9 @@ OpenCV | Zs's Blog -

                  Visual Studio 2019 中 OpenCV 配置教程

                  Windows 平台 Visual Studio 2019 中 OpenCV 配置教程 前言 我这里配置用的是4.5.0版本,但实际配置过程中需要的大部分时间只是路径,因此和版本基本无关。 +

                  Visual Studio 2019 中 OpenCV 配置教程

                  Windows 平台 Visual Studio 2019 中 OpenCV 配置教程 前言 我这里配置用的是4.5.0版本,但实际配置过程中需要的大部分时间只是路径,因此和版本基本无关。 只有一个地方是和版本有关系的,在配置链接器的 opencv_wordxyzd.lib 时,大家一定要注意!! ...

                  October 31, 2020 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/openwrt/index.html b/tags/openwrt/index.html index 25e0b965..039b53c9 100644 --- a/tags/openwrt/index.html +++ b/tags/openwrt/index.html @@ -1,14 +1,14 @@ OpenWrt | Zs's Blog -

                  使用 OrangePi 4 LTS 做旁路由

                  前言 最近同居的学长从香港带了个最新版的 Apple TV 回来,但是 Apple TV 在国内用不了,必须要代理才可以,所以考虑到了路由器代理的方案。但是现在家里在用的路由器是 Redmi AX3000,没法刷固件,也不想再买个 R2S 这种软路由了,因此就计划将公司之前用完的 香橙派(OrangePi) 4 LTS 利用一下。它的芯片是 RK3399,用来做路由器绰绰有余,不用可惜了。 +

                  使用 OrangePi 4 LTS 做旁路由

                  前言 最近同居的学长从香港带了个最新版的 Apple TV 回来,但是 Apple TV 在国内用不了,必须要代理才可以,所以考虑到了路由器代理的方案。但是现在家里在用的路由器是 Redmi AX3000,没法刷固件,也不想再买个 R2S 这种软路由了,因此就计划将公司之前用完的 香橙派(OrangePi) 4 LTS 利用一下。它的芯片是 RK3399,用来做路由器绰绰有余,不用可惜了。 为什么是旁路由? 不熟悉旁路由的同学可以看篇指南:从听说到上手,人人都能看懂的旁路由入门指南 找了一些常见的固件,貌似只有针对于 OrangePi R1 和 OrangePi R1 Plus 编译的软路由固件,并且讯龙官方也有放出针对这两个板子的 Openwrt 固件1,可以说是就是为软路由而生,价格也比较便宜,200 左右,性能和 R2S 差别不大。 试了一下在 4 LTS 上跑 R1 和 R1 Plus 的固件2,都无法正常点亮,可能可以自己编译一个对应架构的 OpenWrt,但是有点麻烦,还是没尝试。 考虑到 4 LTS 上可以使用 Docker,因此可以在上面用 Docker 跑一个 OpenWrt 然后做旁路由,到时候只需要把 Apple TV 或者路由器的网关和 DNS 改一下就可以,因此最终选择使用旁路由方案。 具体方案 这里直接参考了小苏的教程:https://mlapp.cn/376.html,写的很清晰,而且很好的考虑了没有基础的同学,赞一个! 里面写的很详细,但是需要注意的是,因为香橙派4 LTS是 ARMv8 架构的,但是直接拉教程里面的默认 latest 镜像是 ARMv7 的,因此需要指定一下镜像的版本,具体的镜像版本可以看 Docker Hub 中的介绍。 -docker pull registry....

                  December 31, 2022 · 1 min · zzsqwq
                  December 31, 2022 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/orangepi4-lts/index.html b/tags/orangepi4-lts/index.html index 64e3585c..11616c86 100644 --- a/tags/orangepi4-lts/index.html +++ b/tags/orangepi4-lts/index.html @@ -1,14 +1,14 @@ OrangePi4-Lts | Zs's Blog -

                  使用 OrangePi 4 LTS 做旁路由

                  前言 最近同居的学长从香港带了个最新版的 Apple TV 回来,但是 Apple TV 在国内用不了,必须要代理才可以,所以考虑到了路由器代理的方案。但是现在家里在用的路由器是 Redmi AX3000,没法刷固件,也不想再买个 R2S 这种软路由了,因此就计划将公司之前用完的 香橙派(OrangePi) 4 LTS 利用一下。它的芯片是 RK3399,用来做路由器绰绰有余,不用可惜了。 +

                  使用 OrangePi 4 LTS 做旁路由

                  前言 最近同居的学长从香港带了个最新版的 Apple TV 回来,但是 Apple TV 在国内用不了,必须要代理才可以,所以考虑到了路由器代理的方案。但是现在家里在用的路由器是 Redmi AX3000,没法刷固件,也不想再买个 R2S 这种软路由了,因此就计划将公司之前用完的 香橙派(OrangePi) 4 LTS 利用一下。它的芯片是 RK3399,用来做路由器绰绰有余,不用可惜了。 为什么是旁路由? 不熟悉旁路由的同学可以看篇指南:从听说到上手,人人都能看懂的旁路由入门指南 找了一些常见的固件,貌似只有针对于 OrangePi R1 和 OrangePi R1 Plus 编译的软路由固件,并且讯龙官方也有放出针对这两个板子的 Openwrt 固件1,可以说是就是为软路由而生,价格也比较便宜,200 左右,性能和 R2S 差别不大。 试了一下在 4 LTS 上跑 R1 和 R1 Plus 的固件2,都无法正常点亮,可能可以自己编译一个对应架构的 OpenWrt,但是有点麻烦,还是没尝试。 考虑到 4 LTS 上可以使用 Docker,因此可以在上面用 Docker 跑一个 OpenWrt 然后做旁路由,到时候只需要把 Apple TV 或者路由器的网关和 DNS 改一下就可以,因此最终选择使用旁路由方案。 具体方案 这里直接参考了小苏的教程:https://mlapp.cn/376.html,写的很清晰,而且很好的考虑了没有基础的同学,赞一个! 里面写的很详细,但是需要注意的是,因为香橙派4 LTS是 ARMv8 架构的,但是直接拉教程里面的默认 latest 镜像是 ARMv7 的,因此需要指定一下镜像的版本,具体的镜像版本可以看 Docker Hub 中的介绍。 -docker pull registry....

                  December 31, 2022 · 1 min · zzsqwq
                  December 31, 2022 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/pip/index.html b/tags/pip/index.html index 292538df..c758b657 100644 --- a/tags/pip/index.html +++ b/tags/pip/index.html @@ -1,6 +1,6 @@ Pip | Zs's Blog -

                  关于Anaconda中pip路径指向问题

                  前言 最近使用Anaconda的时候遇到了一个很奇怪的问题,如当我新建环境 condatest 后,使用 pip -V 查看pip的路径指向,会发现pip指向的是另一个环境 CenterNet 的路径。搜索了很久得到一个有一些用的解决方法 +

                  关于Anaconda中pip路径指向问题

                  前言 最近使用Anaconda的时候遇到了一个很奇怪的问题,如当我新建环境 condatest 后,使用 pip -V 查看pip的路径指向,会发现pip指向的是另一个环境 CenterNet 的路径。搜索了很久得到一个有一些用的解决方法 解决方案 设有问题的环境为 condatest ,python版本为 3.6 然后进入 ~/anaconda3/envs/condatest/lib/python3.6 编辑目录下的 site.py 文件,将其中的 USER_SITE 的值修改为 /home/zs/anaconda3/envs/condatest ,注意这里路径里面的 zs 是你的当前用户名, USER_BASE 的值修改为 /home/zs/anaconda3/envs/condatest/lib/python3.6/site.py,然后问题应该就解决了。 @@ -8,5 +8,5 @@ 参考链接 更改conda环境中的pip包安装的默认路径

                  March 6, 2021 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/python/index.html b/tags/python/index.html index c5bf2560..65fb0381 100644 --- a/tags/python/index.html +++ b/tags/python/index.html @@ -1,6 +1,6 @@ Python | Zs's Blog -

                  利用神经网络进行波士顿房价预测

                  前言 前一阵学校有五一数模节校赛,和朋友一起参加做B题,波士顿房价预测,算是第一次自己动手实现一个简单的小网络吧,虽然很简单,但还是想记录一下。 +

                  利用神经网络进行波士顿房价预测

                  前言 前一阵学校有五一数模节校赛,和朋友一起参加做B题,波士顿房价预测,算是第一次自己动手实现一个简单的小网络吧,虽然很简单,但还是想记录一下。 题目介绍 波士顿住房数据由哈里森和鲁宾菲尔德于1978年Harrison and Rubinfeld1收集。它包括了波士顿大区每个调查行政区的506个观察值。1980年Belsley et al.2曾对此数据做过分析。 数据一共14列,每一列的含义分别如下: 英文简称 详细含义 CRIM 城镇的人均犯罪率 ZN 大于25,000平方英尺的地块的住宅用地比例。 INDUS 每个镇的非零售业务英亩的比例。 CHAS 查尔斯河虚拟变量(如果环河,则等于1;否则等于0) NOX 一氧化氮的浓度(百万分之几) RM 每个住宅的平均房间数 AGE 1940年之前建造的自有住房的比例 DIS 到五个波士顿就业中心的加权距离 RAD 径向公路通达性的指标 TAX 每一万美元的全值财产税率 PTRATIO 各镇的师生比率 B 计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例 LSTAT 底层人口的百分比(%) price 自有住房数的中位数,单位(千美元) 基于上述数据,请完成以下问题: @@ -10,7 +10,8 @@ 建立前馈神经网络模型,根据通用逼近定理,我们可以拟合此回归模型。 我们对上述模型来进行实现并确定评估标准来对他们进行比较,选择最优的模型作为预测模型。 算法流程 传统的回归算法 自变量的选择 首先,考虑到数据集中13列自变量其中某一些可能和最终的房价并无强相关性,如果全部使用进行预测可能会对模型引入噪声,因此我们首先计算了房价price与各个自变量之间的相关系数 $r$ ,其中 $r$ 计算公式如下: $$ r = \frac{\sum(x_i-\bar{x})(y_i-\bar{y})}{\sqrt{\sum(x_i-\bar{x})^2\sum(y_i-\bar{y})^2}} $$ 其中 $x_i,y_i$ 为数据的每个分量,$\bar{x},\bar{y}$ 为数据的均值 -该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下:...

                  May 16, 2021 · 1 min · zzsqwq

                  关于Anaconda中pip路径指向问题

                  前言 最近使用Anaconda的时候遇到了一个很奇怪的问题,如当我新建环境 condatest 后,使用 pip -V 查看pip的路径指向,会发现pip指向的是另一个环境 CenterNet 的路径。搜索了很久得到一个有一些用的解决方法 +该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下: +...

                  May 16, 2021 · 1 min · zzsqwq

                  关于Anaconda中pip路径指向问题

                  前言 最近使用Anaconda的时候遇到了一个很奇怪的问题,如当我新建环境 condatest 后,使用 pip -V 查看pip的路径指向,会发现pip指向的是另一个环境 CenterNet 的路径。搜索了很久得到一个有一些用的解决方法 解决方案 设有问题的环境为 condatest ,python版本为 3.6 然后进入 ~/anaconda3/envs/condatest/lib/python3.6 编辑目录下的 site.py 文件,将其中的 USER_SITE 的值修改为 /home/zs/anaconda3/envs/condatest ,注意这里路径里面的 zs 是你的当前用户名, USER_BASE 的值修改为 /home/zs/anaconda3/envs/condatest/lib/python3.6/site.py,然后问题应该就解决了。 @@ -24,5 +25,5 @@ ...

                  April 18, 2020 · 6 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/python/index.xml b/tags/python/index.xml index 84bcdba8..6b6298cb 100644 --- a/tags/python/index.xml +++ b/tags/python/index.xml @@ -19,70 +19,70 @@ <p>波士顿住房数据由哈里森和鲁宾菲尔德于1978年Harrison and Rubinfeld<sup><a href="https://blog.zzsqwq.cn/usr/uploads/2021/05/406125417.png">1</a></sup>收集。它包括了波士顿大区每个调查行政区的506个观察值。1980年Belsley et al.<sup><a href="https://blog.zzsqwq.cn/usr/uploads/2021/05/3238192089.png">2</a></sup>曾对此数据做过分析。</p> <p>数据一共14列,每一列的含义分别如下:</p> <table> -<thead> -<tr> -<th>英文简称</th> -<th>详细含义</th> -</tr> -</thead> -<tbody> -<tr> -<td>CRIM</td> -<td>城镇的人均犯罪率</td> -</tr> -<tr> -<td>ZN</td> -<td>大于25,000平方英尺的地块的住宅用地比例。</td> -</tr> -<tr> -<td>INDUS</td> -<td>每个镇的非零售业务英亩的比例。</td> -</tr> -<tr> -<td>CHAS</td> -<td>查尔斯河虚拟变量(如果环河,则等于1;否则等于0)</td> -</tr> -<tr> -<td>NOX</td> -<td>一氧化氮的浓度(百万分之几)</td> -</tr> -<tr> -<td>RM</td> -<td>每个住宅的平均房间数</td> -</tr> -<tr> -<td>AGE</td> -<td>1940年之前建造的自有住房的比例</td> -</tr> -<tr> -<td>DIS</td> -<td>到五个波士顿就业中心的加权距离</td> -</tr> -<tr> -<td>RAD</td> -<td>径向公路通达性的指标</td> -</tr> -<tr> -<td>TAX</td> -<td>每一万美元的全值财产税率</td> -</tr> -<tr> -<td>PTRATIO</td> -<td>各镇的师生比率</td> -</tr> -<tr> -<td>B</td> -<td>计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例</td> -</tr> -<tr> -<td>LSTAT</td> -<td>底层人口的百分比(%)</td> -</tr> -<tr> -<td><strong>price</strong></td> -<td>自有住房数的中位数,单位(千美元)</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">英文简称</th> + <th style="text-align: left">详细含义</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">CRIM</td> + <td style="text-align: left">城镇的人均犯罪率</td> + </tr> + <tr> + <td style="text-align: left">ZN</td> + <td style="text-align: left">大于25,000平方英尺的地块的住宅用地比例。</td> + </tr> + <tr> + <td style="text-align: left">INDUS</td> + <td style="text-align: left">每个镇的非零售业务英亩的比例。</td> + </tr> + <tr> + <td style="text-align: left">CHAS</td> + <td style="text-align: left">查尔斯河虚拟变量(如果环河,则等于1;否则等于0)</td> + </tr> + <tr> + <td style="text-align: left">NOX</td> + <td style="text-align: left">一氧化氮的浓度(百万分之几)</td> + </tr> + <tr> + <td style="text-align: left">RM</td> + <td style="text-align: left">每个住宅的平均房间数</td> + </tr> + <tr> + <td style="text-align: left">AGE</td> + <td style="text-align: left">1940年之前建造的自有住房的比例</td> + </tr> + <tr> + <td style="text-align: left">DIS</td> + <td style="text-align: left">到五个波士顿就业中心的加权距离</td> + </tr> + <tr> + <td style="text-align: left">RAD</td> + <td style="text-align: left">径向公路通达性的指标</td> + </tr> + <tr> + <td style="text-align: left">TAX</td> + <td style="text-align: left">每一万美元的全值财产税率</td> + </tr> + <tr> + <td style="text-align: left">PTRATIO</td> + <td style="text-align: left">各镇的师生比率</td> + </tr> + <tr> + <td style="text-align: left">B</td> + <td style="text-align: left">计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例</td> + </tr> + <tr> + <td style="text-align: left">LSTAT</td> + <td style="text-align: left">底层人口的百分比(%)</td> + </tr> + <tr> + <td style="text-align: left"><strong>price</strong></td> + <td style="text-align: left">自有住房数的中位数,单位(千美元)</td> + </tr> + </tbody> </table> <p>基于上述数据,请完成以下问题:</p> <p><strong>建立波士顿房价预测模型并对预测结果进行评价。</strong></p> @@ -107,46 +107,46 @@ $$ 其中 $x_i,y_i$ 为数据的每个分量,$\bar{x},\bar{y}$ 为数据的均值</p> <p>该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下:</p> <table> -<thead> -<tr> -<th>CRIM</th> -<th>ZN</th> -<th>INDUS</th> -<th>CHAS</th> -<th>NOX</th> -<th>RM</th> -<th>LSTAT</th> -</tr> -</thead> -<tbody> -<tr> -<td>-0.385832</td> -<td>0.360445</td> -<td>-0.483725</td> -<td>0.175260</td> -<td>-0.427321</td> -<td>0.695360</td> -<td>-0.737663</td> -</tr> -<tr> -<td><strong>AGE</strong></td> -<td><strong>DIS</strong></td> -<td><strong>RAD</strong></td> -<td><strong>TAX</strong></td> -<td><strong>PTRATIO</strong></td> -<td><strong>B</strong></td> -<td></td> -</tr> -<tr> -<td>-0.376955</td> -<td>0.249929</td> -<td>-0.381626</td> -<td>-0.468536</td> -<td>-0.507787</td> -<td>0.333461</td> -<td></td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">CRIM</th> + <th style="text-align: left">ZN</th> + <th style="text-align: left">INDUS</th> + <th style="text-align: left">CHAS</th> + <th style="text-align: left">NOX</th> + <th style="text-align: left">RM</th> + <th style="text-align: left">LSTAT</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">-0.385832</td> + <td style="text-align: left">0.360445</td> + <td style="text-align: left">-0.483725</td> + <td style="text-align: left">0.175260</td> + <td style="text-align: left">-0.427321</td> + <td style="text-align: left">0.695360</td> + <td style="text-align: left">-0.737663</td> + </tr> + <tr> + <td style="text-align: left"><strong>AGE</strong></td> + <td style="text-align: left"><strong>DIS</strong></td> + <td style="text-align: left"><strong>RAD</strong></td> + <td style="text-align: left"><strong>TAX</strong></td> + <td style="text-align: left"><strong>PTRATIO</strong></td> + <td style="text-align: left"><strong>B</strong></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">-0.376955</td> + <td style="text-align: left">0.249929</td> + <td style="text-align: left">-0.381626</td> + <td style="text-align: left">-0.468536</td> + <td style="text-align: left">-0.507787</td> + <td style="text-align: left">0.333461</td> + <td style="text-align: left"></td> + </tr> + </tbody> </table> <p>观察结果可以发现,在给定的十三个变量中,<strong>LSTAT <strong>与 <strong>price</strong> 的相关程度最高$(|r|&gt;0.7)$,其次是 <strong>RM</strong> 与</strong>PTRATIO</strong> $(|r|&gt;0.5)$,再者是 <strong>TAX,INDUS,NOX</strong> $(|r|&gt;0.4)$,除上述之外的七个变量都与 <strong>price</strong> 无较强的相关性,因此我们考虑使用六个相关性较强变量和十三个变量分别来对房价进行预测,并对他们进行对比,来寻找最优的回归模型。</p> <h5 id="模型的构建">模型的构建</h5> diff --git a/tags/pytorch/index.html b/tags/pytorch/index.html index b184e963..ae8d94fe 100644 --- a/tags/pytorch/index.html +++ b/tags/pytorch/index.html @@ -1,6 +1,6 @@ Pytorch | Zs's Blog -

                  利用神经网络进行波士顿房价预测

                  前言 前一阵学校有五一数模节校赛,和朋友一起参加做B题,波士顿房价预测,算是第一次自己动手实现一个简单的小网络吧,虽然很简单,但还是想记录一下。 +

                  利用神经网络进行波士顿房价预测

                  前言 前一阵学校有五一数模节校赛,和朋友一起参加做B题,波士顿房价预测,算是第一次自己动手实现一个简单的小网络吧,虽然很简单,但还是想记录一下。 题目介绍 波士顿住房数据由哈里森和鲁宾菲尔德于1978年Harrison and Rubinfeld1收集。它包括了波士顿大区每个调查行政区的506个观察值。1980年Belsley et al.2曾对此数据做过分析。 数据一共14列,每一列的含义分别如下: 英文简称 详细含义 CRIM 城镇的人均犯罪率 ZN 大于25,000平方英尺的地块的住宅用地比例。 INDUS 每个镇的非零售业务英亩的比例。 CHAS 查尔斯河虚拟变量(如果环河,则等于1;否则等于0) NOX 一氧化氮的浓度(百万分之几) RM 每个住宅的平均房间数 AGE 1940年之前建造的自有住房的比例 DIS 到五个波士顿就业中心的加权距离 RAD 径向公路通达性的指标 TAX 每一万美元的全值财产税率 PTRATIO 各镇的师生比率 B 计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例 LSTAT 底层人口的百分比(%) price 自有住房数的中位数,单位(千美元) 基于上述数据,请完成以下问题: @@ -10,8 +10,9 @@ 建立前馈神经网络模型,根据通用逼近定理,我们可以拟合此回归模型。 我们对上述模型来进行实现并确定评估标准来对他们进行比较,选择最优的模型作为预测模型。 算法流程 传统的回归算法 自变量的选择 首先,考虑到数据集中13列自变量其中某一些可能和最终的房价并无强相关性,如果全部使用进行预测可能会对模型引入噪声,因此我们首先计算了房价price与各个自变量之间的相关系数 $r$ ,其中 $r$ 计算公式如下: $$ r = \frac{\sum(x_i-\bar{x})(y_i-\bar{y})}{\sqrt{\sum(x_i-\bar{x})^2\sum(y_i-\bar{y})^2}} $$ 其中 $x_i,y_i$ 为数据的每个分量,$\bar{x},\bar{y}$ 为数据的均值 -该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下:...

                  May 16, 2021 · 1 min · zzsqwq
                  © 2024 Zs's Blog +该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下: +...

                  May 16, 2021 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/pytorch/index.xml b/tags/pytorch/index.xml index ede06781..5388c596 100644 --- a/tags/pytorch/index.xml +++ b/tags/pytorch/index.xml @@ -19,70 +19,70 @@ <p>波士顿住房数据由哈里森和鲁宾菲尔德于1978年Harrison and Rubinfeld<sup><a href="https://blog.zzsqwq.cn/usr/uploads/2021/05/406125417.png">1</a></sup>收集。它包括了波士顿大区每个调查行政区的506个观察值。1980年Belsley et al.<sup><a href="https://blog.zzsqwq.cn/usr/uploads/2021/05/3238192089.png">2</a></sup>曾对此数据做过分析。</p> <p>数据一共14列,每一列的含义分别如下:</p> <table> -<thead> -<tr> -<th>英文简称</th> -<th>详细含义</th> -</tr> -</thead> -<tbody> -<tr> -<td>CRIM</td> -<td>城镇的人均犯罪率</td> -</tr> -<tr> -<td>ZN</td> -<td>大于25,000平方英尺的地块的住宅用地比例。</td> -</tr> -<tr> -<td>INDUS</td> -<td>每个镇的非零售业务英亩的比例。</td> -</tr> -<tr> -<td>CHAS</td> -<td>查尔斯河虚拟变量(如果环河,则等于1;否则等于0)</td> -</tr> -<tr> -<td>NOX</td> -<td>一氧化氮的浓度(百万分之几)</td> -</tr> -<tr> -<td>RM</td> -<td>每个住宅的平均房间数</td> -</tr> -<tr> -<td>AGE</td> -<td>1940年之前建造的自有住房的比例</td> -</tr> -<tr> -<td>DIS</td> -<td>到五个波士顿就业中心的加权距离</td> -</tr> -<tr> -<td>RAD</td> -<td>径向公路通达性的指标</td> -</tr> -<tr> -<td>TAX</td> -<td>每一万美元的全值财产税率</td> -</tr> -<tr> -<td>PTRATIO</td> -<td>各镇的师生比率</td> -</tr> -<tr> -<td>B</td> -<td>计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例</td> -</tr> -<tr> -<td>LSTAT</td> -<td>底层人口的百分比(%)</td> -</tr> -<tr> -<td><strong>price</strong></td> -<td>自有住房数的中位数,单位(千美元)</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">英文简称</th> + <th style="text-align: left">详细含义</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">CRIM</td> + <td style="text-align: left">城镇的人均犯罪率</td> + </tr> + <tr> + <td style="text-align: left">ZN</td> + <td style="text-align: left">大于25,000平方英尺的地块的住宅用地比例。</td> + </tr> + <tr> + <td style="text-align: left">INDUS</td> + <td style="text-align: left">每个镇的非零售业务英亩的比例。</td> + </tr> + <tr> + <td style="text-align: left">CHAS</td> + <td style="text-align: left">查尔斯河虚拟变量(如果环河,则等于1;否则等于0)</td> + </tr> + <tr> + <td style="text-align: left">NOX</td> + <td style="text-align: left">一氧化氮的浓度(百万分之几)</td> + </tr> + <tr> + <td style="text-align: left">RM</td> + <td style="text-align: left">每个住宅的平均房间数</td> + </tr> + <tr> + <td style="text-align: left">AGE</td> + <td style="text-align: left">1940年之前建造的自有住房的比例</td> + </tr> + <tr> + <td style="text-align: left">DIS</td> + <td style="text-align: left">到五个波士顿就业中心的加权距离</td> + </tr> + <tr> + <td style="text-align: left">RAD</td> + <td style="text-align: left">径向公路通达性的指标</td> + </tr> + <tr> + <td style="text-align: left">TAX</td> + <td style="text-align: left">每一万美元的全值财产税率</td> + </tr> + <tr> + <td style="text-align: left">PTRATIO</td> + <td style="text-align: left">各镇的师生比率</td> + </tr> + <tr> + <td style="text-align: left">B</td> + <td style="text-align: left">计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例</td> + </tr> + <tr> + <td style="text-align: left">LSTAT</td> + <td style="text-align: left">底层人口的百分比(%)</td> + </tr> + <tr> + <td style="text-align: left"><strong>price</strong></td> + <td style="text-align: left">自有住房数的中位数,单位(千美元)</td> + </tr> + </tbody> </table> <p>基于上述数据,请完成以下问题:</p> <p><strong>建立波士顿房价预测模型并对预测结果进行评价。</strong></p> @@ -107,46 +107,46 @@ $$ 其中 $x_i,y_i$ 为数据的每个分量,$\bar{x},\bar{y}$ 为数据的均值</p> <p>该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下:</p> <table> -<thead> -<tr> -<th>CRIM</th> -<th>ZN</th> -<th>INDUS</th> -<th>CHAS</th> -<th>NOX</th> -<th>RM</th> -<th>LSTAT</th> -</tr> -</thead> -<tbody> -<tr> -<td>-0.385832</td> -<td>0.360445</td> -<td>-0.483725</td> -<td>0.175260</td> -<td>-0.427321</td> -<td>0.695360</td> -<td>-0.737663</td> -</tr> -<tr> -<td><strong>AGE</strong></td> -<td><strong>DIS</strong></td> -<td><strong>RAD</strong></td> -<td><strong>TAX</strong></td> -<td><strong>PTRATIO</strong></td> -<td><strong>B</strong></td> -<td></td> -</tr> -<tr> -<td>-0.376955</td> -<td>0.249929</td> -<td>-0.381626</td> -<td>-0.468536</td> -<td>-0.507787</td> -<td>0.333461</td> -<td></td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">CRIM</th> + <th style="text-align: left">ZN</th> + <th style="text-align: left">INDUS</th> + <th style="text-align: left">CHAS</th> + <th style="text-align: left">NOX</th> + <th style="text-align: left">RM</th> + <th style="text-align: left">LSTAT</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">-0.385832</td> + <td style="text-align: left">0.360445</td> + <td style="text-align: left">-0.483725</td> + <td style="text-align: left">0.175260</td> + <td style="text-align: left">-0.427321</td> + <td style="text-align: left">0.695360</td> + <td style="text-align: left">-0.737663</td> + </tr> + <tr> + <td style="text-align: left"><strong>AGE</strong></td> + <td style="text-align: left"><strong>DIS</strong></td> + <td style="text-align: left"><strong>RAD</strong></td> + <td style="text-align: left"><strong>TAX</strong></td> + <td style="text-align: left"><strong>PTRATIO</strong></td> + <td style="text-align: left"><strong>B</strong></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">-0.376955</td> + <td style="text-align: left">0.249929</td> + <td style="text-align: left">-0.381626</td> + <td style="text-align: left">-0.468536</td> + <td style="text-align: left">-0.507787</td> + <td style="text-align: left">0.333461</td> + <td style="text-align: left"></td> + </tr> + </tbody> </table> <p>观察结果可以发现,在给定的十三个变量中,<strong>LSTAT <strong>与 <strong>price</strong> 的相关程度最高$(|r|&gt;0.7)$,其次是 <strong>RM</strong> 与</strong>PTRATIO</strong> $(|r|&gt;0.5)$,再者是 <strong>TAX,INDUS,NOX</strong> $(|r|&gt;0.4)$,除上述之外的七个变量都与 <strong>price</strong> 无较强的相关性,因此我们考虑使用六个相关性较强变量和十三个变量分别来对房价进行预测,并对他们进行对比,来寻找最优的回归模型。</p> <h5 id="模型的构建">模型的构建</h5> diff --git a/tags/qq/index.html b/tags/qq/index.html index 3c274146..8c18a73a 100644 --- a/tags/qq/index.html +++ b/tags/qq/index.html @@ -1,13 +1,14 @@ QQ | Zs's Blog -

                  deepin-wine-qq-9.1.8版本无法正常启动的解决方案

                  问题描述 ​Ubuntu下想要使用QQ有一个比较好的解决方案就是deepin-wine的版本,deepin-wine版本的QQ一共有两个版本,分别是 8.9.1 和 9.1.8 ,前者安装后发现无法登陆,登录时会提示版本过低的问题,于是我换到9.1.8版本后,启动初始化后就无任何信息了,于是开始排查问题 +

                  deepin-wine-qq-9.1.8版本无法正常启动的解决方案

                  问题描述 ​Ubuntu下想要使用QQ有一个比较好的解决方案就是deepin-wine的版本,deepin-wine版本的QQ一共有两个版本,分别是 8.9.1 和 9.1.8 ,前者安装后发现无法登陆,登录时会提示版本过低的问题,于是我换到9.1.8版本后,启动初始化后就无任何信息了,于是开始排查问题 解决方案 ​首先我们根据上文的启示,因为每一个应用程序对应了一个 xxx.desktop 文件,因此在应用库中的QQ一定也有一个对应的 desktop 文件 ​我们进入到 /usr/share/applications ,运行 $ ls | grep -i qq ​可以发现其中有一个名为 deepin.com.qq.im.desktop 的文件,我们打开后发现内容如下: #!/usr/bin/env xdg-open [Desktop Entry] Encoding=UTF-8 Type=Application X-Created-By=Deepin WINE Team Categories=chat; Icon=deepin.com.qq.im Exec="/opt/deepinwine/apps/Deepin-QQ/run.sh" -u %u Name=QQ Name[zh_CN]=QQ Comment=Tencent QQ Client on Deepin Wine StartupWMClass=QQ.exe MimeType= ​可以看到Exec那一栏为 Exec="/opt/deepinwine/apps/Deepin-QQ/run.sh" -u %u ,发现他是运行目录下的一个 run.sh 脚本来启动的。 ​我们进入目录下直接运行该脚本,查看log信息: -base ❯ ./run.sh Run Deepin-QQ 9.1.8deepin0 c:/Program Files/Tencent/QQ/Bin/QQ.exe run Deepin-QQ progress pid Gtk-Message: 01:16:58.069: GtkDialog mapped without a transient parent....

                  June 16, 2021 · 4 min · zzsqwq
                  © 2024 Zs's Blog +base ❯ ./run.sh Run Deepin-QQ 9.1.8deepin0 c:/Program Files/Tencent/QQ/Bin/QQ.exe run Deepin-QQ progress pid Gtk-Message: 01:16:58.069: GtkDialog mapped without a transient parent. This is discouraged. total 0 lrwxrwxrwx 1 zs zs 10 6月 16 01:16 c: -> ../drive_c lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com1 -> /dev/ttyS0 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com10 -> /dev/ttyS9 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com11 -> /dev/ttyS10 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com12 -> /dev/ttyS11 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com13 -> /dev/ttyS12 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com14 -> /dev/ttyS13 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com15 -> /dev/ttyS14 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com16 -> /dev/ttyS15 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com17 -> /dev/ttyS16 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com18 -> /dev/ttyS17 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com19 -> /dev/ttyS18 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com2 -> /dev/ttyS1 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com20 -> /dev/ttyS19 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com21 -> /dev/ttyS20 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com22 -> /dev/ttyS21 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com23 -> /dev/ttyS22 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com24 -> /dev/ttyS23 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com25 -> /dev/ttyS24 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com26 -> /dev/ttyS25 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com27 -> /dev/ttyS26 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com28 -> /dev/ttyS27 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com29 -> /dev/ttyS28 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com3 -> /dev/ttyS2 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com30 -> /dev/ttyS29 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com31 -> /dev/ttyS30 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com32 -> /dev/ttyS31 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com4 -> /dev/ttyS3 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com5 -> /dev/ttyS4 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com6 -> /dev/ttyS5 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com7 -> /dev/ttyS6 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com8 -> /dev/ttyS7 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com9 -> /dev/ttyS8 lrwxrwxrwx 1 zs zs 8 6月 16 01:16 y: -> /home/zs lrwxrwxrwx 1 zs zs 1 6月 16 01:16 z: -> / CallApp Deepin-QQ c:/Program Files/Tencent/QQ/Bin/QQ.exe 2021年 06月 16日 星期三 01:16:58 CST:kill QQ.exe block 2021年 06月 16日 星期三 01:16:58 CST:No wine process found /home/zs/.deepinwine/Deepin-QQ/drive_c/Program Files/Tencent/QQ/Bin Starting process c:/Program Files/Tencent/QQ/Bin/QQ.exe ... /opt/deepinwine/apps/Deepin-QQ base ❯ wine: cannot find L"C:\\windows\\system32\\winemenubuilder.exe" wine version: 2.18 libGL error: No matching fbConfigs or visuals found libGL error: failed to load driver: swrast X Error of failed request: GLXBadContext Major opcode of failed request: 152 (GLX) Minor opcode of failed request: 6 (X_GLXIsDirect) Serial number of failed request: 207 Current serial number in output stream: 206 ​可以发现最下面的log信息有一些异常,首先第一行是因为我们是Ubuntu系统,可以暂且不关注 +...

                  June 16, 2021 · 4 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/rk3399/index.html b/tags/rk3399/index.html index d4156911..4fbc5aba 100644 --- a/tags/rk3399/index.html +++ b/tags/rk3399/index.html @@ -1,14 +1,14 @@ RK3399 | Zs's Blog -

                  使用 OrangePi 4 LTS 做旁路由

                  前言 最近同居的学长从香港带了个最新版的 Apple TV 回来,但是 Apple TV 在国内用不了,必须要代理才可以,所以考虑到了路由器代理的方案。但是现在家里在用的路由器是 Redmi AX3000,没法刷固件,也不想再买个 R2S 这种软路由了,因此就计划将公司之前用完的 香橙派(OrangePi) 4 LTS 利用一下。它的芯片是 RK3399,用来做路由器绰绰有余,不用可惜了。 +

                  使用 OrangePi 4 LTS 做旁路由

                  前言 最近同居的学长从香港带了个最新版的 Apple TV 回来,但是 Apple TV 在国内用不了,必须要代理才可以,所以考虑到了路由器代理的方案。但是现在家里在用的路由器是 Redmi AX3000,没法刷固件,也不想再买个 R2S 这种软路由了,因此就计划将公司之前用完的 香橙派(OrangePi) 4 LTS 利用一下。它的芯片是 RK3399,用来做路由器绰绰有余,不用可惜了。 为什么是旁路由? 不熟悉旁路由的同学可以看篇指南:从听说到上手,人人都能看懂的旁路由入门指南 找了一些常见的固件,貌似只有针对于 OrangePi R1 和 OrangePi R1 Plus 编译的软路由固件,并且讯龙官方也有放出针对这两个板子的 Openwrt 固件1,可以说是就是为软路由而生,价格也比较便宜,200 左右,性能和 R2S 差别不大。 试了一下在 4 LTS 上跑 R1 和 R1 Plus 的固件2,都无法正常点亮,可能可以自己编译一个对应架构的 OpenWrt,但是有点麻烦,还是没尝试。 考虑到 4 LTS 上可以使用 Docker,因此可以在上面用 Docker 跑一个 OpenWrt 然后做旁路由,到时候只需要把 Apple TV 或者路由器的网关和 DNS 改一下就可以,因此最终选择使用旁路由方案。 具体方案 这里直接参考了小苏的教程:https://mlapp.cn/376.html,写的很清晰,而且很好的考虑了没有基础的同学,赞一个! 里面写的很详细,但是需要注意的是,因为香橙派4 LTS是 ARMv8 架构的,但是直接拉教程里面的默认 latest 镜像是 ARMv7 的,因此需要指定一下镜像的版本,具体的镜像版本可以看 Docker Hub 中的介绍。 -docker pull registry....

                  December 31, 2022 · 1 min · zzsqwq
                  December 31, 2022 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/search-engine/index.html b/tags/search-engine/index.html index a02874c6..0000babd 100644 --- a/tags/search-engine/index.html +++ b/tags/search-engine/index.html @@ -1,6 +1,6 @@ Search Engine | Zs's Blog -

                  如何善用搜索引擎?

                  前言 我们使用搜索引擎可能是为了搜集信息、或者是解决一些问题。但如果不能正确的使用搜索引擎,使用关键字等,可能搜到的答案就与问题相关不大,或者与我们的问题相差甚远。 +

                  如何善用搜索引擎?

                  前言 我们使用搜索引擎可能是为了搜集信息、或者是解决一些问题。但如果不能正确的使用搜索引擎,使用关键字等,可能搜到的答案就与问题相关不大,或者与我们的问题相差甚远。 这篇文章意在分享我个人在学习、工作中使用搜索引擎的一些技巧与思考,可能后续会不断的更新,如有纰漏,还请大家指正。 应该使用什么搜索平台? 想要提高搜索的效率,选择一个好的搜索引擎或者内容平台颇为重要。 下面列举的是我平时会使用的一些平台,列出的顺序代表了我个人对于他们的推荐程度: @@ -10,8 +10,9 @@ 如何正确的知道问题所在? 我们遇到一个问题,要首先能够定位这个问题的关键。 例如编译中出错了,可能有很多 log,你必须能够精确定位到到底哪一条 log 才是这次编译出错的关键,进而才能解决这个问题。 以 CMake 为例,编译时报错 log 一般为红色,警告 log 一般为黄色,普通 log 一般为白色。得益于这种等级/颜色分明的 log ,我们可以快速的定位报错。我们日常编程中,为了便于 Debug,最好也遵循这个规范,例如在 C++ 中打印错误 log 时推荐使用 std::stderr 而不是 std::stdout 。 -见过很多身边的同学遇到了报错,就一股脑粘贴所有的报错 log,然后贴到搜索引擎中,发现相关的错误基本没有。这就是没有其中错误的关键,报错时的 log 可能 100 行只有 10 行是关键的,甚至只有一行是关键的,例如 100 行 log 中只有 未定义的引用(undefined reference to ‘xxx’) 这一句是最关键的。...

                  October 30, 2022 · 1 min · zzsqwq
                  © 2024 Zs's Blog +见过很多身边的同学遇到了报错,就一股脑粘贴所有的报错 log,然后贴到搜索引擎中,发现相关的错误基本没有。这就是没有其中错误的关键,报错时的 log 可能 100 行只有 10 行是关键的,甚至只有一行是关键的,例如 100 行 log 中只有 未定义的引用(undefined reference to ‘xxx’) 这一句是最关键的。 +...

                  October 30, 2022 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/skills/index.html b/tags/skills/index.html index 2b8acf36..085284c3 100644 --- a/tags/skills/index.html +++ b/tags/skills/index.html @@ -1,6 +1,6 @@ Skills | Zs's Blog -

                  如何善用搜索引擎?

                  前言 我们使用搜索引擎可能是为了搜集信息、或者是解决一些问题。但如果不能正确的使用搜索引擎,使用关键字等,可能搜到的答案就与问题相关不大,或者与我们的问题相差甚远。 +

                  如何善用搜索引擎?

                  前言 我们使用搜索引擎可能是为了搜集信息、或者是解决一些问题。但如果不能正确的使用搜索引擎,使用关键字等,可能搜到的答案就与问题相关不大,或者与我们的问题相差甚远。 这篇文章意在分享我个人在学习、工作中使用搜索引擎的一些技巧与思考,可能后续会不断的更新,如有纰漏,还请大家指正。 应该使用什么搜索平台? 想要提高搜索的效率,选择一个好的搜索引擎或者内容平台颇为重要。 下面列举的是我平时会使用的一些平台,列出的顺序代表了我个人对于他们的推荐程度: @@ -10,8 +10,9 @@ 如何正确的知道问题所在? 我们遇到一个问题,要首先能够定位这个问题的关键。 例如编译中出错了,可能有很多 log,你必须能够精确定位到到底哪一条 log 才是这次编译出错的关键,进而才能解决这个问题。 以 CMake 为例,编译时报错 log 一般为红色,警告 log 一般为黄色,普通 log 一般为白色。得益于这种等级/颜色分明的 log ,我们可以快速的定位报错。我们日常编程中,为了便于 Debug,最好也遵循这个规范,例如在 C++ 中打印错误 log 时推荐使用 std::stderr 而不是 std::stdout 。 -见过很多身边的同学遇到了报错,就一股脑粘贴所有的报错 log,然后贴到搜索引擎中,发现相关的错误基本没有。这就是没有其中错误的关键,报错时的 log 可能 100 行只有 10 行是关键的,甚至只有一行是关键的,例如 100 行 log 中只有 未定义的引用(undefined reference to ‘xxx’) 这一句是最关键的。...

                  October 30, 2022 · 1 min · zzsqwq
                  © 2024 Zs's Blog +见过很多身边的同学遇到了报错,就一股脑粘贴所有的报错 log,然后贴到搜索引擎中,发现相关的错误基本没有。这就是没有其中错误的关键,报错时的 log 可能 100 行只有 10 行是关键的,甚至只有一行是关键的,例如 100 行 log 中只有 未定义的引用(undefined reference to ‘xxx’) 这一句是最关键的。 +...

                  October 30, 2022 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/ssh/index.html b/tags/ssh/index.html index cd916fe2..a6241705 100644 --- a/tags/ssh/index.html +++ b/tags/ssh/index.html @@ -1,12 +1,13 @@ Ssh | Zs's Blog -

                  Docker-Gitlab 与主机共用 ssh 的 22 端口

                  背景 在使用 Docker 搭建 Gitlab/Gitee 会导致无法与主机端共用 22 端口,这导致 ssh 连接的时候会使用形如 ssh://git@git.xxxx.cn:4022/zs/zsblog.git 的 ssh 链接,而不是像官方 Gitlab 那种非常干净的 git@git.xxxx.cn/zs/zsblog.git 链接。这对于我这种强迫症而言非常的难受啊,但因为主机的 22 端口已经被占用了,无法共用,所以需要考虑两者共享端口的问题。 +

                  Docker-Gitlab 与主机共用 ssh 的 22 端口

                  背景 在使用 Docker 搭建 Gitlab/Gitee 会导致无法与主机端共用 22 端口,这导致 ssh 连接的时候会使用形如 ssh://git@git.xxxx.cn:4022/zs/zsblog.git 的 ssh 链接,而不是像官方 Gitlab 那种非常干净的 git@git.xxxx.cn/zs/zsblog.git 链接。这对于我这种强迫症而言非常的难受啊,但因为主机的 22 端口已经被占用了,无法共用,所以需要考虑两者共享端口的问题。 虽说是两者共用,但其实还是使用类似于端口转发的特点,简单说就是在主机设置 git 用户,然后通过一个脚本将 git 用户的所有 ssh 流量转发到 Gitlab 容器中,从而完成对应的事情。 关于 Gitee 的设置,Gitee 官方的 Docker 部署教程1已经说的很清楚了,按照该步骤执行完全没问题。 而关于 Gitlab 貌似没有比较详尽的教程,搜索后发现了一个 Issue2 以及一篇博文3,后者讲的比较清楚,但是经过实践后发现存在一定问题,因此决定将可行的方案记录下来。 具体步骤 一、初始设置 在开始之前,docker-compose.yml 中设置比较关键的几个配置如下: -gitlab-web: image: 'gitlab/gitlab-ce:latest' container_name: 'gitlab' restart: always environment: GITLAB_OMNIBUS_CONFIG: | gitlab_rails['gitlab_shell_ssh_port'] = 4022 ports: - '3090:80' - '4022:22' - '6060:6060' volumes: - '/srv/gitlab/config:/etc/gitlab' - '/srv/gitlab/logs:/var/log/gitlab' - '/srv/gitlab/data:/var/opt/gitlab' - ....

                  April 24, 2022 · 3 min · zzsqwq
                  © 2024 Zs's Blog +gitlab-web: image: 'gitlab/gitlab-ce:latest' container_name: 'gitlab' restart: always environment: GITLAB_OMNIBUS_CONFIG: | gitlab_rails['gitlab_shell_ssh_port'] = 4022 ports: - '3090:80' - '4022:22' - '6060:6060' volumes: - '/srv/gitlab/config:/etc/gitlab' - '/srv/gitlab/logs:/var/log/gitlab' - '/srv/gitlab/data:/var/opt/gitlab' - .... #一些其他的配置 如上设置基本可以确保 Gitlab 形如 ssh://git@git.xxxx.cn:4022/zs/zsblog.git 的链接可以使用。 +...

                  April 24, 2022 · 3 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/steam/index.html b/tags/steam/index.html index 12d436b7..01f99afd 100644 --- a/tags/steam/index.html +++ b/tags/steam/index.html @@ -1,13 +1,14 @@ Steam | Zs's Blog -

                  deepin-wine-qq-9.1.8版本无法正常启动的解决方案

                  问题描述 ​Ubuntu下想要使用QQ有一个比较好的解决方案就是deepin-wine的版本,deepin-wine版本的QQ一共有两个版本,分别是 8.9.1 和 9.1.8 ,前者安装后发现无法登陆,登录时会提示版本过低的问题,于是我换到9.1.8版本后,启动初始化后就无任何信息了,于是开始排查问题 +

                  deepin-wine-qq-9.1.8版本无法正常启动的解决方案

                  问题描述 ​Ubuntu下想要使用QQ有一个比较好的解决方案就是deepin-wine的版本,deepin-wine版本的QQ一共有两个版本,分别是 8.9.1 和 9.1.8 ,前者安装后发现无法登陆,登录时会提示版本过低的问题,于是我换到9.1.8版本后,启动初始化后就无任何信息了,于是开始排查问题 解决方案 ​首先我们根据上文的启示,因为每一个应用程序对应了一个 xxx.desktop 文件,因此在应用库中的QQ一定也有一个对应的 desktop 文件 ​我们进入到 /usr/share/applications ,运行 $ ls | grep -i qq ​可以发现其中有一个名为 deepin.com.qq.im.desktop 的文件,我们打开后发现内容如下: #!/usr/bin/env xdg-open [Desktop Entry] Encoding=UTF-8 Type=Application X-Created-By=Deepin WINE Team Categories=chat; Icon=deepin.com.qq.im Exec="/opt/deepinwine/apps/Deepin-QQ/run.sh" -u %u Name=QQ Name[zh_CN]=QQ Comment=Tencent QQ Client on Deepin Wine StartupWMClass=QQ.exe MimeType= ​可以看到Exec那一栏为 Exec="/opt/deepinwine/apps/Deepin-QQ/run.sh" -u %u ,发现他是运行目录下的一个 run.sh 脚本来启动的。 ​我们进入目录下直接运行该脚本,查看log信息: -base ❯ ./run.sh Run Deepin-QQ 9.1.8deepin0 c:/Program Files/Tencent/QQ/Bin/QQ.exe run Deepin-QQ progress pid Gtk-Message: 01:16:58.069: GtkDialog mapped without a transient parent....

                  June 16, 2021 · 4 min · zzsqwq
                  © 2024 Zs's Blog +base ❯ ./run.sh Run Deepin-QQ 9.1.8deepin0 c:/Program Files/Tencent/QQ/Bin/QQ.exe run Deepin-QQ progress pid Gtk-Message: 01:16:58.069: GtkDialog mapped without a transient parent. This is discouraged. total 0 lrwxrwxrwx 1 zs zs 10 6月 16 01:16 c: -> ../drive_c lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com1 -> /dev/ttyS0 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com10 -> /dev/ttyS9 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com11 -> /dev/ttyS10 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com12 -> /dev/ttyS11 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com13 -> /dev/ttyS12 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com14 -> /dev/ttyS13 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com15 -> /dev/ttyS14 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com16 -> /dev/ttyS15 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com17 -> /dev/ttyS16 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com18 -> /dev/ttyS17 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com19 -> /dev/ttyS18 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com2 -> /dev/ttyS1 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com20 -> /dev/ttyS19 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com21 -> /dev/ttyS20 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com22 -> /dev/ttyS21 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com23 -> /dev/ttyS22 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com24 -> /dev/ttyS23 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com25 -> /dev/ttyS24 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com26 -> /dev/ttyS25 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com27 -> /dev/ttyS26 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com28 -> /dev/ttyS27 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com29 -> /dev/ttyS28 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com3 -> /dev/ttyS2 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com30 -> /dev/ttyS29 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com31 -> /dev/ttyS30 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com32 -> /dev/ttyS31 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com4 -> /dev/ttyS3 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com5 -> /dev/ttyS4 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com6 -> /dev/ttyS5 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com7 -> /dev/ttyS6 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com8 -> /dev/ttyS7 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com9 -> /dev/ttyS8 lrwxrwxrwx 1 zs zs 8 6月 16 01:16 y: -> /home/zs lrwxrwxrwx 1 zs zs 1 6月 16 01:16 z: -> / CallApp Deepin-QQ c:/Program Files/Tencent/QQ/Bin/QQ.exe 2021年 06月 16日 星期三 01:16:58 CST:kill QQ.exe block 2021年 06月 16日 星期三 01:16:58 CST:No wine process found /home/zs/.deepinwine/Deepin-QQ/drive_c/Program Files/Tencent/QQ/Bin Starting process c:/Program Files/Tencent/QQ/Bin/QQ.exe ... /opt/deepinwine/apps/Deepin-QQ base ❯ wine: cannot find L"C:\\windows\\system32\\winemenubuilder.exe" wine version: 2.18 libGL error: No matching fbConfigs or visuals found libGL error: failed to load driver: swrast X Error of failed request: GLXBadContext Major opcode of failed request: 152 (GLX) Minor opcode of failed request: 6 (X_GLXIsDirect) Serial number of failed request: 207 Current serial number in output stream: 206 ​可以发现最下面的log信息有一些异常,首先第一行是因为我们是Ubuntu系统,可以暂且不关注 +...

                  June 16, 2021 · 4 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/stl/index.html b/tags/stl/index.html index 7224f165..8bf93fb7 100644 --- a/tags/stl/index.html +++ b/tags/stl/index.html @@ -1,8 +1,8 @@ STL | Zs's Blog -

                  关于STL的一些总结

                  前言 STL之前只会用 stack 和 queue ,set 和 map 啥的也不太会用。学习一下。 +

                  关于STL的一些总结

                  前言 STL之前只会用 stack 和 queue ,set 和 map 啥的也不太会用。学习一下。 ...

                  February 16, 2020 · 3 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/summary/index.html b/tags/summary/index.html index c7d4dd72..d46924b9 100644 --- a/tags/summary/index.html +++ b/tags/summary/index.html @@ -1,6 +1,6 @@ Summary | Zs's Blog -

                  2023 年度总结

                  前言 在回望过去时,我们常感叹时间飞逝,我想这或许是因为过去发生的无数大小事情最终在脑海中留存的只有寥寥几件。因此,撰写年度总结这件事似乎变得格外有意义,它能帮助我们更充分地回味过去的一年。可能正是因为如此,现在各大 APP 似乎都很喜欢推出年度总结,例如网易云、QQ音乐、知乎、飞书、京东、美团、支付宝等。为此,我写下了这篇 2023 年度总结。 +

                  2023 年度总结

                  前言 在回望过去时,我们常感叹时间飞逝,我想这或许是因为过去发生的无数大小事情最终在脑海中留存的只有寥寥几件。因此,撰写年度总结这件事似乎变得格外有意义,它能帮助我们更充分地回味过去的一年。可能正是因为如此,现在各大 APP 似乎都很喜欢推出年度总结,例如网易云、QQ音乐、知乎、飞书、京东、美团、支付宝等。为此,我写下了这篇 2023 年度总结。 仔细回味我这过去的一年,我想用几个关键词来概括:#消费升级、#数码科技、#大模型、#老友重逢。 #消费升级:这一年是我消费升级的一年,尽管今年「消费降级」这个词似乎很火,但我似乎与大众走上了一条相反的道路。可能是因为我以往的消费水平本就不高,所以「降级」更是无从谈起。 #数码科技:这一年我购入了一些新的数码设备,虽然数量不多,但每一件都还挺满意的。同时今年由于消费观念的转变,也支持了很多正版软件,因此今年在软件上的开销也不小。 @@ -17,8 +17,7 @@ 五月 五月似乎是相对平淡的一月,在继续社畜日常的同时开始写毕设了。 六月 月初和朋友去海底捞过了生日,属于是 404 的「企业文化」了。然后终于把毕设给忙完了,返校进行了答辩,结果还算顺利。因为返校了也见了很多老朋友,舍友、基地的伙伴们、学弟们(是的应该是没有学妹),约了数不清次数的饭。 基地的大伙聚会 七月 我正式本科毕业了。 -就像开头说的,回望过去总是很快。感觉开学和父母踏进工大校园的那一天还历历在目,转眼间就要毕业了。纵有万般不舍,但还是不得不和朋友们分别了,最后一晚大家一起在 KTV 合唱《朋友》的时候,忍不住泪奔。 -再见,工大 八月 相对平淡的一月,学弟来深圳参加夏令营,顺便过来找我玩,一起逛了腾讯大厦和华强北,看完感觉大厂平常的这些福利确实还是很不错的(不过确实加班严重)。...

                  January 3, 2024 · 1 min · zzsqwq

                  2022 年度总结

                  2022 依旧是被疫情伴随的一年,时间正着看总是要比回看慢很多,现在回头看过往一年似乎一瞬间就过去了。 +...

                  January 3, 2024 · 1 min · zzsqwq

                  2022 年度总结

                  2022 依旧是被疫情伴随的一年,时间正着看总是要比回看慢很多,现在回头看过往一年似乎一瞬间就过去了。 今年共发了 11 篇文章,其中还包含了两篇碎碎念,还是没有达到月更,新的一年希望可以。2022 年对我来说变化很大,算是暂时摆脱了学生生活,体验了社畜的感觉,打卡了北上广深中的北和深。 接下来按月份盘点一些值得纪念的事情吧。 一月: @@ -45,12 +44,8 @@ 哦对了,这个月还搬了新的住所,因为人逐渐变多了,之前的屋子已经住不下了。九月,真是繁忙的一月。 十月: 这个月初入手了 Apple Watch,补齐了个人设备的最后一块拼图算是。iMac 这种没有算进来,因为 iOS、iPadOS、MacOS、WatchOS 四个系统已经集齐了,苹果生态给人的感觉真的很不错。 -有了 Watch 以后,借着新鲜感锻炼了一段时间,但是体重不降反增了,于是动力没了,又回到了肥宅的生活😁。 -同时这个月还和乐乐和雷宝一起去了深圳的欢乐谷游玩,体验了失重的感觉,下次不敢了。 -十一月:平淡的一个月,上班、吃吃吃、玩玩玩。卓卓越来越好看了。 -十二月: -学长从 HK 带回来了最新版的 Apple TV,苹果生态又添一员。现在的联动已经非常棒了,手机可以直接推流到 Homepod、电视、Mac、耳机等。...

                  January 1, 2023 · 1 min · zzsqwq
                  January 1, 2023 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/suspended/index.html b/tags/suspended/index.html index 62fd6c6d..228d9edb 100644 --- a/tags/suspended/index.html +++ b/tags/suspended/index.html @@ -1,14 +1,15 @@ Suspended | Zs's Blog -

                  记一次 GitHub 账号突然被 suspended 的经历

                  TL;DR 我在 2023.11.07 凌晨被 GitHub 封禁了账号,GitHub 账号被 suspended 后会在 GitHub 上完全除名(只有自建创建的组织不会消失)。 +

                  记一次 GitHub 账号突然被 suspended 的经历

                  TL;DR 我在 2023.11.07 凌晨被 GitHub 封禁了账号,GitHub 账号被 suspended 后会在 GitHub 上完全除名(只有自建创建的组织不会消失)。 被封禁后我首先通过 Google 查找了相关的文章。 根据博主 @phith0n 的指引首先通过 API:https://api.github.com/users/[username]/starred 备份了自己 star 过的项目,同时通过 Can’t sign-in form 来在无法登陆的情况下发起 GitHub Support 工单来询问/请求解封/询问原因等,一般在两天内收到了回复。最终账号顺利恢复。 我此次被封禁的原因是由于管理的组织内部有成员被盗号,在组织内创建了违法仓库,因此管理员和被盗号的成员都被封禁了,但后续都被解除了封禁。同时也有可能因为创建违反 DMCA 条款 的仓库、fork 违反 DMCA 条款的仓库、贩卖学生/教师教育包等原因被封禁。 背景 大约在 2023.11.07 凌晨 00:30 左右,在 GitHub 上看到了一个不错的项目想要 Star,被提示没有登陆。当时我还在想:“怎么这次 session 过期的这么快?” 就当我边疑惑边重新登录后,突然收到了下图的提示我的账号「Account suspended」: 确认无法登录后,查看邮箱没有任何相关通知。同时我查看了其他内容是否还存在,最后综合表现如下: 没有任何邮件/信息通知被封禁及更加具体的封禁原因,只告诉违反了 ToS 个人页面(https://github.com/zzsqwq)无法访问,访问显示 404 提的相关 Issue 全部被删除(隐藏),无法找到 个人创建的所有项目,访问全部 404,也无法拉取 自己参与的项目,被除名 自己加入的组织,被除名 自己创建的组织,访问 404 简单说就是跟这个账号从来没存在过一样,除了仍可以登陆,但是显示 suspended。接下来开始尝试找办法恢复。 -恢复经过 试图查找封禁原因 首先看提示上显示违反了 Github Terms of Service,快速的看了一眼 ToS 没发现我有什么明显违规的地方。...

                  November 12, 2023 · 4 min · zzsqwq
                  © 2024 Zs's Blog +恢复经过 试图查找封禁原因 首先看提示上显示违反了 Github Terms of Service,快速的看了一眼 ToS 没发现我有什么明显违规的地方。 +...

                  November 12, 2023 · 4 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/theme/index.html b/tags/theme/index.html index 59784b3f..e7686909 100644 --- a/tags/theme/index.html +++ b/tags/theme/index.html @@ -1,6 +1,6 @@ Theme | Zs's Blog -

                  一个基于 Hugo 的个人主页主题

                  背景 之前看到过学长学姐做过个人主页,多是用来申请一些学校的夏令营使用的,觉得非常的 Nice,自己也想搞一个。 +

                  一个基于 Hugo 的个人主页主题

                  背景 之前看到过学长学姐做过个人主页,多是用来申请一些学校的夏令营使用的,觉得非常的 Nice,自己也想搞一个。 大家之前好像大多用的是基于 Hexo 的一个主题 — hexo-theme-academia,但是由于之前我用过 Hexo,觉得他有一些比较明显的弊端,例如环境配置比较麻烦、需要安装 Nodejs、npm 等环境,然后再安装 Hexo。其次它的构建速度比较慢,用起来感觉比较僵硬。 后来随着了解增多,尝试了 Typecho、WordPress,Hugo 等主题后,目前还是决定使用 Hugo。它构建速度快,而且安装简单,在 Ubuntu 上只需要一行 sudo apt install hugo 即可,不可谓不简单。因此萌生了移植一个 Hugo 版本主题的想法,刚好可以锻炼一下自己。 欢迎点击 这里 查看我的个人主页。 @@ -18,5 +18,5 @@ 中文效果图:

                  May 3, 2022 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/typecho/index.html b/tags/typecho/index.html index f2408ac5..c1b93e4e 100644 --- a/tags/typecho/index.html +++ b/tags/typecho/index.html @@ -1,9 +1,9 @@ Typecho | Zs's Blog -

                  自买服务器建站教程

                  引言 本来之前是用的 Hexo + Github 搭建的,虽然用的是 Github 的服务器,但是我用家里的移动网访问起来还是没什么压力,就是慢一点,可以接受。 +

                  自买服务器建站教程

                  引言 本来之前是用的 Hexo + Github 搭建的,虽然用的是 Github 的服务器,但是我用家里的移动网访问起来还是没什么压力,就是慢一点,可以接受。 后来到了学校,我们学校网访问 Github 的速度简直可以用龟速来形容,白天可以说不开代理根本进不去,只有晚上了才能勉强进得去。然后我就寻思,能不能换成国内的服务器,然后就发现了 Gitee ,这个可以算是中国版的 Github ,他具有的服务 Gitee Pages 在国内可以飞速的访问,But如果想要自定义域名/每次推送自动更新需要开 Github Pages Pro ,还挺贵的,一年大概 120¥ 吧。此外,如果想要将域名解析到国内的服务器必须要备案,备案又必须有服务器,那我有服务器了还费那些事了,于是考虑自己买服务器重构一下博客。 ...

                  August 26, 2020 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/typora/index.html b/tags/typora/index.html index fa7a19ed..3bade87e 100644 --- a/tags/typora/index.html +++ b/tags/typora/index.html @@ -1,6 +1,6 @@ Typora | Zs's Blog -

                  Markdown 编辑器推荐

                  前言 近期著名 Markdown 编辑器 Typora 宣布收费了,起初感觉很难受,后来感慨之余也觉得算是合理,毕竟 Typora 用起来感觉是真的很良心,也在考虑是否买一份支持一下。 +

                  Markdown 编辑器推荐

                  前言 近期著名 Markdown 编辑器 Typora 宣布收费了,起初感觉很难受,后来感慨之余也觉得算是合理,毕竟 Typora 用起来感觉是真的很良心,也在考虑是否买一份支持一下。 已于2021/12/10购入,还是选择回归了 Typora 了哈哈哈 虽说左右分屏的设计可能更符合 Markdown 的初衷,但是像 Typora 这种所见即所得(WYSIWYG) 的书写体验确实是感觉习惯了就回不去了。 因此近期也搜集了 Markdown 编辑器作为 Typora 的替代品,在这里给大家分享一下。 @@ -15,8 +15,9 @@ 在我使用的一段时间内,他给我的感觉是,功能十分丰富的一个 Markdown 文件管理工具。如果你购买了他的同步服务,那你可以很轻松的在各平台同步你的 Markdown 文件夹,并且基于他强大的插件,可以很完成很多 Markdown 文件份外的事,例如待办清单、日历等等。 他虽没有所见即所得的模式,但是依靠其一款第三方插件,可以达成类似的效果,不过还是用起来不如 Typora 这种顺手。同时,它的各端同步如果不开启官方的服务,用起来还是挺麻烦的,经过我的一阵倒腾,我总结了如下几个方案: 使用第三方Git管理插件,可以定时推送文件夹中的内容到仓库,这样可以完成 linux 与 Windwos 平台的同步,只需要在某一方推送某一方拉取即可。而 Windows 平台与 iPad 平台的同步,可以借助 Apple 的 iCloud,Windows上有对应的客户端,这也是 Obsidian 官方支持的。不过在我使用的过程中我发现,这样异常的麻烦,使用 Git 来管理很可能会产生冲突,导致需要手动处理冲突,久而久之就会觉得很烦。 -使用自建云盘如 NextCloud + Obsidian,或者 Seafile + Obsidian。 这个是我觉得目前非常可行的一个方案,最近我也有在尝试 NextCloud,它的多端同步做的非常不错,依靠此可以在各个平台同步文件夹,加上 Obsidian 强悍的能力,是不错的组合!...

                  December 1, 2021 · 1 min · zzsqwq
                  © 2024 Zs's Blog +使用自建云盘如 NextCloud + Obsidian,或者 Seafile + Obsidian。 这个是我觉得目前非常可行的一个方案,最近我也有在尝试 NextCloud,它的多端同步做的非常不错,依靠此可以在各个平台同步文件夹,加上 Obsidian 强悍的能力,是不错的组合! +...

                  December 1, 2021 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/ubuntu/index.html b/tags/ubuntu/index.html index 8f22d22d..0b06f448 100644 --- a/tags/ubuntu/index.html +++ b/tags/ubuntu/index.html @@ -1,6 +1,6 @@ Ubuntu | Zs's Blog -

                  2021版小新Pro14 Ubuntu 20.04 配置指南

                  2021版小新Pro14 Ubuntu 20.04 配置指南 补充 最近重装了 Ubuntu 20.04,又找了相关的一些帖子,发现 聯想Yoga 14s 2021款裝機小記 中提到了下文中提到的屏幕闪烁的问题,解决办法是:只需要在内核参数中加入 i915.enable_psr=0 即可。 +

                  2021版小新Pro14 Ubuntu 20.04 配置指南

                  2021版小新Pro14 Ubuntu 20.04 配置指南 补充 最近重装了 Ubuntu 20.04,又找了相关的一些帖子,发现 聯想Yoga 14s 2021款裝機小記 中提到了下文中提到的屏幕闪烁的问题,解决办法是:只需要在内核参数中加入 i915.enable_psr=0 即可。 具体操作步骤如下: $ sudo vim /etc/default/grub 在 GRUB_CMDLINE_LINUX_DEFAULT 这一行的最后添加 i915.enable_psr=0,保存后终端运行: $ sudo update-grub 然后重启即可。 @@ -8,13 +8,15 @@ CPU:酷睿 i5-11300H 显卡:集成显卡 Intel 锐炬Iris Xe 内存:16G 外存:512 SSD 屏幕:分辨率 2880x1800、400nits、100%sRGB 这里需要注意的是,不同时间出的小新Pro14配置是不太一样的,所以我这里列了一下配置。主要区别在于有一部分是2.2K分辨率+MX450显卡,而我这个是2.8K分辨率+锐炬Iris Xe显卡。 为了工作的需要,要装一个Ubuntu,先是装了之前用过的 Ubuntu 18.04,安装后发现触摸板无法使用,一系列探索后无果,在朋友的推荐下,还是决定安装 Ubuntu 20.04 试一下,踩了一些坑,在这里记录一下。 问题列表 如果你遇到了以下问题,那么这篇文章的方法可能会对你有益处: -Ubuntu 18.04 相关 Ubuntu 18.04 无法使用触摸板 Ubuntu 18.04 无法使用内置键盘 Ubuntu 18.04 无法调节亮 Ubuntu 18.04 查看GPU发现是llvm,而不是Iris Xe Ubuntu 20.04 相关 Ubuntu 20....

                  November 2, 2021 · 2 min · zzsqwq

                  deepin-wine-qq-9.1.8版本无法正常启动的解决方案

                  问题描述 ​Ubuntu下想要使用QQ有一个比较好的解决方案就是deepin-wine的版本,deepin-wine版本的QQ一共有两个版本,分别是 8.9.1 和 9.1.8 ,前者安装后发现无法登陆,登录时会提示版本过低的问题,于是我换到9.1.8版本后,启动初始化后就无任何信息了,于是开始排查问题 +Ubuntu 18.04 相关 Ubuntu 18.04 无法使用触摸板 Ubuntu 18.04 无法使用内置键盘 Ubuntu 18.04 无法调节亮 Ubuntu 18.04 查看GPU发现是llvm,而不是Iris Xe Ubuntu 20.04 相关 Ubuntu 20.04 进入后屏幕花屏、黑屏 Ubuntu 20.04 查看GPU发现是llvm,而不是Iris Xe 现在达成的效果 Ubuntu 20.04 能够正常使用,触摸板以及外界屏幕,亮度调节均无问题。 +...

                  November 2, 2021 · 2 min · zzsqwq

                  deepin-wine-qq-9.1.8版本无法正常启动的解决方案

                  问题描述 ​Ubuntu下想要使用QQ有一个比较好的解决方案就是deepin-wine的版本,deepin-wine版本的QQ一共有两个版本,分别是 8.9.1 和 9.1.8 ,前者安装后发现无法登陆,登录时会提示版本过低的问题,于是我换到9.1.8版本后,启动初始化后就无任何信息了,于是开始排查问题 解决方案 ​首先我们根据上文的启示,因为每一个应用程序对应了一个 xxx.desktop 文件,因此在应用库中的QQ一定也有一个对应的 desktop 文件 ​我们进入到 /usr/share/applications ,运行 $ ls | grep -i qq ​可以发现其中有一个名为 deepin.com.qq.im.desktop 的文件,我们打开后发现内容如下: #!/usr/bin/env xdg-open [Desktop Entry] Encoding=UTF-8 Type=Application X-Created-By=Deepin WINE Team Categories=chat; Icon=deepin.com.qq.im Exec="/opt/deepinwine/apps/Deepin-QQ/run.sh" -u %u Name=QQ Name[zh_CN]=QQ Comment=Tencent QQ Client on Deepin Wine StartupWMClass=QQ.exe MimeType= ​可以看到Exec那一栏为 Exec="/opt/deepinwine/apps/Deepin-QQ/run.sh" -u %u ,发现他是运行目录下的一个 run.sh 脚本来启动的。 ​我们进入目录下直接运行该脚本,查看log信息: -base ❯ ./run.sh Run Deepin-QQ 9.1.8deepin0 c:/Program Files/Tencent/QQ/Bin/QQ.exe run Deepin-QQ progress pid Gtk-Message: 01:16:58.069: GtkDialog mapped without a transient parent....

                  June 16, 2021 · 4 min · zzsqwq

                  Ubuntu18.04优化教程

                  前言 因为最近Ubuntu用的比较频繁,所以前一阵把Ubuntu16.04换成Ubuntu18.04了,并且囿于机械硬盘那启动速度,我忍痛割爱把我80G的固态硬盘分给了Ubuntu。 +base ❯ ./run.sh Run Deepin-QQ 9.1.8deepin0 c:/Program Files/Tencent/QQ/Bin/QQ.exe run Deepin-QQ progress pid Gtk-Message: 01:16:58.069: GtkDialog mapped without a transient parent. This is discouraged. total 0 lrwxrwxrwx 1 zs zs 10 6月 16 01:16 c: -> ../drive_c lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com1 -> /dev/ttyS0 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com10 -> /dev/ttyS9 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com11 -> /dev/ttyS10 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com12 -> /dev/ttyS11 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com13 -> /dev/ttyS12 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com14 -> /dev/ttyS13 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com15 -> /dev/ttyS14 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com16 -> /dev/ttyS15 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com17 -> /dev/ttyS16 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com18 -> /dev/ttyS17 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com19 -> /dev/ttyS18 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com2 -> /dev/ttyS1 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com20 -> /dev/ttyS19 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com21 -> /dev/ttyS20 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com22 -> /dev/ttyS21 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com23 -> /dev/ttyS22 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com24 -> /dev/ttyS23 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com25 -> /dev/ttyS24 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com26 -> /dev/ttyS25 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com27 -> /dev/ttyS26 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com28 -> /dev/ttyS27 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com29 -> /dev/ttyS28 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com3 -> /dev/ttyS2 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com30 -> /dev/ttyS29 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com31 -> /dev/ttyS30 lrwxrwxrwx 1 zs zs 11 6月 15 23:36 com32 -> /dev/ttyS31 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com4 -> /dev/ttyS3 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com5 -> /dev/ttyS4 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com6 -> /dev/ttyS5 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com7 -> /dev/ttyS6 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com8 -> /dev/ttyS7 lrwxrwxrwx 1 zs zs 10 6月 15 23:36 com9 -> /dev/ttyS8 lrwxrwxrwx 1 zs zs 8 6月 16 01:16 y: -> /home/zs lrwxrwxrwx 1 zs zs 1 6月 16 01:16 z: -> / CallApp Deepin-QQ c:/Program Files/Tencent/QQ/Bin/QQ.exe 2021年 06月 16日 星期三 01:16:58 CST:kill QQ.exe block 2021年 06月 16日 星期三 01:16:58 CST:No wine process found /home/zs/.deepinwine/Deepin-QQ/drive_c/Program Files/Tencent/QQ/Bin Starting process c:/Program Files/Tencent/QQ/Bin/QQ.exe ... /opt/deepinwine/apps/Deepin-QQ base ❯ wine: cannot find L"C:\\windows\\system32\\winemenubuilder.exe" wine version: 2.18 libGL error: No matching fbConfigs or visuals found libGL error: failed to load driver: swrast X Error of failed request: GLXBadContext Major opcode of failed request: 152 (GLX) Minor opcode of failed request: 6 (X_GLXIsDirect) Serial number of failed request: 207 Current serial number in output stream: 206 ​可以发现最下面的log信息有一些异常,首先第一行是因为我们是Ubuntu系统,可以暂且不关注 +...

                  June 16, 2021 · 4 min · zzsqwq

                  Ubuntu18.04优化教程

                  前言 因为最近Ubuntu用的比较频繁,所以前一阵把Ubuntu16.04换成Ubuntu18.04了,并且囿于机械硬盘那启动速度,我忍痛割爱把我80G的固态硬盘分给了Ubuntu。 后来,用着用着就觉得这个Ubuntu的原始界面确实不是特别的好看,配色偏基佬紫的感觉。“工欲善其事,必先利其器“,我们只有将自己的工作环境布置的舒心一些才能有做下去的动力!所以我想给Ubuntu换一个看起来舒服点的界面,然后上网找教程乱七八糟的倒腾了一会,感觉换完以后完全不一样了,这个界面真的好看!!用起来也特别的舒心,感觉自己马上就要告别Windows投奔Linux的怀抱了。后续还有一些其他的优化,例如装QQ、微信、配置终端等,一并写在这里吧。 Ubuntu界面的优化 具体效果 先放几张效果图上来,是我改后的界面。大概就是这样(自我感觉挺好看的),当然也有其他的主题可供选择。 1.安装GNOME桌面环境主题配置工具 如果要改主题,那么首先要有一个利器,这里我用的Ubuntu18.04,桌面环境为 GNOME 3.28.2 ,因为我目前接触的只有GNOME桌面环境的,Ubuntu18.04本来的桌面环境就是GNOME,但是Ubuntu16.04好像没有自带,但是可以安装,这里大家可以自行百度了解。 @@ -29,8 +31,9 @@ 然后我们回到 GNOME Tweaks 软件中就可以发现,我们已经可以在主题\图标\光标\Shell清单中找到我们移动到文件夹中的文件了,然后选择就可以切换了。这里需要注意的,很多主题都是自带Shell的,你下了一个主题,那么你可以在Shell和主题这两个栏目中都找到他们,是一个配套的。 4.一些后续的调整 我们后续可以改变左边收藏夹的位置,我觉得放在左边有一丢丢的丑,所以我选择把它放在的下面。 我们去Ubuntu软件中搜索 Dash to dock,然后安装这个拓展,然后打开 GNOME Tweaks 软件在拓展中找到他就可以随心所欲的调我们的收藏夹的位置了。 -5.我自己的配置 theme&shell Canta-light-compact icons 01-McMojave-circle 6.界面修改的参考链接 Ubuntu18.04美化主题(mac主题) Ubuntu18.04美化主题(完整版) GNOME-LOOK.ORG 30个非常不错的Ubuntu主题供你选择 ubuntu18....

                  December 4, 2020 · 1 min · zzsqwq
                  © 2024 Zs's Blog +5.我自己的配置 theme&shell Canta-light-compact icons 01-McMojave-circle 6.界面修改的参考链接 Ubuntu18.04美化主题(mac主题) Ubuntu18.04美化主题(完整版) GNOME-LOOK.ORG 30个非常不错的Ubuntu主题供你选择 ubuntu18.04更换鼠标游标主题 配置终端 前言 唔,终端本来用起来感觉也还行,感觉终端就是linux的灵魂,啥都能干。 +...

                  December 4, 2020 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/vim/index.html b/tags/vim/index.html index eb17e274..47355d86 100644 --- a/tags/vim/index.html +++ b/tags/vim/index.html @@ -1,8 +1,8 @@ Vim | Zs's Blog -

                  Linux和Vim入门

                  Linux系统常见命令 基本操作 **cd (Change Directory)**命令:跳转目录 +

                  Linux和Vim入门

                  Linux系统常见命令 基本操作 **cd (Change Directory)**命令:跳转目录 cd path : path为路径,进入相应目录 cd # 或 cd ~ :回到主目录 cd - : 回到上次所在目录 cd !$ :将上个命令的参数做为输入 cd .. :回到上层目录 ...

                  March 30, 2020 · 2 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git a/tags/vim/index.xml b/tags/vim/index.xml index bd90e937..47268af0 100644 --- a/tags/vim/index.xml +++ b/tags/vim/index.xml @@ -102,34 +102,34 @@ <p><strong>tar</strong> 命令:压缩或解压命令。<code>tar [参数] 打包文件名 要打包的各个文件 </code> 。</p> <p>参数表:</p> <table> -<thead> -<tr> -<th>参数</th> -<th>含义</th> -</tr> -</thead> -<tbody> -<tr> -<td>-c</td> -<td>生成档案文件,创建打包文件</td> -</tr> -<tr> -<td>-v</td> -<td>列出归档解档的详细过程,显示进度</td> -</tr> -<tr> -<td>-f</td> -<td>指定档案文件名称,f后面一定是.tar文件,所以放选项最后</td> -</tr> -<tr> -<td>-t</td> -<td>列出档案中包含的文件</td> -</tr> -<tr> -<td>-x</td> -<td>解开档案文件</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">参数</th> + <th style="text-align: left">含义</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">-c</td> + <td style="text-align: left">生成档案文件,创建打包文件</td> + </tr> + <tr> + <td style="text-align: left">-v</td> + <td style="text-align: left">列出归档解档的详细过程,显示进度</td> + </tr> + <tr> + <td style="text-align: left">-f</td> + <td style="text-align: left">指定档案文件名称,f后面一定是.tar文件,所以放选项最后</td> + </tr> + <tr> + <td style="text-align: left">-t</td> + <td style="text-align: left">列出档案中包含的文件</td> + </tr> + <tr> + <td style="text-align: left">-x</td> + <td style="text-align: left">解开档案文件</td> + </tr> + </tbody> </table> <p>打包实例: <code>tar -cvf 文件名 要打包的文件</code> 解压实例:<code>tar -xvf 压缩包名</code></p> </li> diff --git "a/tags/\344\270\273\351\242\230\351\205\215\347\275\256/index.html" "b/tags/\344\270\273\351\242\230\351\205\215\347\275\256/index.html" index 0bdce542..d3e78bae 100644 --- "a/tags/\344\270\273\351\242\230\351\205\215\347\275\256/index.html" +++ "b/tags/\344\270\273\351\242\230\351\205\215\347\275\256/index.html" @@ -1,6 +1,6 @@ 主题配置 | Zs's Blog -

                  Ubuntu18.04优化教程

                  前言 因为最近Ubuntu用的比较频繁,所以前一阵把Ubuntu16.04换成Ubuntu18.04了,并且囿于机械硬盘那启动速度,我忍痛割爱把我80G的固态硬盘分给了Ubuntu。 +

                  Ubuntu18.04优化教程

                  前言 因为最近Ubuntu用的比较频繁,所以前一阵把Ubuntu16.04换成Ubuntu18.04了,并且囿于机械硬盘那启动速度,我忍痛割爱把我80G的固态硬盘分给了Ubuntu。 后来,用着用着就觉得这个Ubuntu的原始界面确实不是特别的好看,配色偏基佬紫的感觉。“工欲善其事,必先利其器“,我们只有将自己的工作环境布置的舒心一些才能有做下去的动力!所以我想给Ubuntu换一个看起来舒服点的界面,然后上网找教程乱七八糟的倒腾了一会,感觉换完以后完全不一样了,这个界面真的好看!!用起来也特别的舒心,感觉自己马上就要告别Windows投奔Linux的怀抱了。后续还有一些其他的优化,例如装QQ、微信、配置终端等,一并写在这里吧。 Ubuntu界面的优化 具体效果 先放几张效果图上来,是我改后的界面。大概就是这样(自我感觉挺好看的),当然也有其他的主题可供选择。 1.安装GNOME桌面环境主题配置工具 如果要改主题,那么首先要有一个利器,这里我用的Ubuntu18.04,桌面环境为 GNOME 3.28.2 ,因为我目前接触的只有GNOME桌面环境的,Ubuntu18.04本来的桌面环境就是GNOME,但是Ubuntu16.04好像没有自带,但是可以安装,这里大家可以自行百度了解。 @@ -15,8 +15,9 @@ 然后我们回到 GNOME Tweaks 软件中就可以发现,我们已经可以在主题\图标\光标\Shell清单中找到我们移动到文件夹中的文件了,然后选择就可以切换了。这里需要注意的,很多主题都是自带Shell的,你下了一个主题,那么你可以在Shell和主题这两个栏目中都找到他们,是一个配套的。 4.一些后续的调整 我们后续可以改变左边收藏夹的位置,我觉得放在左边有一丢丢的丑,所以我选择把它放在的下面。 我们去Ubuntu软件中搜索 Dash to dock,然后安装这个拓展,然后打开 GNOME Tweaks 软件在拓展中找到他就可以随心所欲的调我们的收藏夹的位置了。 -5.我自己的配置 theme&shell Canta-light-compact icons 01-McMojave-circle 6.界面修改的参考链接 Ubuntu18.04美化主题(mac主题) Ubuntu18.04美化主题(完整版) GNOME-LOOK.ORG 30个非常不错的Ubuntu主题供你选择 ubuntu18....

                  December 4, 2020 · 1 min · zzsqwq
                  © 2024 Zs's Blog +5.我自己的配置 theme&shell Canta-light-compact icons 01-McMojave-circle 6.界面修改的参考链接 Ubuntu18.04美化主题(mac主题) Ubuntu18.04美化主题(完整版) GNOME-LOOK.ORG 30个非常不错的Ubuntu主题供你选择 ubuntu18.04更换鼠标游标主题 配置终端 前言 唔,终端本来用起来感觉也还行,感觉终端就是linux的灵魂,啥都能干。 +...

                  December 4, 2020 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/tags/\345\244\247\346\225\260\347\261\273/index.html" "b/tags/\345\244\247\346\225\260\347\261\273/index.html" index 70107ca4..4e1e445e 100644 --- "a/tags/\345\244\247\346\225\260\347\261\273/index.html" +++ "b/tags/\345\244\247\346\225\260\347\261\273/index.html" @@ -1,8 +1,8 @@ 大数类 | Zs's Blog -

                  C++大数类的实现

                  C++大数类设计思路 洛谷大数类的评测结果(开了氧气优化) 这个第四个点真的优化不过去了QAQ,24W的数据,丧心病狂 +

                  C++大数类的实现

                  C++大数类设计思路 洛谷大数类的评测结果(开了氧气优化) 这个第四个点真的优化不过去了QAQ,24W的数据,丧心病狂 ...

                  April 6, 2020 · 5 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/tags/\345\260\217\346\226\260pro14/index.html" "b/tags/\345\260\217\346\226\260pro14/index.html" index 070355f7..e1bb0b99 100644 --- "a/tags/\345\260\217\346\226\260pro14/index.html" +++ "b/tags/\345\260\217\346\226\260pro14/index.html" @@ -1,6 +1,6 @@ 小新Pro14 | Zs's Blog -

                  2021版小新Pro14 Ubuntu 20.04 配置指南

                  2021版小新Pro14 Ubuntu 20.04 配置指南 补充 最近重装了 Ubuntu 20.04,又找了相关的一些帖子,发现 聯想Yoga 14s 2021款裝機小記 中提到了下文中提到的屏幕闪烁的问题,解决办法是:只需要在内核参数中加入 i915.enable_psr=0 即可。 +

                  2021版小新Pro14 Ubuntu 20.04 配置指南

                  2021版小新Pro14 Ubuntu 20.04 配置指南 补充 最近重装了 Ubuntu 20.04,又找了相关的一些帖子,发现 聯想Yoga 14s 2021款裝機小記 中提到了下文中提到的屏幕闪烁的问题,解决办法是:只需要在内核参数中加入 i915.enable_psr=0 即可。 具体操作步骤如下: $ sudo vim /etc/default/grub 在 GRUB_CMDLINE_LINUX_DEFAULT 这一行的最后添加 i915.enable_psr=0,保存后终端运行: $ sudo update-grub 然后重启即可。 @@ -8,8 +8,9 @@ CPU:酷睿 i5-11300H 显卡:集成显卡 Intel 锐炬Iris Xe 内存:16G 外存:512 SSD 屏幕:分辨率 2880x1800、400nits、100%sRGB 这里需要注意的是,不同时间出的小新Pro14配置是不太一样的,所以我这里列了一下配置。主要区别在于有一部分是2.2K分辨率+MX450显卡,而我这个是2.8K分辨率+锐炬Iris Xe显卡。 为了工作的需要,要装一个Ubuntu,先是装了之前用过的 Ubuntu 18.04,安装后发现触摸板无法使用,一系列探索后无果,在朋友的推荐下,还是决定安装 Ubuntu 20.04 试一下,踩了一些坑,在这里记录一下。 问题列表 如果你遇到了以下问题,那么这篇文章的方法可能会对你有益处: -Ubuntu 18.04 相关 Ubuntu 18.04 无法使用触摸板 Ubuntu 18.04 无法使用内置键盘 Ubuntu 18.04 无法调节亮 Ubuntu 18.04 查看GPU发现是llvm,而不是Iris Xe Ubuntu 20.04 相关 Ubuntu 20....

                  November 2, 2021 · 2 min · zzsqwq
                  © 2024 Zs's Blog +Ubuntu 18.04 相关 Ubuntu 18.04 无法使用触摸板 Ubuntu 18.04 无法使用内置键盘 Ubuntu 18.04 无法调节亮 Ubuntu 18.04 查看GPU发现是llvm,而不是Iris Xe Ubuntu 20.04 相关 Ubuntu 20.04 进入后屏幕花屏、黑屏 Ubuntu 20.04 查看GPU发现是llvm,而不是Iris Xe 现在达成的效果 Ubuntu 20.04 能够正常使用,触摸板以及外界屏幕,亮度调节均无问题。 +...

                  November 2, 2021 · 2 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/tags/\345\274\202\346\255\245/index.html" "b/tags/\345\274\202\346\255\245/index.html" index 217ef413..4ef35fa2 100644 --- "a/tags/\345\274\202\346\255\245/index.html" +++ "b/tags/\345\274\202\346\255\245/index.html" @@ -1,6 +1,6 @@ 异步 | Zs's Blog -

                  一个 Javascript 中异步的小技巧

                  前言 最近看了一些 js 有关的知识,其中令我这种初学者感到很头疼的一个问题就是异步问题。 +

                  一个 Javascript 中异步的小技巧

                  前言 最近看了一些 js 有关的知识,其中令我这种初学者感到很头疼的一个问题就是异步问题。 今天就我碰到的一个小问题详解一个关于异步的小技巧。 背景 我在程序中需要鉴权,来判断一个用户是普通用户还是管理员,针对不同的用户渲染不同的页面。 每个用户具有唯一的 ID,因此我只需要将管理员的 ID 放到数据库,然后加载程序的时候一一比对即可。 @@ -15,8 +15,9 @@ 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 所以此处加入 callback 以防止这种情况 这里判断了主程序内是否含有 userInfoReadyCallback 这个函数,如果有的话就执行。 -qq.getSetting({ success: res => { if (res.authSetting['scope.userInfo']) { // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框 qq.getUserInfo({ success: res => { // 可以将 res 发送给后台解码出 unionId this.globalData.userInfo = res.userInfo // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 if (this....

                  January 19, 2022 · 1 min · zzsqwq
                  © 2024 Zs's Blog +qq.getSetting({ success: res => { if (res.authSetting['scope.userInfo']) { // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框 qq.getUserInfo({ success: res => { // 可以将 res 发送给后台解码出 unionId this.globalData.userInfo = res.userInfo // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 if (this.userInfoReadyCallback) { this.userInfoReadyCallback(res) } } }) } } }) 页面初始化部分代码: +...

                  January 19, 2022 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/tags/\346\211\223\345\215\260\346\234\272/index.html" "b/tags/\346\211\223\345\215\260\346\234\272/index.html" index 4fd31889..435e8662 100644 --- "a/tags/\346\211\223\345\215\260\346\234\272/index.html" +++ "b/tags/\346\211\223\345\215\260\346\234\272/index.html" @@ -1,6 +1,6 @@ 打印机 | Zs's Blog -

                  利用树莓派为HP LaserJet 1020配置无线打印功能

                  前言 最近基地的打印机突然又好起来了。 +

                  利用树莓派为HP LaserJet 1020配置无线打印功能

                  前言 最近基地的打印机突然又好起来了。 因为基地的打印机型号比较老——HP LaserJet 1020,没有无线打印的功能。所以之前一位学长1 用树莓派配置了打印机的无线打印功能,但是后来发现有一些问题,有时候发送打印请求树莓派无法接收,而且不知道为何,学长之前用的是树莓派自己创建WiFi,连接对应WiFi才能打印,但是这个显然不是最优的解决办法。 考虑到之间已经配置好基地WiFi,我决定重新配置一下打印功能,使其连接基地WiFi即可实现局域网打印。 配置过程 查看树莓派内容 通过ssh连接树莓派,发现里面除了Github上的一个开源项目create_ap ,就没有什么其他的内容了,连接屏幕后发现没有任何图像信号,无从下手,因此考虑重新刷机。 @@ -14,8 +14,9 @@ $ sudo ifconfig 查看WiFi对应的IP,至此,树莓派可以摆脱屏幕,我们可以使用电脑进行使用 ssh 连接。 这里也可以使用网线进行连接,具体操作如下 用网线连接树莓派和自己的电脑。 -在树莓派的利用 nmtui 选择 Edit a connection ,Add一个Ethernet connect,对IPv4 CONFIGURATION进行设置,首先讲 Automatic 设置为 Manual,设置 Address 为 静态IP 如 192....

                  July 18, 2021 · 2 min · zzsqwq
                  © 2024 Zs's Blog +在树莓派的利用 nmtui 选择 Edit a connection ,Add一个Ethernet connect,对IPv4 CONFIGURATION进行设置,首先讲 Automatic 设置为 Manual,设置 Address 为 静态IP 如 192.168.3.2 ,Gateway 设置为 192.168.3.1 。 +...

                  July 18, 2021 · 2 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/tags/\346\212\265\345\210\266/index.html" "b/tags/\346\212\265\345\210\266/index.html" index 81ccdca2..7e398dc9 100644 --- "a/tags/\346\212\265\345\210\266/index.html" +++ "b/tags/\346\212\265\345\210\266/index.html" @@ -1,6 +1,6 @@ 抵制 | Zs's Blog -

                  为什么应该抵制拼多多?

                  TL;DR 本文旨在结合一系列事实总结拼多多过去的一系列恶心行为,包括不限于 +

                  为什么应该抵制拼多多?

                  TL;DR 本文旨在结合一系列事实总结拼多多过去的一系列恶心行为,包括不限于 虚假宣传 砍一刀套路多 拉人助力 铺天盖地的广告 利用漏洞 希望大家抵制拼多多这种无良平台,非必要不使用拼多多。 前言 最近看了很多拼多多令人反感的操作以及看了很多拼多多的软广,如 拼多多,让谁不爽,看到这么一个无良平台逐渐壮大实在是令人恼火,因此我觉得有必要写一篇文章来总结一下拼多多各种恶心人的操作来让大家了解这个无良平台,来看看他到底为什么让人不爽,并呼吁大家可以联合抵制这个平台。 本文会尽量客观理性,陈述已发生的事实而不是自己的观点,同时因为我不是商家,也不是拼多多的员工,本文只是作为用户角度评判。除了对用户方面的恶心行为,还有对员工及商家的压榨,这个后面有时间再写。欢迎大家补充、批评、指正。 @@ -17,8 +17,9 @@ 据小桀自己回应,直到3月17号下午2点40分左右下播,也没有砍成功,但是突然在4点40分左右莫名其妙的成功了,赠送了一张无门槛购物券可以下单此手机,随后客服回应:砍价不成功不属实,已经发放「特制」优惠券。这一通操作,实在是闻所未闻,谁也能看出来是事态发展到不可预料的地步搞了个东西出来封口的。 实在是太像诈骗、传销了,即使这样广泛的虚假宣传,到现在也没有被整治,也还是随处可见。 附小桀对这件事情的声明: -三、拉人助力 拼多多最特色的行为,应该就是这个拉人助力,可能算是拉人助力的始祖了,如今算是各个软件的标配了,美团、饿了么、携程旅行、智行中也都随处可见。好处显而易见,可以提高自己活动的参与率、提高 App 的下载率、提高品牌知名度、提高用户粘性。...

                  May 1, 2023 · 1 min · zzsqwq
                  © 2024 Zs's Blog +三、拉人助力 拼多多最特色的行为,应该就是这个拉人助力,可能算是拉人助力的始祖了,如今算是各个软件的标配了,美团、饿了么、携程旅行、智行中也都随处可见。好处显而易见,可以提高自己活动的参与率、提高 App 的下载率、提高品牌知名度、提高用户粘性。 +...

                  May 1, 2023 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/tags/\346\213\274\345\244\232\345\244\232/index.html" "b/tags/\346\213\274\345\244\232\345\244\232/index.html" index e56d212f..b88d2412 100644 --- "a/tags/\346\213\274\345\244\232\345\244\232/index.html" +++ "b/tags/\346\213\274\345\244\232\345\244\232/index.html" @@ -1,6 +1,6 @@ 拼多多 | Zs's Blog -

                  为什么应该抵制拼多多?

                  TL;DR 本文旨在结合一系列事实总结拼多多过去的一系列恶心行为,包括不限于 +

                  为什么应该抵制拼多多?

                  TL;DR 本文旨在结合一系列事实总结拼多多过去的一系列恶心行为,包括不限于 虚假宣传 砍一刀套路多 拉人助力 铺天盖地的广告 利用漏洞 希望大家抵制拼多多这种无良平台,非必要不使用拼多多。 前言 最近看了很多拼多多令人反感的操作以及看了很多拼多多的软广,如 拼多多,让谁不爽,看到这么一个无良平台逐渐壮大实在是令人恼火,因此我觉得有必要写一篇文章来总结一下拼多多各种恶心人的操作来让大家了解这个无良平台,来看看他到底为什么让人不爽,并呼吁大家可以联合抵制这个平台。 本文会尽量客观理性,陈述已发生的事实而不是自己的观点,同时因为我不是商家,也不是拼多多的员工,本文只是作为用户角度评判。除了对用户方面的恶心行为,还有对员工及商家的压榨,这个后面有时间再写。欢迎大家补充、批评、指正。 @@ -17,8 +17,9 @@ 据小桀自己回应,直到3月17号下午2点40分左右下播,也没有砍成功,但是突然在4点40分左右莫名其妙的成功了,赠送了一张无门槛购物券可以下单此手机,随后客服回应:砍价不成功不属实,已经发放「特制」优惠券。这一通操作,实在是闻所未闻,谁也能看出来是事态发展到不可预料的地步搞了个东西出来封口的。 实在是太像诈骗、传销了,即使这样广泛的虚假宣传,到现在也没有被整治,也还是随处可见。 附小桀对这件事情的声明: -三、拉人助力 拼多多最特色的行为,应该就是这个拉人助力,可能算是拉人助力的始祖了,如今算是各个软件的标配了,美团、饿了么、携程旅行、智行中也都随处可见。好处显而易见,可以提高自己活动的参与率、提高 App 的下载率、提高品牌知名度、提高用户粘性。...

                  May 1, 2023 · 1 min · zzsqwq
                  © 2024 Zs's Blog +三、拉人助力 拼多多最特色的行为,应该就是这个拉人助力,可能算是拉人助力的始祖了,如今算是各个软件的标配了,美团、饿了么、携程旅行、智行中也都随处可见。好处显而易见,可以提高自己活动的参与率、提高 App 的下载率、提高品牌知名度、提高用户粘性。 +...

                  May 1, 2023 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/tags/\346\220\234\347\264\242/index.html" "b/tags/\346\220\234\347\264\242/index.html" index 6b08fc83..3b6ea1f2 100644 --- "a/tags/\346\220\234\347\264\242/index.html" +++ "b/tags/\346\220\234\347\264\242/index.html" @@ -1,8 +1,8 @@ 搜索 | Zs's Blog -

                  洛谷的一些搜索题

                  1. P1378 油滴扩展 题意 在长方形框中,最多有 n ($0\le{n}\le6$)个相异点,在框中点上依次放置可扩展的油滴,当碰到其他油滴边界或者长方形边框时会停止,扩展呈圆形展开。放置下一个时会确保上一个已经扩展完成。问通过变换放置顺序可使得最终框中剩下的面积最小为多少。 +

                  洛谷的一些搜索题

                  1. P1378 油滴扩展 题意 在长方形框中,最多有 n ($0\le{n}\le6$)个相异点,在框中点上依次放置可扩展的油滴,当碰到其他油滴边界或者长方形边框时会停止,扩展呈圆形展开。放置下一个时会确保上一个已经扩展完成。问通过变换放置顺序可使得最终框中剩下的面积最小为多少。 ...

                  February 4, 2020 · 2 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/tags/\346\225\260\346\215\256\347\273\223\346\236\204/index.html" "b/tags/\346\225\260\346\215\256\347\273\223\346\236\204/index.html" index de545aba..6c543a0e 100644 --- "a/tags/\346\225\260\346\215\256\347\273\223\346\236\204/index.html" +++ "b/tags/\346\225\260\346\215\256\347\273\223\346\236\204/index.html" @@ -1,9 +1,9 @@ 数据结构 | Zs's Blog -

                  高精度计算pi

                  高精度计算PI值 题目描述 使用双向链表作为存储结构,请根据用户输入的一个整数(该整数表示精确到小数点后的位数,可能要求精确到小数点后 500 位),高精度计算PI值。提示:可以利用反三角函数幂级展开式来进行计算。 +

                  高精度计算pi

                  高精度计算PI值 题目描述 使用双向链表作为存储结构,请根据用户输入的一个整数(该整数表示精确到小数点后的位数,可能要求精确到小数点后 500 位),高精度计算PI值。提示:可以利用反三角函数幂级展开式来进行计算。 ...

                  April 20, 2020 · 3 min · zzsqwq

                  关于STL的一些总结

                  前言 STL之前只会用 stack 和 queue ,set 和 map 啥的也不太会用。学习一下。 ...

                  February 16, 2020 · 3 min · zzsqwq

                  单调队列和单调栈总结

                  前言 最近感觉遇到了好多单调队列和单调栈的问题,但是因为以前没学好,所以遇见了就一脸懵逼,然后绝对下决心来学一下。。感觉遇到啥都不会,这可咋办呐。。补不完的漏洞。 ...

                  February 11, 2020 · 3 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/tags/\346\225\260\346\215\256\347\273\223\346\236\204/index.xml" "b/tags/\346\225\260\346\215\256\347\273\223\346\236\204/index.xml" index ddee64c0..8b342451 100644 --- "a/tags/\346\225\260\346\215\256\347\273\223\346\236\204/index.xml" +++ "b/tags/\346\225\260\346\215\256\347\273\223\346\236\204/index.xml" @@ -508,46 +508,46 @@ $$</p> <p>顾名思义,他就是一个单调的队列,那么我们可以规定他是单调递增的还是单调递减的,他和普通的队列有点区别,队列一般是尾进头出,而单调队列要实现的话要确保头和尾都可以出,尾可以进。如果要用STL库的话可以用里面的双端队列。 跟普通队列相比他的进队需要确保一个条件就是要<strong>不破坏原有序列的单调性</strong>,好比我们有一个单调递增的单调队列,也就是从队首到队尾是单调递增的,那么有一段序列是 $[2,3,1,5,8,7,4,2]$ ,我们从左到右依次入队。</p> <table> -<thead> -<tr> -<th>队列中元素</th> -<th>关于元素进出的备注</th> -</tr> -</thead> -<tbody> -<tr> -<td>2</td> -<td>2入队</td> -</tr> -<tr> -<td>2,3</td> -<td>3比2大,可以满足递增性质,入队</td> -</tr> -<tr> -<td>1</td> -<td>因为1比2,3都小,要满足递增性质,先把2,3出队,再将1入队</td> -</tr> -<tr> -<td>1,5</td> -<td>5比1大,可以满足递增性质,入队</td> -</tr> -<tr> -<td>1,5,8</td> -<td>8比5大,可以满足递增性质,入队</td> -</tr> -<tr> -<td>1,5,7</td> -<td>7小于8,大于5,要满足递增性质,我们把8出队,然后将7入队</td> -</tr> -<tr> -<td>1,4</td> -<td>4小于5、7,但是大于1,因此7,5依次出队,4入队</td> -</tr> -<tr> -<td>1,2</td> -<td>2小于4,大于1,因此4出队,2入队</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">队列中元素</th> + <th style="text-align: left">关于元素进出的备注</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">2</td> + <td style="text-align: left">2入队</td> + </tr> + <tr> + <td style="text-align: left">2,3</td> + <td style="text-align: left">3比2大,可以满足递增性质,入队</td> + </tr> + <tr> + <td style="text-align: left">1</td> + <td style="text-align: left">因为1比2,3都小,要满足递增性质,先把2,3出队,再将1入队</td> + </tr> + <tr> + <td style="text-align: left">1,5</td> + <td style="text-align: left">5比1大,可以满足递增性质,入队</td> + </tr> + <tr> + <td style="text-align: left">1,5,8</td> + <td style="text-align: left">8比5大,可以满足递增性质,入队</td> + </tr> + <tr> + <td style="text-align: left">1,5,7</td> + <td style="text-align: left">7小于8,大于5,要满足递增性质,我们把8出队,然后将7入队</td> + </tr> + <tr> + <td style="text-align: left">1,4</td> + <td style="text-align: left">4小于5、7,但是大于1,因此7,5依次出队,4入队</td> + </tr> + <tr> + <td style="text-align: left">1,2</td> + <td style="text-align: left">2小于4,大于1,因此4出队,2入队</td> + </tr> + </tbody> </table> <p>根据上述例子不难看出,我们要入队的时候首先要确保队尾元素要比想要入队的元素小,然后才能入队,否则的话就一直循环让尾部元素出队,直到能够满足单调性为止。</p> <h2 id="单调队列的应用">单调队列的应用</h2> @@ -685,38 +685,38 @@ $$</p> <h2 id="理解-1">理解</h2> <p>单调栈也是在普通栈的基础上加了单调性,一般是用从栈底到栈顶的单调性来命名,好比从栈底到栈顶是单调递增的,那么他就是单调增的栈。跟单调队列一样,他的入栈规则也是<strong>要不破坏单调性</strong>,因此一个单调递增的栈如果有元素要入栈,如果他比栈顶的元素还要大,就可以直接入栈,如果他比栈顶的元素小,那么就要将栈顶的元素一直出栈到比要入栈元素小为止。如果序列为 $[2,3,1,5,4,7]$,要加入单调递增栈中,过程如下。<strong>PS:注意从左到右对应栈底到栈顶。</strong></p> <table> -<thead> -<tr> -<th>栈中的元素</th> -<th>关于元素进出的备注</th> -</tr> -</thead> -<tbody> -<tr> -<td>2</td> -<td>元素2压入栈中</td> -</tr> -<tr> -<td>2,3</td> -<td>3大于2,压入栈中</td> -</tr> -<tr> -<td>1</td> -<td>1小于3、2,因此全部弹出将1入栈</td> -</tr> -<tr> -<td>1,5</td> -<td>5大于1,压入栈中</td> -</tr> -<tr> -<td>1,4</td> -<td>4比5小,比1大,弹出5,压入4</td> -</tr> -<tr> -<td>1,4,7</td> -<td>7大于4,压入栈中</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">栈中的元素</th> + <th style="text-align: left">关于元素进出的备注</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">2</td> + <td style="text-align: left">元素2压入栈中</td> + </tr> + <tr> + <td style="text-align: left">2,3</td> + <td style="text-align: left">3大于2,压入栈中</td> + </tr> + <tr> + <td style="text-align: left">1</td> + <td style="text-align: left">1小于3、2,因此全部弹出将1入栈</td> + </tr> + <tr> + <td style="text-align: left">1,5</td> + <td style="text-align: left">5大于1,压入栈中</td> + </tr> + <tr> + <td style="text-align: left">1,4</td> + <td style="text-align: left">4比5小,比1大,弹出5,压入4</td> + </tr> + <tr> + <td style="text-align: left">1,4,7</td> + <td style="text-align: left">7大于4,压入栈中</td> + </tr> + </tbody> </table> <p>根据上述描述不难看出,其实单调栈就是单调队列的半部分,他能完成的任务理论上单调队列都能够完成,但是有些时候不需要麻烦的去维护单调队列只需要维护单调栈即可完成。</p> <h2 id="单调栈的应用">单调栈的应用</h2> diff --git "a/tags/\346\225\260\346\250\241/index.html" "b/tags/\346\225\260\346\250\241/index.html" index 3f5fdb26..f3f696e1 100644 --- "a/tags/\346\225\260\346\250\241/index.html" +++ "b/tags/\346\225\260\346\250\241/index.html" @@ -1,6 +1,6 @@ 数模 | Zs's Blog -

                  利用神经网络进行波士顿房价预测

                  前言 前一阵学校有五一数模节校赛,和朋友一起参加做B题,波士顿房价预测,算是第一次自己动手实现一个简单的小网络吧,虽然很简单,但还是想记录一下。 +

                  利用神经网络进行波士顿房价预测

                  前言 前一阵学校有五一数模节校赛,和朋友一起参加做B题,波士顿房价预测,算是第一次自己动手实现一个简单的小网络吧,虽然很简单,但还是想记录一下。 题目介绍 波士顿住房数据由哈里森和鲁宾菲尔德于1978年Harrison and Rubinfeld1收集。它包括了波士顿大区每个调查行政区的506个观察值。1980年Belsley et al.2曾对此数据做过分析。 数据一共14列,每一列的含义分别如下: 英文简称 详细含义 CRIM 城镇的人均犯罪率 ZN 大于25,000平方英尺的地块的住宅用地比例。 INDUS 每个镇的非零售业务英亩的比例。 CHAS 查尔斯河虚拟变量(如果环河,则等于1;否则等于0) NOX 一氧化氮的浓度(百万分之几) RM 每个住宅的平均房间数 AGE 1940年之前建造的自有住房的比例 DIS 到五个波士顿就业中心的加权距离 RAD 径向公路通达性的指标 TAX 每一万美元的全值财产税率 PTRATIO 各镇的师生比率 B 计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例 LSTAT 底层人口的百分比(%) price 自有住房数的中位数,单位(千美元) 基于上述数据,请完成以下问题: @@ -10,8 +10,9 @@ 建立前馈神经网络模型,根据通用逼近定理,我们可以拟合此回归模型。 我们对上述模型来进行实现并确定评估标准来对他们进行比较,选择最优的模型作为预测模型。 算法流程 传统的回归算法 自变量的选择 首先,考虑到数据集中13列自变量其中某一些可能和最终的房价并无强相关性,如果全部使用进行预测可能会对模型引入噪声,因此我们首先计算了房价price与各个自变量之间的相关系数 $r$ ,其中 $r$ 计算公式如下: $$ r = \frac{\sum(x_i-\bar{x})(y_i-\bar{y})}{\sqrt{\sum(x_i-\bar{x})^2\sum(y_i-\bar{y})^2}} $$ 其中 $x_i,y_i$ 为数据的每个分量,$\bar{x},\bar{y}$ 为数据的均值 -该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下:...

                  May 16, 2021 · 1 min · zzsqwq
                  © 2024 Zs's Blog +该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下: +...

                  May 16, 2021 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/tags/\346\225\260\346\250\241/index.xml" "b/tags/\346\225\260\346\250\241/index.xml" index ffa45603..bb00d417 100644 --- "a/tags/\346\225\260\346\250\241/index.xml" +++ "b/tags/\346\225\260\346\250\241/index.xml" @@ -19,70 +19,70 @@ <p>波士顿住房数据由哈里森和鲁宾菲尔德于1978年Harrison and Rubinfeld<sup><a href="https://blog.zzsqwq.cn/usr/uploads/2021/05/406125417.png">1</a></sup>收集。它包括了波士顿大区每个调查行政区的506个观察值。1980年Belsley et al.<sup><a href="https://blog.zzsqwq.cn/usr/uploads/2021/05/3238192089.png">2</a></sup>曾对此数据做过分析。</p> <p>数据一共14列,每一列的含义分别如下:</p> <table> -<thead> -<tr> -<th>英文简称</th> -<th>详细含义</th> -</tr> -</thead> -<tbody> -<tr> -<td>CRIM</td> -<td>城镇的人均犯罪率</td> -</tr> -<tr> -<td>ZN</td> -<td>大于25,000平方英尺的地块的住宅用地比例。</td> -</tr> -<tr> -<td>INDUS</td> -<td>每个镇的非零售业务英亩的比例。</td> -</tr> -<tr> -<td>CHAS</td> -<td>查尔斯河虚拟变量(如果环河,则等于1;否则等于0)</td> -</tr> -<tr> -<td>NOX</td> -<td>一氧化氮的浓度(百万分之几)</td> -</tr> -<tr> -<td>RM</td> -<td>每个住宅的平均房间数</td> -</tr> -<tr> -<td>AGE</td> -<td>1940年之前建造的自有住房的比例</td> -</tr> -<tr> -<td>DIS</td> -<td>到五个波士顿就业中心的加权距离</td> -</tr> -<tr> -<td>RAD</td> -<td>径向公路通达性的指标</td> -</tr> -<tr> -<td>TAX</td> -<td>每一万美元的全值财产税率</td> -</tr> -<tr> -<td>PTRATIO</td> -<td>各镇的师生比率</td> -</tr> -<tr> -<td>B</td> -<td>计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例</td> -</tr> -<tr> -<td>LSTAT</td> -<td>底层人口的百分比(%)</td> -</tr> -<tr> -<td><strong>price</strong></td> -<td>自有住房数的中位数,单位(千美元)</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">英文简称</th> + <th style="text-align: left">详细含义</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">CRIM</td> + <td style="text-align: left">城镇的人均犯罪率</td> + </tr> + <tr> + <td style="text-align: left">ZN</td> + <td style="text-align: left">大于25,000平方英尺的地块的住宅用地比例。</td> + </tr> + <tr> + <td style="text-align: left">INDUS</td> + <td style="text-align: left">每个镇的非零售业务英亩的比例。</td> + </tr> + <tr> + <td style="text-align: left">CHAS</td> + <td style="text-align: left">查尔斯河虚拟变量(如果环河,则等于1;否则等于0)</td> + </tr> + <tr> + <td style="text-align: left">NOX</td> + <td style="text-align: left">一氧化氮的浓度(百万分之几)</td> + </tr> + <tr> + <td style="text-align: left">RM</td> + <td style="text-align: left">每个住宅的平均房间数</td> + </tr> + <tr> + <td style="text-align: left">AGE</td> + <td style="text-align: left">1940年之前建造的自有住房的比例</td> + </tr> + <tr> + <td style="text-align: left">DIS</td> + <td style="text-align: left">到五个波士顿就业中心的加权距离</td> + </tr> + <tr> + <td style="text-align: left">RAD</td> + <td style="text-align: left">径向公路通达性的指标</td> + </tr> + <tr> + <td style="text-align: left">TAX</td> + <td style="text-align: left">每一万美元的全值财产税率</td> + </tr> + <tr> + <td style="text-align: left">PTRATIO</td> + <td style="text-align: left">各镇的师生比率</td> + </tr> + <tr> + <td style="text-align: left">B</td> + <td style="text-align: left">计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例</td> + </tr> + <tr> + <td style="text-align: left">LSTAT</td> + <td style="text-align: left">底层人口的百分比(%)</td> + </tr> + <tr> + <td style="text-align: left"><strong>price</strong></td> + <td style="text-align: left">自有住房数的中位数,单位(千美元)</td> + </tr> + </tbody> </table> <p>基于上述数据,请完成以下问题:</p> <p><strong>建立波士顿房价预测模型并对预测结果进行评价。</strong></p> @@ -107,46 +107,46 @@ $$ 其中 $x_i,y_i$ 为数据的每个分量,$\bar{x},\bar{y}$ 为数据的均值</p> <p>该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下:</p> <table> -<thead> -<tr> -<th>CRIM</th> -<th>ZN</th> -<th>INDUS</th> -<th>CHAS</th> -<th>NOX</th> -<th>RM</th> -<th>LSTAT</th> -</tr> -</thead> -<tbody> -<tr> -<td>-0.385832</td> -<td>0.360445</td> -<td>-0.483725</td> -<td>0.175260</td> -<td>-0.427321</td> -<td>0.695360</td> -<td>-0.737663</td> -</tr> -<tr> -<td><strong>AGE</strong></td> -<td><strong>DIS</strong></td> -<td><strong>RAD</strong></td> -<td><strong>TAX</strong></td> -<td><strong>PTRATIO</strong></td> -<td><strong>B</strong></td> -<td></td> -</tr> -<tr> -<td>-0.376955</td> -<td>0.249929</td> -<td>-0.381626</td> -<td>-0.468536</td> -<td>-0.507787</td> -<td>0.333461</td> -<td></td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">CRIM</th> + <th style="text-align: left">ZN</th> + <th style="text-align: left">INDUS</th> + <th style="text-align: left">CHAS</th> + <th style="text-align: left">NOX</th> + <th style="text-align: left">RM</th> + <th style="text-align: left">LSTAT</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">-0.385832</td> + <td style="text-align: left">0.360445</td> + <td style="text-align: left">-0.483725</td> + <td style="text-align: left">0.175260</td> + <td style="text-align: left">-0.427321</td> + <td style="text-align: left">0.695360</td> + <td style="text-align: left">-0.737663</td> + </tr> + <tr> + <td style="text-align: left"><strong>AGE</strong></td> + <td style="text-align: left"><strong>DIS</strong></td> + <td style="text-align: left"><strong>RAD</strong></td> + <td style="text-align: left"><strong>TAX</strong></td> + <td style="text-align: left"><strong>PTRATIO</strong></td> + <td style="text-align: left"><strong>B</strong></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">-0.376955</td> + <td style="text-align: left">0.249929</td> + <td style="text-align: left">-0.381626</td> + <td style="text-align: left">-0.468536</td> + <td style="text-align: left">-0.507787</td> + <td style="text-align: left">0.333461</td> + <td style="text-align: left"></td> + </tr> + </tbody> </table> <p>观察结果可以发现,在给定的十三个变量中,<strong>LSTAT <strong>与 <strong>price</strong> 的相关程度最高$(|r|&gt;0.7)$,其次是 <strong>RM</strong> 与</strong>PTRATIO</strong> $(|r|&gt;0.5)$,再者是 <strong>TAX,INDUS,NOX</strong> $(|r|&gt;0.4)$,除上述之外的七个变量都与 <strong>price</strong> 无较强的相关性,因此我们考虑使用六个相关性较强变量和十三个变量分别来对房价进行预测,并对他们进行对比,来寻找最优的回归模型。</p> <h5 id="模型的构建">模型的构建</h5> diff --git "a/tags/\346\235\202\350\260\210/index.html" "b/tags/\346\235\202\350\260\210/index.html" index b98f924a..1473c894 100644 --- "a/tags/\346\235\202\350\260\210/index.html" +++ "b/tags/\346\235\202\350\260\210/index.html" @@ -1,6 +1,6 @@ 杂谈 | Zs's Blog -

                  关于春节期间的一些碎碎念

                  前言 春节期间,走亲访友是必不可少的。交谈的多了,免不得一些问题的讨论。 +

                  关于春节期间的一些碎碎念

                  前言 春节期间,走亲访友是必不可少的。交谈的多了,免不得一些问题的讨论。 读了很多书,经历了很多事,似乎想法也有一些”离经叛道“,记一下自己目前的一些想法,不知道多年后的自己看这篇文章会是什么想法,还会一如既往的坚持吗。 讨论的话题 打点关系 无论是父母,还是各方亲戚,大家好像都喜欢打点关系,以此来获得一些好处。 最常见的是求人办事,很多时候是我们常说的”走后门“,想让孩子上个好点的小学,避免不了又送礼又吃饭。 @@ -44,8 +44,9 @@ 具体导出为 zip 的时候可能会提示损坏,这样的话可以直接去服务器 \tmp\Export2Hugo 下面打包。 安装 hugo 过程基于 Windows 平台,很简单,在 这里 下载 hugo 最新的 release 版本,找到对应自己系统的即可。下载后解压到某个目录下,设置一下环境变量即可。这里牵扯到 hugo 和 hugo_extended 两个版本的区别,以下是某个 issue 中的解释: I agree. -The only functional difference is SASS/SCSS The technical build time difference is that it requires a C++ build chain for the target platform to build, the reason why we currently only build the extended for 3 platforms (Windows, Linux, MacOS) Binaries are slightly less portable as you need a compatible Libc version on your computer (for Windows we build a fully static version as Libc is rather uncommon unless you have Visual Studio or something installed)....

                  December 13, 2021 · 2 min · zzsqwq
                  © 2024 Zs's Blog +The only functional difference is SASS/SCSS The technical build time difference is that it requires a C++ build chain for the target platform to build, the reason why we currently only build the extended for 3 platforms (Windows, Linux, MacOS) Binaries are slightly less portable as you need a compatible Libc version on your computer (for Windows we build a fully static version as Libc is rather uncommon unless you have Visual Studio or something installed). via: Please document the difference between the “extended” and non-“extended” versions +...

                  December 13, 2021 · 2 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/tags/\346\240\221\350\216\223\346\264\276/index.html" "b/tags/\346\240\221\350\216\223\346\264\276/index.html" index 4dd19669..94bbc6b2 100644 --- "a/tags/\346\240\221\350\216\223\346\264\276/index.html" +++ "b/tags/\346\240\221\350\216\223\346\264\276/index.html" @@ -1,6 +1,6 @@ 树莓派 | Zs's Blog -

                  利用树莓派为HP LaserJet 1020配置无线打印功能

                  前言 最近基地的打印机突然又好起来了。 +

                  利用树莓派为HP LaserJet 1020配置无线打印功能

                  前言 最近基地的打印机突然又好起来了。 因为基地的打印机型号比较老——HP LaserJet 1020,没有无线打印的功能。所以之前一位学长1 用树莓派配置了打印机的无线打印功能,但是后来发现有一些问题,有时候发送打印请求树莓派无法接收,而且不知道为何,学长之前用的是树莓派自己创建WiFi,连接对应WiFi才能打印,但是这个显然不是最优的解决办法。 考虑到之间已经配置好基地WiFi,我决定重新配置一下打印功能,使其连接基地WiFi即可实现局域网打印。 配置过程 查看树莓派内容 通过ssh连接树莓派,发现里面除了Github上的一个开源项目create_ap ,就没有什么其他的内容了,连接屏幕后发现没有任何图像信号,无从下手,因此考虑重新刷机。 @@ -14,8 +14,9 @@ $ sudo ifconfig 查看WiFi对应的IP,至此,树莓派可以摆脱屏幕,我们可以使用电脑进行使用 ssh 连接。 这里也可以使用网线进行连接,具体操作如下 用网线连接树莓派和自己的电脑。 -在树莓派的利用 nmtui 选择 Edit a connection ,Add一个Ethernet connect,对IPv4 CONFIGURATION进行设置,首先讲 Automatic 设置为 Manual,设置 Address 为 静态IP 如 192....

                  July 18, 2021 · 2 min · zzsqwq
                  © 2024 Zs's Blog +在树莓派的利用 nmtui 选择 Edit a connection ,Add一个Ethernet connect,对IPv4 CONFIGURATION进行设置,首先讲 Automatic 设置为 Manual,设置 Address 为 静态IP 如 192.168.3.2 ,Gateway 设置为 192.168.3.1 。 +...

                  July 18, 2021 · 2 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/tags/\346\257\224\350\265\233\350\256\260\345\275\225/index.html" "b/tags/\346\257\224\350\265\233\350\256\260\345\275\225/index.html" index ad9564e3..aaa5b9fc 100644 --- "a/tags/\346\257\224\350\265\233\350\256\260\345\275\225/index.html" +++ "b/tags/\346\257\224\350\265\233\350\256\260\345\275\225/index.html" @@ -1,6 +1,6 @@ 比赛记录 | Zs's Blog -

                  2021RoboMaster中国赛比赛记录

                  前言 ​说起来的话今天距离比赛已经过去近一个月了,比赛结束一直想要记录一下and总结一下经验,但是实在是太懒了,临近五一假期,在四月的末尾为这次中国赛画一个句号吧。 +

                  2021RoboMaster中国赛比赛记录

                  前言 ​说起来的话今天距离比赛已经过去近一个月了,比赛结束一直想要记录一下and总结一下经验,但是实在是太懒了,临近五一假期,在四月的末尾为这次中国赛画一个句号吧。 比赛过程 ​如果没记错的话比赛是3.30号(周二)去,4.1号(周四)结束,共三天。但是因为第三天没做什么有意义的事情,就只记录两天了。 第一天 ​第一天大概中午十点到的吧,去的时候登记完领了牌,就在当地布置场地了。到了场地上才发现,我们好像是拿的东西最多的,包括外接显示屏和集成主机,好像都基本没人带过去····集成主机拿了过去也没怎么用到,本来预想用到的哨岗相机因为 ROS 的通信问题也没能跑成,最后两个机器人还是各跑各的策略了。 ​调试的时候出了一点问题,两个哨岗相机通过20m的USB延长线后,只有一个能连接,后来排查了一下,好像是因为有一条线是光纤USB3.0的线,跟相机的接口不兼容···这个问题还没想好怎么解决,可能会考虑到时候自己带一根USB延长线过去。 @@ -15,5 +15,5 @@ 最后,这一天还拿到了和Charm young的合照,还挺动容的,之前看Robomaster的一个宣传标语就是让工程师们成为明星,给他们一个展示的舞台,看到大家对Charm young的热情,深深的感受到了这一点。

                  April 30, 2021 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/tags/\346\267\261\345\272\246\345\255\246\344\271\240/index.html" "b/tags/\346\267\261\345\272\246\345\255\246\344\271\240/index.html" index 143f0ac5..148d47e2 100644 --- "a/tags/\346\267\261\345\272\246\345\255\246\344\271\240/index.html" +++ "b/tags/\346\267\261\345\272\246\345\255\246\344\271\240/index.html" @@ -1,6 +1,6 @@ 深度学习 | Zs's Blog -

                  利用神经网络进行波士顿房价预测

                  前言 前一阵学校有五一数模节校赛,和朋友一起参加做B题,波士顿房价预测,算是第一次自己动手实现一个简单的小网络吧,虽然很简单,但还是想记录一下。 +

                  利用神经网络进行波士顿房价预测

                  前言 前一阵学校有五一数模节校赛,和朋友一起参加做B题,波士顿房价预测,算是第一次自己动手实现一个简单的小网络吧,虽然很简单,但还是想记录一下。 题目介绍 波士顿住房数据由哈里森和鲁宾菲尔德于1978年Harrison and Rubinfeld1收集。它包括了波士顿大区每个调查行政区的506个观察值。1980年Belsley et al.2曾对此数据做过分析。 数据一共14列,每一列的含义分别如下: 英文简称 详细含义 CRIM 城镇的人均犯罪率 ZN 大于25,000平方英尺的地块的住宅用地比例。 INDUS 每个镇的非零售业务英亩的比例。 CHAS 查尔斯河虚拟变量(如果环河,则等于1;否则等于0) NOX 一氧化氮的浓度(百万分之几) RM 每个住宅的平均房间数 AGE 1940年之前建造的自有住房的比例 DIS 到五个波士顿就业中心的加权距离 RAD 径向公路通达性的指标 TAX 每一万美元的全值财产税率 PTRATIO 各镇的师生比率 B 计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例 LSTAT 底层人口的百分比(%) price 自有住房数的中位数,单位(千美元) 基于上述数据,请完成以下问题: @@ -10,8 +10,9 @@ 建立前馈神经网络模型,根据通用逼近定理,我们可以拟合此回归模型。 我们对上述模型来进行实现并确定评估标准来对他们进行比较,选择最优的模型作为预测模型。 算法流程 传统的回归算法 自变量的选择 首先,考虑到数据集中13列自变量其中某一些可能和最终的房价并无强相关性,如果全部使用进行预测可能会对模型引入噪声,因此我们首先计算了房价price与各个自变量之间的相关系数 $r$ ,其中 $r$ 计算公式如下: $$ r = \frac{\sum(x_i-\bar{x})(y_i-\bar{y})}{\sqrt{\sum(x_i-\bar{x})^2\sum(y_i-\bar{y})^2}} $$ 其中 $x_i,y_i$ 为数据的每个分量,$\bar{x},\bar{y}$ 为数据的均值 -该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下:...

                  May 16, 2021 · 1 min · zzsqwq
                  © 2024 Zs's Blog +该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下: +...

                  May 16, 2021 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/tags/\346\267\261\345\272\246\345\255\246\344\271\240/index.xml" "b/tags/\346\267\261\345\272\246\345\255\246\344\271\240/index.xml" index 4bc05c73..37e09739 100644 --- "a/tags/\346\267\261\345\272\246\345\255\246\344\271\240/index.xml" +++ "b/tags/\346\267\261\345\272\246\345\255\246\344\271\240/index.xml" @@ -19,70 +19,70 @@ <p>波士顿住房数据由哈里森和鲁宾菲尔德于1978年Harrison and Rubinfeld<sup><a href="https://blog.zzsqwq.cn/usr/uploads/2021/05/406125417.png">1</a></sup>收集。它包括了波士顿大区每个调查行政区的506个观察值。1980年Belsley et al.<sup><a href="https://blog.zzsqwq.cn/usr/uploads/2021/05/3238192089.png">2</a></sup>曾对此数据做过分析。</p> <p>数据一共14列,每一列的含义分别如下:</p> <table> -<thead> -<tr> -<th>英文简称</th> -<th>详细含义</th> -</tr> -</thead> -<tbody> -<tr> -<td>CRIM</td> -<td>城镇的人均犯罪率</td> -</tr> -<tr> -<td>ZN</td> -<td>大于25,000平方英尺的地块的住宅用地比例。</td> -</tr> -<tr> -<td>INDUS</td> -<td>每个镇的非零售业务英亩的比例。</td> -</tr> -<tr> -<td>CHAS</td> -<td>查尔斯河虚拟变量(如果环河,则等于1;否则等于0)</td> -</tr> -<tr> -<td>NOX</td> -<td>一氧化氮的浓度(百万分之几)</td> -</tr> -<tr> -<td>RM</td> -<td>每个住宅的平均房间数</td> -</tr> -<tr> -<td>AGE</td> -<td>1940年之前建造的自有住房的比例</td> -</tr> -<tr> -<td>DIS</td> -<td>到五个波士顿就业中心的加权距离</td> -</tr> -<tr> -<td>RAD</td> -<td>径向公路通达性的指标</td> -</tr> -<tr> -<td>TAX</td> -<td>每一万美元的全值财产税率</td> -</tr> -<tr> -<td>PTRATIO</td> -<td>各镇的师生比率</td> -</tr> -<tr> -<td>B</td> -<td>计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例</td> -</tr> -<tr> -<td>LSTAT</td> -<td>底层人口的百分比(%)</td> -</tr> -<tr> -<td><strong>price</strong></td> -<td>自有住房数的中位数,单位(千美元)</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">英文简称</th> + <th style="text-align: left">详细含义</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">CRIM</td> + <td style="text-align: left">城镇的人均犯罪率</td> + </tr> + <tr> + <td style="text-align: left">ZN</td> + <td style="text-align: left">大于25,000平方英尺的地块的住宅用地比例。</td> + </tr> + <tr> + <td style="text-align: left">INDUS</td> + <td style="text-align: left">每个镇的非零售业务英亩的比例。</td> + </tr> + <tr> + <td style="text-align: left">CHAS</td> + <td style="text-align: left">查尔斯河虚拟变量(如果环河,则等于1;否则等于0)</td> + </tr> + <tr> + <td style="text-align: left">NOX</td> + <td style="text-align: left">一氧化氮的浓度(百万分之几)</td> + </tr> + <tr> + <td style="text-align: left">RM</td> + <td style="text-align: left">每个住宅的平均房间数</td> + </tr> + <tr> + <td style="text-align: left">AGE</td> + <td style="text-align: left">1940年之前建造的自有住房的比例</td> + </tr> + <tr> + <td style="text-align: left">DIS</td> + <td style="text-align: left">到五个波士顿就业中心的加权距离</td> + </tr> + <tr> + <td style="text-align: left">RAD</td> + <td style="text-align: left">径向公路通达性的指标</td> + </tr> + <tr> + <td style="text-align: left">TAX</td> + <td style="text-align: left">每一万美元的全值财产税率</td> + </tr> + <tr> + <td style="text-align: left">PTRATIO</td> + <td style="text-align: left">各镇的师生比率</td> + </tr> + <tr> + <td style="text-align: left">B</td> + <td style="text-align: left">计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例</td> + </tr> + <tr> + <td style="text-align: left">LSTAT</td> + <td style="text-align: left">底层人口的百分比(%)</td> + </tr> + <tr> + <td style="text-align: left"><strong>price</strong></td> + <td style="text-align: left">自有住房数的中位数,单位(千美元)</td> + </tr> + </tbody> </table> <p>基于上述数据,请完成以下问题:</p> <p><strong>建立波士顿房价预测模型并对预测结果进行评价。</strong></p> @@ -107,46 +107,46 @@ $$ 其中 $x_i,y_i$ 为数据的每个分量,$\bar{x},\bar{y}$ 为数据的均值</p> <p>该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下:</p> <table> -<thead> -<tr> -<th>CRIM</th> -<th>ZN</th> -<th>INDUS</th> -<th>CHAS</th> -<th>NOX</th> -<th>RM</th> -<th>LSTAT</th> -</tr> -</thead> -<tbody> -<tr> -<td>-0.385832</td> -<td>0.360445</td> -<td>-0.483725</td> -<td>0.175260</td> -<td>-0.427321</td> -<td>0.695360</td> -<td>-0.737663</td> -</tr> -<tr> -<td><strong>AGE</strong></td> -<td><strong>DIS</strong></td> -<td><strong>RAD</strong></td> -<td><strong>TAX</strong></td> -<td><strong>PTRATIO</strong></td> -<td><strong>B</strong></td> -<td></td> -</tr> -<tr> -<td>-0.376955</td> -<td>0.249929</td> -<td>-0.381626</td> -<td>-0.468536</td> -<td>-0.507787</td> -<td>0.333461</td> -<td></td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">CRIM</th> + <th style="text-align: left">ZN</th> + <th style="text-align: left">INDUS</th> + <th style="text-align: left">CHAS</th> + <th style="text-align: left">NOX</th> + <th style="text-align: left">RM</th> + <th style="text-align: left">LSTAT</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">-0.385832</td> + <td style="text-align: left">0.360445</td> + <td style="text-align: left">-0.483725</td> + <td style="text-align: left">0.175260</td> + <td style="text-align: left">-0.427321</td> + <td style="text-align: left">0.695360</td> + <td style="text-align: left">-0.737663</td> + </tr> + <tr> + <td style="text-align: left"><strong>AGE</strong></td> + <td style="text-align: left"><strong>DIS</strong></td> + <td style="text-align: left"><strong>RAD</strong></td> + <td style="text-align: left"><strong>TAX</strong></td> + <td style="text-align: left"><strong>PTRATIO</strong></td> + <td style="text-align: left"><strong>B</strong></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">-0.376955</td> + <td style="text-align: left">0.249929</td> + <td style="text-align: left">-0.381626</td> + <td style="text-align: left">-0.468536</td> + <td style="text-align: left">-0.507787</td> + <td style="text-align: left">0.333461</td> + <td style="text-align: left"></td> + </tr> + </tbody> </table> <p>观察结果可以发现,在给定的十三个变量中,<strong>LSTAT <strong>与 <strong>price</strong> 的相关程度最高$(|r|&gt;0.7)$,其次是 <strong>RM</strong> 与</strong>PTRATIO</strong> $(|r|&gt;0.5)$,再者是 <strong>TAX,INDUS,NOX</strong> $(|r|&gt;0.4)$,除上述之外的七个变量都与 <strong>price</strong> 无较强的相关性,因此我们考虑使用六个相关性较强变量和十三个变量分别来对房价进行预测,并对他们进行对比,来寻找最优的回归模型。</p> <h5 id="模型的构建">模型的构建</h5> diff --git "a/tags/\347\245\236\347\273\217\347\275\221\347\273\234/index.html" "b/tags/\347\245\236\347\273\217\347\275\221\347\273\234/index.html" index 7e17c15b..c008d9a2 100644 --- "a/tags/\347\245\236\347\273\217\347\275\221\347\273\234/index.html" +++ "b/tags/\347\245\236\347\273\217\347\275\221\347\273\234/index.html" @@ -1,6 +1,6 @@ 神经网络 | Zs's Blog -

                  利用神经网络进行波士顿房价预测

                  前言 前一阵学校有五一数模节校赛,和朋友一起参加做B题,波士顿房价预测,算是第一次自己动手实现一个简单的小网络吧,虽然很简单,但还是想记录一下。 +

                  利用神经网络进行波士顿房价预测

                  前言 前一阵学校有五一数模节校赛,和朋友一起参加做B题,波士顿房价预测,算是第一次自己动手实现一个简单的小网络吧,虽然很简单,但还是想记录一下。 题目介绍 波士顿住房数据由哈里森和鲁宾菲尔德于1978年Harrison and Rubinfeld1收集。它包括了波士顿大区每个调查行政区的506个观察值。1980年Belsley et al.2曾对此数据做过分析。 数据一共14列,每一列的含义分别如下: 英文简称 详细含义 CRIM 城镇的人均犯罪率 ZN 大于25,000平方英尺的地块的住宅用地比例。 INDUS 每个镇的非零售业务英亩的比例。 CHAS 查尔斯河虚拟变量(如果环河,则等于1;否则等于0) NOX 一氧化氮的浓度(百万分之几) RM 每个住宅的平均房间数 AGE 1940年之前建造的自有住房的比例 DIS 到五个波士顿就业中心的加权距离 RAD 径向公路通达性的指标 TAX 每一万美元的全值财产税率 PTRATIO 各镇的师生比率 B 计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例 LSTAT 底层人口的百分比(%) price 自有住房数的中位数,单位(千美元) 基于上述数据,请完成以下问题: @@ -10,7 +10,8 @@ 建立前馈神经网络模型,根据通用逼近定理,我们可以拟合此回归模型。 我们对上述模型来进行实现并确定评估标准来对他们进行比较,选择最优的模型作为预测模型。 算法流程 传统的回归算法 自变量的选择 首先,考虑到数据集中13列自变量其中某一些可能和最终的房价并无强相关性,如果全部使用进行预测可能会对模型引入噪声,因此我们首先计算了房价price与各个自变量之间的相关系数 $r$ ,其中 $r$ 计算公式如下: $$ r = \frac{\sum(x_i-\bar{x})(y_i-\bar{y})}{\sqrt{\sum(x_i-\bar{x})^2\sum(y_i-\bar{y})^2}} $$ 其中 $x_i,y_i$ 为数据的每个分量,$\bar{x},\bar{y}$ 为数据的均值 -该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下:...

                  May 16, 2021 · 1 min · zzsqwq

                  如何使用CenterNet做3D目标检测测试

                  CenterNet—Objects as Points介绍 ​CenterNet是一个anchor-free的目标检测网络,与YOLOv3相比,精度有所提升,此外他不仅能够用于2D目标检测,也能够用于人体姿态识别,3D目标检测等··· +该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下: +...

                  May 16, 2021 · 1 min · zzsqwq

                  如何使用CenterNet做3D目标检测测试

                  CenterNet—Objects as Points介绍 ​CenterNet是一个anchor-free的目标检测网络,与YOLOv3相比,精度有所提升,此外他不仅能够用于2D目标检测,也能够用于人体姿态识别,3D目标检测等··· 安装CenterNet ​其实安装CenterNet的过程就是一个配置环境的问题,直接跟着官方给出的这里Install.md配置一下即可,十分推荐使用Conda来管理环境,这里给出我的环境给大家参考一下: Ubuntu = 18.04 LTS pytorch = 1.2.0 @@ -23,8 +24,12 @@ python demo.py ctdet --demo ${CenterNet_Root}/images/17790319373_bd19b24cfc_k.jpg --load_model ../models/ctdet_coco_dla_2x.pth ​这里需要注意的是 --demo 后面的 ${CenterNet_Root}/images/17790319373_bd19b24cfc_k.jpg ,这里我使用的是官方给出的实例图片,它位于CenterNet根目录的images文件夹中,前面的 ${CenterNet_Root} 代表的是 CenterNet根目录,好比我的就位于 /home/zs/CenterNet 。 ​如果不出意外的话效果应该如下图所示: 运行CenterNet的3D目标检测 配置数据集和模型 ​我们可以直接参考官方的 DATA.md 来配置我们的数据集。 -​然后到 Model zoo 下载3D检测使用的模型 ddd_3dop....

                  January 27, 2021 · 2 min · zzsqwq
                  © 2024 Zs's Blog +​然后到 Model zoo 下载3D检测使用的模型 ddd_3dop.pth 。 +​这里说一下遇到的几个坑: +首先是配置数据集的过程中,我们需要配置的目录结构如图所示(官方给出的结构树有点模糊不清的感觉) +. ├── ImageSets_3dop │ ├── test.txt │ ├── train.txt │ ├── trainval.txt │ └── val.txt ├── ImageSets_subcnn │ ├── test.txt │ ├── train.txt │ ├── trainval.txt │ └── val.txt └── training ├── calib ├── image_2 └── label_2 然后去到 ${CenterNet_ROOT}/src/tools目录下,运行 python convert_kitti_to_coco.py 将 kitti 数据集转换为 coco 数据集的格式,不出意外应该会报错如下: +...

                  January 27, 2021 · 2 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/tags/\347\245\236\347\273\217\347\275\221\347\273\234/index.xml" "b/tags/\347\245\236\347\273\217\347\275\221\347\273\234/index.xml" index afb03ec3..63254f95 100644 --- "a/tags/\347\245\236\347\273\217\347\275\221\347\273\234/index.xml" +++ "b/tags/\347\245\236\347\273\217\347\275\221\347\273\234/index.xml" @@ -19,70 +19,70 @@ <p>波士顿住房数据由哈里森和鲁宾菲尔德于1978年Harrison and Rubinfeld<sup><a href="https://blog.zzsqwq.cn/usr/uploads/2021/05/406125417.png">1</a></sup>收集。它包括了波士顿大区每个调查行政区的506个观察值。1980年Belsley et al.<sup><a href="https://blog.zzsqwq.cn/usr/uploads/2021/05/3238192089.png">2</a></sup>曾对此数据做过分析。</p> <p>数据一共14列,每一列的含义分别如下:</p> <table> -<thead> -<tr> -<th>英文简称</th> -<th>详细含义</th> -</tr> -</thead> -<tbody> -<tr> -<td>CRIM</td> -<td>城镇的人均犯罪率</td> -</tr> -<tr> -<td>ZN</td> -<td>大于25,000平方英尺的地块的住宅用地比例。</td> -</tr> -<tr> -<td>INDUS</td> -<td>每个镇的非零售业务英亩的比例。</td> -</tr> -<tr> -<td>CHAS</td> -<td>查尔斯河虚拟变量(如果环河,则等于1;否则等于0)</td> -</tr> -<tr> -<td>NOX</td> -<td>一氧化氮的浓度(百万分之几)</td> -</tr> -<tr> -<td>RM</td> -<td>每个住宅的平均房间数</td> -</tr> -<tr> -<td>AGE</td> -<td>1940年之前建造的自有住房的比例</td> -</tr> -<tr> -<td>DIS</td> -<td>到五个波士顿就业中心的加权距离</td> -</tr> -<tr> -<td>RAD</td> -<td>径向公路通达性的指标</td> -</tr> -<tr> -<td>TAX</td> -<td>每一万美元的全值财产税率</td> -</tr> -<tr> -<td>PTRATIO</td> -<td>各镇的师生比率</td> -</tr> -<tr> -<td>B</td> -<td>计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例</td> -</tr> -<tr> -<td>LSTAT</td> -<td>底层人口的百分比(%)</td> -</tr> -<tr> -<td><strong>price</strong></td> -<td>自有住房数的中位数,单位(千美元)</td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">英文简称</th> + <th style="text-align: left">详细含义</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">CRIM</td> + <td style="text-align: left">城镇的人均犯罪率</td> + </tr> + <tr> + <td style="text-align: left">ZN</td> + <td style="text-align: left">大于25,000平方英尺的地块的住宅用地比例。</td> + </tr> + <tr> + <td style="text-align: left">INDUS</td> + <td style="text-align: left">每个镇的非零售业务英亩的比例。</td> + </tr> + <tr> + <td style="text-align: left">CHAS</td> + <td style="text-align: left">查尔斯河虚拟变量(如果环河,则等于1;否则等于0)</td> + </tr> + <tr> + <td style="text-align: left">NOX</td> + <td style="text-align: left">一氧化氮的浓度(百万分之几)</td> + </tr> + <tr> + <td style="text-align: left">RM</td> + <td style="text-align: left">每个住宅的平均房间数</td> + </tr> + <tr> + <td style="text-align: left">AGE</td> + <td style="text-align: left">1940年之前建造的自有住房的比例</td> + </tr> + <tr> + <td style="text-align: left">DIS</td> + <td style="text-align: left">到五个波士顿就业中心的加权距离</td> + </tr> + <tr> + <td style="text-align: left">RAD</td> + <td style="text-align: left">径向公路通达性的指标</td> + </tr> + <tr> + <td style="text-align: left">TAX</td> + <td style="text-align: left">每一万美元的全值财产税率</td> + </tr> + <tr> + <td style="text-align: left">PTRATIO</td> + <td style="text-align: left">各镇的师生比率</td> + </tr> + <tr> + <td style="text-align: left">B</td> + <td style="text-align: left">计算方法为 $1000(B_k-0.63)^2$,其中Bk是按城镇划分的非裔美国人的比例</td> + </tr> + <tr> + <td style="text-align: left">LSTAT</td> + <td style="text-align: left">底层人口的百分比(%)</td> + </tr> + <tr> + <td style="text-align: left"><strong>price</strong></td> + <td style="text-align: left">自有住房数的中位数,单位(千美元)</td> + </tr> + </tbody> </table> <p>基于上述数据,请完成以下问题:</p> <p><strong>建立波士顿房价预测模型并对预测结果进行评价。</strong></p> @@ -107,46 +107,46 @@ $$ 其中 $x_i,y_i$ 为数据的每个分量,$\bar{x},\bar{y}$ 为数据的均值</p> <p>该系数反映了两变量之间的相关性,$r$ 的绝对值介于 $[0,1]$ 区间内,$|r|$ 越接近1,表示两数据相关性越高,反之越低。计算后结果如下:</p> <table> -<thead> -<tr> -<th>CRIM</th> -<th>ZN</th> -<th>INDUS</th> -<th>CHAS</th> -<th>NOX</th> -<th>RM</th> -<th>LSTAT</th> -</tr> -</thead> -<tbody> -<tr> -<td>-0.385832</td> -<td>0.360445</td> -<td>-0.483725</td> -<td>0.175260</td> -<td>-0.427321</td> -<td>0.695360</td> -<td>-0.737663</td> -</tr> -<tr> -<td><strong>AGE</strong></td> -<td><strong>DIS</strong></td> -<td><strong>RAD</strong></td> -<td><strong>TAX</strong></td> -<td><strong>PTRATIO</strong></td> -<td><strong>B</strong></td> -<td></td> -</tr> -<tr> -<td>-0.376955</td> -<td>0.249929</td> -<td>-0.381626</td> -<td>-0.468536</td> -<td>-0.507787</td> -<td>0.333461</td> -<td></td> -</tr> -</tbody> + <thead> + <tr> + <th style="text-align: left">CRIM</th> + <th style="text-align: left">ZN</th> + <th style="text-align: left">INDUS</th> + <th style="text-align: left">CHAS</th> + <th style="text-align: left">NOX</th> + <th style="text-align: left">RM</th> + <th style="text-align: left">LSTAT</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left">-0.385832</td> + <td style="text-align: left">0.360445</td> + <td style="text-align: left">-0.483725</td> + <td style="text-align: left">0.175260</td> + <td style="text-align: left">-0.427321</td> + <td style="text-align: left">0.695360</td> + <td style="text-align: left">-0.737663</td> + </tr> + <tr> + <td style="text-align: left"><strong>AGE</strong></td> + <td style="text-align: left"><strong>DIS</strong></td> + <td style="text-align: left"><strong>RAD</strong></td> + <td style="text-align: left"><strong>TAX</strong></td> + <td style="text-align: left"><strong>PTRATIO</strong></td> + <td style="text-align: left"><strong>B</strong></td> + <td style="text-align: left"></td> + </tr> + <tr> + <td style="text-align: left">-0.376955</td> + <td style="text-align: left">0.249929</td> + <td style="text-align: left">-0.381626</td> + <td style="text-align: left">-0.468536</td> + <td style="text-align: left">-0.507787</td> + <td style="text-align: left">0.333461</td> + <td style="text-align: left"></td> + </tr> + </tbody> </table> <p>观察结果可以发现,在给定的十三个变量中,<strong>LSTAT <strong>与 <strong>price</strong> 的相关程度最高$(|r|&gt;0.7)$,其次是 <strong>RM</strong> 与</strong>PTRATIO</strong> $(|r|&gt;0.5)$,再者是 <strong>TAX,INDUS,NOX</strong> $(|r|&gt;0.4)$,除上述之外的七个变量都与 <strong>price</strong> 无较强的相关性,因此我们考虑使用六个相关性较强变量和十三个变量分别来对房价进行预测,并对他们进行对比,来寻找最优的回归模型。</p> <h5 id="模型的构建">模型的构建</h5> diff --git "a/tags/\347\250\213\345\272\217\346\230\237/index.html" "b/tags/\347\250\213\345\272\217\346\230\237/index.html" index 7b759abf..2db665ec 100644 --- "a/tags/\347\250\213\345\272\217\346\230\237/index.html" +++ "b/tags/\347\250\213\345\272\217\346\230\237/index.html" @@ -1,14 +1,15 @@ 程序星 | Zs's Blog -

                  “程序星编程之路”第二次作业题解

                  “程序星编程之路”第二次作业题解 A. Zs的回文质数 题目描述 读入一个整数 $n$ ,输出 $[1,n]$ 的所有回文质数,我们规定 $1\sim9$ 也是回文数。 +

                  “程序星编程之路”第二次作业题解

                  “程序星编程之路”第二次作业题解 A. Zs的回文质数 题目描述 读入一个整数 $n$ ,输出 $[1,n]$ 的所有回文质数,我们规定 $1\sim9$ 也是回文数。 思路 首先我们需要了解什么是回文数,以及什么是质数。 简单点说,回文数就是正着读反着读都是一样的,也就是对称的,形如 $abcba $ 或者 $123321$ 这样的。 质数的话,对于一个数 $n$ ,如果他是质数,那它除了 $1$ 和 $n$ 没有其他因子。例如 $2,3,5,7,11$ 这样的。 那么接下来我们考虑一下解决这个问题应该怎么做,首先我们看一下数据范围,$[1,100000]$ ,还是挺小的,我们可以考虑直接枚举每一个数来判断它是不是回文数,然后再判断一下是不是质数,如果两个都满足,我们就输出它。 判断回文数,我们可以考虑到 NOJ05 幸运数 一题的解题思路,也就是说我们把一个数倒置过来,好比一个数 $xyz$ 倒置成 $zyx$ ,然后判断是否 $xyz == zyx$ ,如果相等的话就是回文数,如果不相等就不是。 判断质数,我们可以在 $[2,\lfloor\sqrt{n}\rfloor]$ 枚举它的因子,这个的完备性我上课的时候证明过,不再赘述。这里需要注意 $1,2$ 需要特判一下。 -代码 #include<stdio.h> #include<math.h> //我们需要用到sqrt函数,因此需要引入数学库 int main() { int n; bool flag = false; // 标记 i 是否满足条件 scanf("%d",&n); for(int i=1;i<=n;i++) { flag = true; int p=i,j=0; while(p) // 将 p 反转为 j { j=j*10+p%10; p/=10; } if(j==i) { if(j==1) continue; // 特判 1 if(j==2) // 特判 2 { printf("2\n"); continue; } int sqrtj = sqrt(j); for(int k=2;k<=sqrtj;k++) // 枚举 [2,sqrt(n)] { if(j%k==0) // 如果能够整除(余数为0),那么是 j 的因子 { flag = false; break; } } if(flag) { printf("%d\n",j); } } } } 其他 因为我们讲到这里的时候,我们没讲函数,但是这道题如果我们把判断是否为回文数,判断是否为质数,都另成一个函数模块,将使得程序变得更加简洁。我在这里也将函数版本的贴出来,有兴趣的可以看一下。...

                  November 12, 2020 · 3 min · zzsqwq
                  © 2024 Zs's Blog +代码 #include<stdio.h> #include<math.h> //我们需要用到sqrt函数,因此需要引入数学库 int main() { int n; bool flag = false; // 标记 i 是否满足条件 scanf("%d",&n); for(int i=1;i<=n;i++) { flag = true; int p=i,j=0; while(p) // 将 p 反转为 j { j=j*10+p%10; p/=10; } if(j==i) { if(j==1) continue; // 特判 1 if(j==2) // 特判 2 { printf("2\n"); continue; } int sqrtj = sqrt(j); for(int k=2;k<=sqrtj;k++) // 枚举 [2,sqrt(n)] { if(j%k==0) // 如果能够整除(余数为0),那么是 j 的因子 { flag = false; break; } } if(flag) { printf("%d\n",j); } } } } 其他 因为我们讲到这里的时候,我们没讲函数,但是这道题如果我们把判断是否为回文数,判断是否为质数,都另成一个函数模块,将使得程序变得更加简洁。我在这里也将函数版本的贴出来,有兴趣的可以看一下。 +...

                  November 12, 2020 · 3 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/tags/\350\203\214\345\214\205/index.html" "b/tags/\350\203\214\345\214\205/index.html" index 2af7add9..e5c9ccdc 100644 --- "a/tags/\350\203\214\345\214\205/index.html" +++ "b/tags/\350\203\214\345\214\205/index.html" @@ -1,10 +1,10 @@ 背包 | Zs's Blog -

                  背包进阶

                  1. 分组背包 题意 在01背包基础上,将其中的物体分成 $k$ 组,每组内的物品相互冲突,即只能取其中一个,问最大价值。 +

                  背包进阶

                  1. 分组背包 题意 在01背包基础上,将其中的物体分成 $k$ 组,每组内的物品相互冲突,即只能取其中一个,问最大价值。 ...

                  February 9, 2020 · 2 min · zzsqwq

                  一些关于背包的题

                  前言 今天跟着背包九讲把背包再学习一下,dd_engi大佬的背包九讲Github链接: 背包九讲 1. 采药(01背包) 题意 有 $n$ 个价值为 $w_i$ ,体积为 $v_i$ 的物品,装入体积为 $V$ 的背包中,问能获得的最大为多少。 ...

                  February 8, 2020 · 2 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/tags/\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/index.html" "b/tags/\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/index.html" index 7c63d162..0eef83f3 100644 --- "a/tags/\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/index.html" +++ "b/tags/\350\256\241\347\256\227\346\234\272\350\247\206\350\247\211/index.html" @@ -1,6 +1,6 @@ 计算机视觉 | Zs's Blog -

                  2021RoboMaster中国赛比赛记录

                  前言 ​说起来的话今天距离比赛已经过去近一个月了,比赛结束一直想要记录一下and总结一下经验,但是实在是太懒了,临近五一假期,在四月的末尾为这次中国赛画一个句号吧。 +

                  2021RoboMaster中国赛比赛记录

                  前言 ​说起来的话今天距离比赛已经过去近一个月了,比赛结束一直想要记录一下and总结一下经验,但是实在是太懒了,临近五一假期,在四月的末尾为这次中国赛画一个句号吧。 比赛过程 ​如果没记错的话比赛是3.30号(周二)去,4.1号(周四)结束,共三天。但是因为第三天没做什么有意义的事情,就只记录两天了。 第一天 ​第一天大概中午十点到的吧,去的时候登记完领了牌,就在当地布置场地了。到了场地上才发现,我们好像是拿的东西最多的,包括外接显示屏和集成主机,好像都基本没人带过去····集成主机拿了过去也没怎么用到,本来预想用到的哨岗相机因为 ROS 的通信问题也没能跑成,最后两个机器人还是各跑各的策略了。 ​调试的时候出了一点问题,两个哨岗相机通过20m的USB延长线后,只有一个能连接,后来排查了一下,好像是因为有一条线是光纤USB3.0的线,跟相机的接口不兼容···这个问题还没想好怎么解决,可能会考虑到时候自己带一根USB延长线过去。 @@ -15,5 +15,5 @@ 最后,这一天还拿到了和Charm young的合照,还挺动容的,之前看Robomaster的一个宣传标语就是让工程师们成为明星,给他们一个展示的舞台,看到大家对Charm young的热情,深深的感受到了这一点。

                  April 30, 2021 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/tags/\350\266\263\345\237\272/index.html" "b/tags/\350\266\263\345\237\272/index.html" index 31d11a21..d4cbb894 100644 --- "a/tags/\350\266\263\345\237\272/index.html" +++ "b/tags/\350\266\263\345\237\272/index.html" @@ -1,6 +1,6 @@ 足基 | Zs's Blog -

                  2021RoboMaster中国赛比赛记录

                  前言 ​说起来的话今天距离比赛已经过去近一个月了,比赛结束一直想要记录一下and总结一下经验,但是实在是太懒了,临近五一假期,在四月的末尾为这次中国赛画一个句号吧。 +

                  2021RoboMaster中国赛比赛记录

                  前言 ​说起来的话今天距离比赛已经过去近一个月了,比赛结束一直想要记录一下and总结一下经验,但是实在是太懒了,临近五一假期,在四月的末尾为这次中国赛画一个句号吧。 比赛过程 ​如果没记错的话比赛是3.30号(周二)去,4.1号(周四)结束,共三天。但是因为第三天没做什么有意义的事情,就只记录两天了。 第一天 ​第一天大概中午十点到的吧,去的时候登记完领了牌,就在当地布置场地了。到了场地上才发现,我们好像是拿的东西最多的,包括外接显示屏和集成主机,好像都基本没人带过去····集成主机拿了过去也没怎么用到,本来预想用到的哨岗相机因为 ROS 的通信问题也没能跑成,最后两个机器人还是各跑各的策略了。 ​调试的时候出了一点问题,两个哨岗相机通过20m的USB延长线后,只有一个能连接,后来排查了一下,好像是因为有一条线是光纤USB3.0的线,跟相机的接口不兼容···这个问题还没想好怎么解决,可能会考虑到时候自己带一根USB延长线过去。 @@ -15,5 +15,5 @@ 最后,这一天还拿到了和Charm young的合照,还挺动容的,之前看Robomaster的一个宣传标语就是让工程师们成为明星,给他们一个展示的舞台,看到大家对Charm young的热情,深深的感受到了这一点。

                  April 30, 2021 · 1 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file diff --git "a/tags/\351\224\220\347\202\254/index.html" "b/tags/\351\224\220\347\202\254/index.html" index 0751673f..9c1fb6a6 100644 --- "a/tags/\351\224\220\347\202\254/index.html" +++ "b/tags/\351\224\220\347\202\254/index.html" @@ -1,6 +1,6 @@ 锐炬 | Zs's Blog -

                  2021版小新Pro14 Ubuntu 20.04 配置指南

                  2021版小新Pro14 Ubuntu 20.04 配置指南 补充 最近重装了 Ubuntu 20.04,又找了相关的一些帖子,发现 聯想Yoga 14s 2021款裝機小記 中提到了下文中提到的屏幕闪烁的问题,解决办法是:只需要在内核参数中加入 i915.enable_psr=0 即可。 +

                  2021版小新Pro14 Ubuntu 20.04 配置指南

                  2021版小新Pro14 Ubuntu 20.04 配置指南 补充 最近重装了 Ubuntu 20.04,又找了相关的一些帖子,发现 聯想Yoga 14s 2021款裝機小記 中提到了下文中提到的屏幕闪烁的问题,解决办法是:只需要在内核参数中加入 i915.enable_psr=0 即可。 具体操作步骤如下: $ sudo vim /etc/default/grub 在 GRUB_CMDLINE_LINUX_DEFAULT 这一行的最后添加 i915.enable_psr=0,保存后终端运行: $ sudo update-grub 然后重启即可。 @@ -8,8 +8,9 @@ CPU:酷睿 i5-11300H 显卡:集成显卡 Intel 锐炬Iris Xe 内存:16G 外存:512 SSD 屏幕:分辨率 2880x1800、400nits、100%sRGB 这里需要注意的是,不同时间出的小新Pro14配置是不太一样的,所以我这里列了一下配置。主要区别在于有一部分是2.2K分辨率+MX450显卡,而我这个是2.8K分辨率+锐炬Iris Xe显卡。 为了工作的需要,要装一个Ubuntu,先是装了之前用过的 Ubuntu 18.04,安装后发现触摸板无法使用,一系列探索后无果,在朋友的推荐下,还是决定安装 Ubuntu 20.04 试一下,踩了一些坑,在这里记录一下。 问题列表 如果你遇到了以下问题,那么这篇文章的方法可能会对你有益处: -Ubuntu 18.04 相关 Ubuntu 18.04 无法使用触摸板 Ubuntu 18.04 无法使用内置键盘 Ubuntu 18.04 无法调节亮 Ubuntu 18.04 查看GPU发现是llvm,而不是Iris Xe Ubuntu 20.04 相关 Ubuntu 20....

                  November 2, 2021 · 2 min · zzsqwq
                  © 2024 Zs's Blog +Ubuntu 18.04 相关 Ubuntu 18.04 无法使用触摸板 Ubuntu 18.04 无法使用内置键盘 Ubuntu 18.04 无法调节亮 Ubuntu 18.04 查看GPU发现是llvm,而不是Iris Xe Ubuntu 20.04 相关 Ubuntu 20.04 进入后屏幕花屏、黑屏 Ubuntu 20.04 查看GPU发现是llvm,而不是Iris Xe 现在达成的效果 Ubuntu 20.04 能够正常使用,触摸板以及外界屏幕,亮度调节均无问题。 +...

                  November 2, 2021 · 2 min · zzsqwq
                  + PaperMod | 鲁ICP备2020034310号 \ No newline at end of file