将数组分成最小总代价的子数组 II

将数组分成最小总代价的子数组 II 给你一个下标从 0 开始长度为 n 的整数数组 nums 和两个 正 整数 k 和 dist 。 一个数组的 代价 是数组中的 第一个 元素。比方说,[1,2,3] 的代价为 1 ,[3,4,1] 的代价为 3 。 你需要将 nums 分割成 k 个 连续且互不相交 的子数组,满足 第二 个子数组与第 k 个子数组中第一个元素的下标距离 不超过 dist 。换句话说,如果你将 nums 分割成子数组 $nums[0..(i_1 - 1)], nums[i_1..(i_2 - 1)], ..., nums[i_{k-1}..(n - 1)] ,$ 那么它需要满足 $i_{k-1} - i_1 <= dist$ 请你返回这些子数组的 最小 总代价。 提示: 3 <= n <= 105 1 <= nums[i] <= 109 3 <= k <= n k - 2 <= dist <= n - 2 思路 从将 nums 分割成 k 个 连续且互不相交 的子数组得到 ...

February 2, 2026 · 1 min · farmer3-c

开源软件导论

第一章:开源概述 开源是什么 在 20 世纪 70 年代末,Richard Stallman 在 MIT 人工智能实验室安装了一台新的打印机,当时他在那里工作,这台打印机运行专有固件。打印机出现问题时,理查德·斯托曼很沮丧,因为他无法获得打印机软件的副本并编辑代码来解决。这种挫败感时自由与开源运动的起源。 对于所有人而言,开源的好处: 获取任何给定工作的源代码、配置文件和文档。 自由地使用、修改和分发这些代码。 摆脱厂商的恶意绑定 更高的合作程度 对于开源的使用者而言,他们想要达成目标不会受到制约,最大程度地发挥自己的意愿。 对于开源的贡献者而言,他们可以在不付出实际代价的情况下,为开源软件做出贡献,在自己的简历中展示自己的能力。 开源历史上的 6 个关键时刻 RMS 和打印机 在 20 世纪 70 年代末,Richard·M·Stallman(RMS)是麻省理工学院的一名员工程序员。他的部门像当时许多大学一样,共享一台 PDP-10 计算机和一台打印机。他们遇到的一个问题是,纸经常在打印机中卡住,导致一连串的打印任务堆积在队列中,直到有人修理好卡纸问题。为了解决这个问题,麻省理工学院的员工想出了一个很棒的社会性解决方案:他们编写了打印机驱动程序的代码,以便当打印机卡住时,会向所有当前等待打印任务的人发送一条消息:“打印机卡纸了,请修理。“这样,它就不会长时间卡住。 1980 年,实验室接受了一台全新的激光打印机的捐赠。然而,当斯托曼要求获取打印机驱动程序的源代码,以便重新实现社会黑客技术,让系统在纸张卡住时通知用户时,他被告知这是专有信息。他听说另一所大学的一位研究员拥有一个研究项目的源代码,当机会出现时,他请求这位同事分享——而对方拒绝时他感到震惊。他们签署了保密协议(NDA),斯托曼认为这是对黑客文化的背叛。 20 世纪 70 年代末至 80 年代初,软件被视为有价值,这种软件传统上与硬件一起以源代码形式提供。越来越多的麻省理工学院研究人员开始创办软件公司,而销售软件许可证是他们商业模式的关键。保密协议和专有软件许可证成为常态,最好的程序员被从麻省理工学院等大学招聘来参与私人开发项目,在那里他们无法再分享或合作。 作为对此的反应,斯托曼决定创建一个完整的操作系统,它不会剥夺用户理解其工作原理的自由,并且如果他们愿意,还可以进行修改。这就是自由软件运动的诞生。 GNU 的创建和自由软件的兴起 到 1983 年底,斯托曼准备好宣布他的项目并招募支持者和助手。1983 年 9 月,他宣布了 GNU 项目的创建(GNU 代表 Gnu’s Not Unix——一个递归缩写)。该项目的目标是克隆 Unix 操作系统,以创建一个赋予用户完全自由的系统。 1984 年 1 月,他开始全职从事该项目,首先创建了一个编译器系统(GCC)和各种操作系统工具。1985 年初,他发布了《GNU 宣言》,号召程序员加入,并成立了自由软件基金会以接受捐赠来支持这项工作。这份文件是自由软件运动的创始章程。 《GNU 通用公共许可证》的编写 直到 1989 年,自由软件基金会和理查德·斯托曼(RMS)编写并发布的软件都没有统一的许可证。Emacs 在 Emacs 许可证下发布,GCC 在 GCC 许可证下发布,等等;然而,在一家名为 Unipress 的公司强迫斯托曼停止分发他们从詹姆斯·高斯林(Java 之父)那里获得的 Emacs 实现版本后,他意识到需要一种保护用户自由的许可证。 ...

January 28, 2026 · 3 min · farmer3-c

go环境安装

Go 计算机编程语言 Go(又称为Golang)是一种由Google开发的开源编程语言,于2009年首次公开发布。它旨在提供简洁、高效、可靠的软件开发解决方案。Go是一种静态强类型、编译型语言,具有很强的表达能力,得益于其并发机制,用它编写的程序能够非常有效地利用多核与联网的计算机。 主要特点 Go语言的设计目标是将静态语言的安全性和性能与动态语言的易用性相结合。它在语言层面提供了对协程的支持,特别适合编写高并发的项目。以下是Go语言的一些主要特点: 简洁、快速、安全:Go语言的语法接近C语言,但更简洁,编译速度非常快,且具有内置的垃圾回收功能。 并发支持:Go语言内置了轻量级进程(goroutine)、通道和select语句等并发原语,使得编写并发程序变得简单和高效。 模块化:Go语言采用模块化的方式组织代码,易于维护和重用。 跨平台:Go语言支持跨平台编译,可以在不同的操作系统上进行开发和部署。 安装 在Windows中安装Go: 安装包下载地址为:https://go.dev/dl/。 如果打不开可以使用这个地址:https://golang.google.cn/dl/。 运行第一个go程序 1 2 3 4 5 6 7 package main import "fmt" func main() { fmt.Println("Hello, World!") } 保存为hello.go 终端运行 1 2 $ go run hello.go Hello, World! 在同一命令提示符窗口中,第一次运行这个程序时,会耗时较多,在我的电脑上大约需要2~3秒,之后再运行这个程序就会很快,但关闭这个窗口,隔一段时间下次运行情况如初。 原因是这个命令会先编译 .go 文件,然后再运行编译后的可执行文件,所以第一次运行会比较慢。 可以使用go build命令来编译程序,然后再运行编译后的可执行文件,这样就不会每次都重新编译了。 1 2 3 $ go build hello.go $ ./hello Hello, World! VS Code运行 在VS Code中安装Go插件,然后打开hello.go文件,点击运行按钮,就可以运行这个程序了。 我遇到了几个问题: 1. VS Code 在安装 Go 语言的核心工具(gopls 和 dlv)时,无法连接到官方的 Go 模块代理服务器(proxy.golang.org),导致网络连接超时失败。 报错中有dial tcp 142.251.45.145:443: connectex: A connection attempt failed ...

January 28, 2026 · 1 min · farmer3-c

爬取中国工商银行人民币即期外汇牌价数据

爬取单日数据 前期准备 我要爬取的网站是 https://www.icbc.com.cn/ICBC/%e9%87%91%e8%9e%8d%e4%bf%a1%e6%81%af/%e8%a1%8c%e6%83%85%e6%95%b0%e6%8d%ae/%e4%ba%ba%e6%b0%91%e5%b8%81%e5%8d%b3%e6%9c%9f%e5%a4%96%e6%b1%87%e7%89%8c%e4%bb%b7/ 数据是这样的:币种、银行买入价、银行卖出价、发布时间 环境:python 3.12.2 寻找网络请求接口 在浏览器中按F12打开开发者工具,然后点击Network,勾选 Preserve log 选择 Fetch / XHR XMLHttpRequest (XHR) 和 Fetch API都是网页向服务器发起 HTTP 请求的机制。Fetch API 是一种现代的、基于 Promise 的替代方案,用于取代老旧的、基于回调的 XHR,它提供了更简洁的语法和更适合现代网页开发的功能。 手动操作页面: 选择一个日期(比如 2021-01-25) 点击【查询】 Network 列表里 新出现的 POST 请求 可以确定工商银行新版 PAPI 的“历史外汇牌价接口”:POST https://papi.icbc.com.cn/exchanges/ns/history 如何使用接口 请求方式 POST Content-Type: application/json 请求体 1 2 3 4 5 { "date": "2021-01-13", "currType": "", "serverType": "1" } 👉 这个接口不支持“时间区间” 👉 需要一天一天请求 编写代码 点击展开/折叠代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import requests url = "https://papi.icbc.com.cn/exchanges/ns/history" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", "Content-Type": "application/json", "Origin": "https://www.icbc.com.cn", "Referer": "https://www.icbc.com.cn/ICBC/%E9%87%91%E8%9E%8D%E4%BF%A1%E6%81%AF/%E8%A1%8C%E6%83%85%E6%95%B0%E6%8D%AE/%E4%BA%BA%E6%B0%91%E5%B8%81%E5%8D%B3%E6%9C%9F%E5%A4%96%E6%B1%87%E7%89%8C%E4%BB%B7/" } payload = { "date": "2021-01-13", "currType": "", "serverType": "1" } r = requests.post(url, headers=headers, json=payload, timeout=10) r.raise_for_status() print(r.json()) 报错:[SSL: UNSAFE_LEGACY_RENEGOTIATION_DISABLED] 当前的 Python + OpenSSL 与工行 PAPI 服务器的 TLS 协商不兼容 更准确地说: 请求触发了“不安全的旧式 TLS 重新协商”,而 Python 默认已经禁止它 为什么浏览器能访问,我的 Python 不能? 浏览器(Chrome / Edge): ...

January 20, 2026 · 5 min · farmer3-c

翻转树上最少边

翻转树上最少边 给你一棵包含 n 个节点的 无向树,节点编号从 0 到 n - 1。该树由长度为 n - 1 的二维整数数组 edges 表示,其中 edges[i] = [ai, bi] 表示树中节点 ai 和 bi 之间存在一条边。 另外给你两个长度为 n 的 二进制 字符串 start 和 target。对于每个节点 x,start[x] 是其初始颜色,而 target[x] 是其目标颜色。 在一次操作中,你可以选择下标为 i 的一条边并 翻转 它的两个端点。也就是说,如果这条边是 [u, v],那么节点 u 和 v 的颜色 各自 从 ‘0’ 变为 ‘1’,或者从 ‘1’ 变为 ‘0’。 返回一个边下标数组,执行这些边对应的操作可以将 start 转换为 target。在所有有效序列中找出 长度最短 的序列,以 升序 返回边下标。 如果无法将 start 转换为 target,则返回一个仅包含单个元素 -1 的数组。 ...

January 19, 2026 · 2 min · farmer3-c

交替按位异或分割的数目

3811.交替按位异或分割的数目 给你一个整数数组 nums 以及两个 互不相同 的整数 target1 和 target2。nums 的一个 分割 是指将其划分为一个或多个 连续且非空 的块,这些块在不重叠的情况下覆盖整个数组。 如果一个分割中各块元素的 按位异或 结果在 target1 和 target2 之间 交替 出现,且以 target1 开始,则称该分割是 有效的。 形式上,对于块 b1, b2, … : XOR(b1) = target1 XOR(b2) = target2(如果存在) XOR(b3) = target1,以此类推。 返回 nums 的有效分割方案数,结果对 $10^9 $+ 7 取余。 注意: 如果单个块的 按位异或 结果等于 target1,则该分割也是有效的。 1 <= nums.length <= $10^5$ 0 <= nums[i], target1, target2 <= $10^5$ target1 != target2 思路 方法一:递归+记忆化搜索 点击展开/折叠代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 class Solution { int mod = 1e9 + 7, t[2]; vector<vector<long long>> memo; long long dfs(int i, int state, vector<int> &nums) { if (i == nums.size()) { return 0; } if (memo[i][state] != -1) { return memo[i][state]; } long long res = 0; int cur = 0; for (int j = i; j < nums.size(); j++) { cur ^= nums[j]; if (cur == t[state]) { if (j == nums.size() - 1) { res = (res + 1) % mod; } else { res = (res + dfs(j + 1, state ^ 1, nums)) % mod; } } } return memo[i][state]=res; } public: int alternatingXOR(vector<int> &nums, int target1, int target2) { int n = nums.size(); t[0] = target1; t[1] = target2; memo.resize(n, vector<long long>(2, -1)); return dfs(0, 0, nums); } }; 时间复杂度:O(n),其中n为数组nums的长度。 空间复杂度:O(n),需要使用一个二维数组memo来存储中间结果。 不足以通过所有测试用例,超时。 ...

January 19, 2026 · 2 min · farmer3-c

查找并重命名文件

下面是实现查找并重命名文件的C程序,使用了apue.h库中的函数和数据结构。 该程序支持查找指定目录下的所有文件,并将指定文件名的文件重命名为"pass"。 程序会输出重命名的文件数量。 点击展开/折叠代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 #include "apue.h" #include <dirent.h> #include <limits.h> #include <string.h> #include <sys/stat.h> #include <sys/types.h> #include <stdio.h> #include <stdlib.h> typedef int Myfunc(const char *, const struct stat *, int); static Myfunc myfunc_rename; static int dopath(Myfunc *); static int myftw(char *, Myfunc *); static char *fullpath; // 存储文件完整路径 static char *target_filename; // 要查找并重命名的目标文件名 static int rename_count = 0; // 成功重命名的文件数 // 文件类型标记 #define FTW_F 1 /* 普通文件 */ #define FTW_D 2 /* 目录 */ #define FTW_DNR 3 /* 不可读目录 */ #define FTW_NS 4 /* 无法stat的文件 */ int main(int argc, char *argv[]) { int ret; // 校验参数:支持 myfind <指定目录> <要改名的文件名> if (argc != 3) { err_quit("usage: myfind <target_directory> <filename_to_rename>"); } target_filename = argv[2]; rename_count = 0; ret = myftw(argv[1], myfunc_rename); if (rename_count == 0) { printf("未找到名为 '%s' 的文件,无需重命名\n", target_filename); } else { printf("成功将 %d 个文件重命名为 'pass'\n", rename_count); } exit(ret); } static int myftw(char *pathname, Myfunc *func) { size_t len; fullpath = path_alloc(&len); // 从apue库获取路径缓冲区 strncpy(fullpath, pathname, len); fullpath[len-1] = 0; // 确保字符串终止 return(dopath(func)); } static int dopath(Myfunc *func) { struct stat statbuf; struct dirent *dirp; DIR *dp; int ret; char *ptr; // 获取文件属性失败 if (lstat(fullpath, &statbuf) < 0) return(func(fullpath, &statbuf, FTW_NS)); // 如果是普通文件,执行重命名逻辑 if (S_ISDIR(statbuf.st_mode) == 0) return(func(fullpath, &statbuf, FTW_F)); // 如果是目录,先执行回调(无实际操作) if ((ret = func(fullpath, &statbuf, FTW_D)) != 0) return(ret); // 拼接子目录路径 ptr = fullpath + strlen(fullpath); *ptr++ = '/'; *ptr = 0; // 打开目录失败 if ((dp = opendir(fullpath)) == NULL) return(func(fullpath, &statbuf, FTW_DNR)); // 遍历目录下的所有文件/子目录 while ((dirp = readdir(dp)) != NULL) { // 跳过.和.. if (strcmp(dirp->d_name, ".") == 0 || strcmp(dirp->d_name, "..") == 0) continue; // 拼接子文件路径 strcpy(ptr, dirp->d_name); // 递归处理子文件/子目录 if ((ret = dopath(func)) != 0) break; } // 恢复路径(移除最后拼接的子文件名) ptr[-1] = 0; // 关闭目录 if (closedir(dp) < 0) err_ret("无法关闭目录: %s", fullpath); return(ret); } // 查找目标文件并将其重命名为pass static int myfunc_rename(const char *pathname, const struct stat *statptr, int type) { // 仅处理普通文件 if (type != FTW_F) return 0; // 提取文件名(路径最后一个/后的部分) char *filename = strrchr(pathname, '/'); if (filename == NULL) { filename = (char *)pathname; // 无/,直接是文件名 } else { filename++; // 跳过/,指向实际文件名 } // 匹配到目标文件,执行重命名 if (strcmp(filename, target_filename) == 0) { // 拼接新路径:原目录 + /pass char new_path[PATH_MAX]; strncpy(new_path, pathname, strrchr(pathname, '/') - pathname + 1); strcat(new_path, "pass"); // 执行重命名 if (rename(pathname, new_path) == 0) { printf("成功重命名: %s -> %s\n", pathname, new_path); rename_count++; } else { err_ret("重命名失败: %s", pathname); } } return 0; } UNIX系统中路径的操作与修改 这个程序实现了在指定目录下查找并重命名特定文件的功能,展示了多种路径操作技术。 ...

January 13, 2026 · 4 min · farmer3-c

判断质数汇编程序编写

以下面的代码为例,说明如何用汇编语言判断一个数是否为素数,从而进行汇编语言的学习。 点击展开/折叠代码 .MODEL SMALL .STACK 100H .DATA msg_input DB ‘Please input a number: $' msg_prime DB 0DH, 0AH, 'It is a prime number.$’ msg_not DB 0DH, 0AH, ‘It is not a prime number.$’ num DW 0 .CODE START: MOV AX, @DATA MOV DS, AX ; 1. 显示输入提示 LEA DX, msg_input MOV AH, 09H INT 21H ; 2. 读取数字 (读取一个十进制数) CALL READ_NUM MOV num, AX ; 3. 判断素数逻辑 ; 如果 n < 2,不是素数 CMP AX, 2 JL NOT_PRIME JE IS_PRIME ; 2 是素数 ; 循环判断: 从 2 到 n-1 MOV CX, 2 ; CX 是除数 CHECK_LOOP: MOV AX, num XOR DX, DX ; 清除高位 DIV CX ; AX / CX, 余数在 DX ...

January 12, 2026 · 3 min · farmer3-c

convex review

Lecture 1: Unconstrained Optimization for Differentiable Functions 几个无限制可微问题的优化: 对于一般的函数求极值问题: 一个变量的函数可以求导,极值一般在导函数的零点。 如:求极小值$f(x)=x^2-1$ 多个变量的函数可以求偏导,极值一般在偏导函数的零点。 如:求极值$f(x,y)=x^3-y^3+3x^2+3y^2-9x$ 对得到的四个驻点进行的二阶导数检验(Hessian 判别法) $$|H|=f_{xx}f_{yy}-(f_{xy})^2$$令$a=f_{xx}$ 若 ∣H∣>0且 a>0 → 局部极小值(Ext. small) 若 ∣H∣>0 且 a<0 → 局部极大值(Ext. large) 若 ∣H∣<0 → 鞍点(uncertain,即非极值点) 若 ∣H∣=0 → 无法判断(需要更高阶检验) 梯度下降求极大/极小值: 对一个复杂的函数求极值是一件困难的事,梯度下降可以使它变得简单。 $$ \begin{aligned} f(x) &\approx f(x_0)+(x-x_0)f'(x_0) \\ f(x) &= f(x_0)-\Delta xf'(x_0) \end{aligned} $$$\implies x=x_0-\Delta x$ 设置一个学习率a,或者叫步长, $\Delta x=a f'(x_0)$ 然后就是一个迭代的过程: $x_{k+1}=x_k-\Delta x_k$ $f'(x_k)=0$时到达极值点。 牛顿法-I解决等式限制的优化: 思想也是迭代。 如:$e^x-2x^2+3x-4=0$ 迭代$(x_n,f(x_n))$ ${y=f'(x_n)(x-x_n)+f(x_n)} \xrightarrow {\text{y → 0}}{x=x_n-\frac{f(x_n)}{f'(x_n)}}$ ...

December 11, 2025 · 7 min · farmer3-c

matlab tutorial

1.Basic Arithmetic 直接在命令行输入算式,结果存入ans变量中 如: >> 1+2 ans = 3 2.Variables 设置变量的值,存入系统中,之后可以调用 >> x=7 x = 7 >> x+3 ans = 10 >> 3.Change Format format [数据类型] 可以改变运算的结果数据类型 >> 1/3 ans = 0.3333 >> format short >> 1/3 ans = 0.3333 >> format long >> 1/3 ans = 0.333333333333333 >> 4.Remove Variables clear [变量名] 用于清楚变量 >> x x = 7 >> clear x >> x 函数或变量 'x' 无法识别。 >> 5.Clear Specific Variables 高级一点的Remove Variables之类的用法 >> x3=3 x3 = 3 >> >> clear x* >> x3=3 x3 = 3 >> who 您的变量为: ans x3 >> whos Name Size Bytes Class Attributes ans 1x1 8 double x3 1x1 8 double >> 6. Pre-Defined Constants 系统中预定义的变量 ...

November 22, 2025 · 5 min · farmer3-c