<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Pinellia Blog</title><description>Markdown eyerything.</description><link>https://pinellia.uk/</link><language>zh_CN</language><item><title>Claude Code 斜杠命令完全指南</title><link>https://pinellia.uk/posts/claude-code-slash-commands/</link><guid isPermaLink="true">https://pinellia.uk/posts/claude-code-slash-commands/</guid><description>全面介绍 Claude Code CLI 中所有 / 斜杠命令的用途、用法与实战技巧，帮助你高效驾驭终端中的 AI 编程助手</description><pubDate>Fri, 12 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://claude.com/claude-code&quot;&gt;Claude Code&lt;/a&gt; 是 Anthropic 推出的终端原生 AI 编程助手。除了在交互中自然描述需求之外，它还提供了一套以 &lt;code&gt;/&lt;/code&gt; 开头的&lt;strong&gt;斜杠命令（Slash Commands）&lt;/strong&gt;，用于执行配置、会话管理、代码审查、项目初始化等操作。&lt;/p&gt;
&lt;p&gt;本文基于实际使用经验，对所有内置斜杠命令进行系统梳理。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;1. 会话管理&lt;/h2&gt;
&lt;p&gt;控制当前对话会话的状态与生命周期。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;命令&lt;/th&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;th&gt;示例 / 说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/clear&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;清空当前会话上下文&lt;/td&gt;
&lt;td&gt;开始全新对话，不影响项目文件和设置。适合切换话题或上下文过长时使用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/compact&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;压缩会话上下文&lt;/td&gt;
&lt;td&gt;将对话历史总结为摘要以释放 token 空间。压缩前确保重要内容已落地到文件中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/rename&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;重命名当前会话标题&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/rename &quot;修复登录页面布局问题&quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/resume&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;恢复之前的会话&lt;/td&gt;
&lt;td&gt;继续之前的对话&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/export&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;导出当前会话记录&lt;/td&gt;
&lt;td&gt;支持多种格式，用于存档、分享或审计&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/prompt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;显示当前系统提示词&lt;/td&gt;
&lt;td&gt;查看 CLAUDE.md 注入的项目上下文、记忆、环境信息等&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;2. 配置与偏好&lt;/h2&gt;
&lt;p&gt;调整 Claude Code 的外观、行为和模型偏好。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;命令&lt;/th&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;th&gt;示例 / 说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/config&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;打开设置界面&lt;/td&gt;
&lt;td&gt;修改主题、模型、权限策略、hooks 等。等价于编辑 &lt;code&gt;~/.claude/settings.json&lt;/code&gt; 和 &lt;code&gt;.claude/settings.json&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/theme&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;切换终端颜色主题&lt;/td&gt;
&lt;td&gt;暗色 / 亮色 / 系统跟随&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/statusline&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;配置状态栏显示项&lt;/td&gt;
&lt;td&gt;选择显示模型名、分支、token 用量等信息&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/model&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;切换 AI 模型&lt;/td&gt;
&lt;td&gt;可用模型取决于订阅计划和最新模型列表&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/fast&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;切换 Fast 模式&lt;/td&gt;
&lt;td&gt;使用 Opus 模型并加速输出，适合需要快速响应的场景&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;3. 项目初始化与记忆&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;命令&lt;/th&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;th&gt;示例 / 说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/init&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;生成项目的 CLAUDE.md&lt;/td&gt;
&lt;td&gt;分析项目结构，自动生成包含技术栈、目录结构、常用命令的文档。建议每个项目根目录运行一次&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/memory&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;管理持久记忆&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/memory 记住：这个项目使用 Biome 格式化代码&lt;/code&gt;。记忆存储在 &lt;code&gt;.claude/projects/&amp;lt;path&amp;gt;/memory/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/recall&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检索相关记忆&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/recall 代码格式化工具&lt;/code&gt;。Claude Code 启动时自动加载 &lt;code&gt;MEMORY.md&lt;/code&gt; 索引&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;4. 代码审查与质量&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;命令&lt;/th&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;th&gt;示例 / 说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/review&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;审查当前 Pull Request&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/review --effort high&lt;/code&gt; 指定审查强度；覆盖正确性、安全性、性能、可维护性&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/security-review&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;安全漏洞专项审查&lt;/td&gt;
&lt;td&gt;覆盖 OWASP Top 10：注入、认证绕过、敏感信息泄露、不安全反序列化等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/simplify&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;审查并自动简化代码&lt;/td&gt;
&lt;td&gt;识别可简化、复用、提效的代码模式并自动修复，侧重质量而非 bug&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/code-review&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;分级代码审查&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/code-review --effort low&lt;/code&gt;（仅高置信度）/ &lt;code&gt;max&lt;/code&gt;（全面）/ &lt;code&gt;--comment&lt;/code&gt;（发布到 PR）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;5. 开发与调试&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;命令&lt;/th&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;th&gt;示例 / 说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/run&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;启动并驱动项目应用&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/run &quot;测试登录功能是否正常&quot;&lt;/code&gt;。自动检测项目类型并选择运行方式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/verify&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;验证变更实际效果&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/verify &quot;检查导航栏响应式布局是否修复&quot;&lt;/code&gt;。运行应用并观察行为来确认&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;6. 任务与后台管理&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;命令&lt;/th&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;th&gt;示例 / 说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/tasks&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;查看任务列表&lt;/td&gt;
&lt;td&gt;显示每个任务的状态（pending / in_progress / completed）和依赖关系&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/bashes&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;列出后台 Shell 任务&lt;/td&gt;
&lt;td&gt;查看所有运行中的后台任务及其状态&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/terminate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;终止后台任务&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/terminate &amp;lt;task-id&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;7. 自动化与工作流&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;命令&lt;/th&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;th&gt;示例 / 说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/loop&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;按固定间隔循环执行命令&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/loop 5m /run &quot;检查 Vercel 最新部署状态&quot;&lt;/code&gt;（每 5 分钟）；默认间隔 10 分钟&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/workflows&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;查看和管理多 Agent 编排工作流&lt;/td&gt;
&lt;td&gt;支持 &lt;code&gt;parallel()&lt;/code&gt;、&lt;code&gt;pipeline()&lt;/code&gt;、&lt;code&gt;phase()&lt;/code&gt; 等编排原语，用 JS 编写脚本&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;8. 扩展与集成&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;命令&lt;/th&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;th&gt;示例 / 说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/mcp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;管理 MCP 服务器连接&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/mcp add &amp;lt;server-name&amp;gt;&lt;/code&gt; 添加外部工具/数据源（数据库、API 等）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/ide&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;管理 IDE 集成&lt;/td&gt;
&lt;td&gt;与 VS Code、JetBrains 等协作，在 IDE 中打开文件、定位到指定行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/add-dir&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;添加额外工作区目录&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/add-dir /path/to/another-project&lt;/code&gt;，允许操作多个目录下的文件&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;9. 技能类命令（Skills）&lt;/h2&gt;
&lt;p&gt;Skills 是扩展 Claude Code 能力边界的专业化模块：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;命令&lt;/th&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/deep-research&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;多源深度调研——自动搜索、交叉验证并生成带引用的报告&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/claude-api&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Claude API / Anthropic SDK 参考——模型 ID、定价、参数、token 计算等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/update-config&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;通过 settings.json 配置 hooks、权限、环境变量等自动化行为&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/keybindings-help&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;自定义键盘快捷键&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/fewer-permission-prompts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;分析操作历史，生成权限白名单以减少重复授权弹窗&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/run&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;启动并驱动项目应用以观察变更效果&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/verify&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;验证代码变更是否达到预期效果&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/code-review&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;对当前 diff 进行分级审查&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/simplify&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;审查变更代码的质量优化点并自动修复&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/review&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;审查 Pull Request&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/security-review&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;安全审查&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/init&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;初始化项目 CLAUDE.md&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/loop&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;定时循环执行任务&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;Skills 列表会随版本更新持续扩展。使用 &lt;code&gt;/help&lt;/code&gt; 可查看当前可用的完整 Skills 列表。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;10. 信息与帮助&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;命令&lt;/th&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;th&gt;示例 / 说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/help&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;显示帮助信息和命令概览&lt;/td&gt;
&lt;td&gt;遇到不熟悉的命令时的第一站&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/cost&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;查看 token 用量及费用&lt;/td&gt;
&lt;td&gt;当前会话和累计明细，帮助控制 API 消费&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/doctor&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;系统健康检查&lt;/td&gt;
&lt;td&gt;验证安装完整性、依赖项（Node.js、pnpm 等）、配置文件有效性&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;11. 账户管理&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;命令&lt;/th&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;th&gt;示例 / 说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/login&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;登录或切换 Anthropic 账户&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/logout&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;登出当前账户&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;12. 实用技巧&lt;/h2&gt;
&lt;h3&gt;12.1 命令组合&lt;/h3&gt;
&lt;p&gt;多个命令可以串联达到高效 workflow：先 &lt;code&gt;/review&lt;/code&gt; 审查，再 &lt;code&gt;/simplify&lt;/code&gt; 自动修复；先 &lt;code&gt;/init&lt;/code&gt; 初始化，再 &lt;code&gt;/config&lt;/code&gt; 自定义。&lt;/p&gt;
&lt;h3&gt;12.2 善用 &lt;code&gt;/prompt&lt;/code&gt; 排查问题&lt;/h3&gt;
&lt;p&gt;当 Claude Code 的行为不符合预期时，用 &lt;code&gt;/prompt&lt;/code&gt; 查看它实际「看到」了哪些指令——包括 CLAUDE.md、memory、系统提示词等。&lt;/p&gt;
&lt;h3&gt;12.3 &lt;code&gt;/compact&lt;/code&gt; 的时机&lt;/h3&gt;
&lt;p&gt;当出现以下情况时建议执行压缩：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;上下文 token 使用率超过 80%&lt;/li&gt;
&lt;li&gt;对话中已完成多个独立任务&lt;/li&gt;
&lt;li&gt;响应速度明显下降&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;12.4 项目级 vs 用户级配置&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;级别&lt;/th&gt;
&lt;th&gt;路径&lt;/th&gt;
&lt;th&gt;作用范围&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;用户级&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.claude/settings.json&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;适用于所有项目的全局设置&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;项目级&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.claude/settings.json&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;仅对当前项目生效，覆盖用户级设置&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;使用 &lt;code&gt;/config&lt;/code&gt; 编辑时注意区分两者的作用范围。&lt;/p&gt;
&lt;h3&gt;12.5 Memory 的最佳实践&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;记录项目特有的约定和非标准做法&lt;/li&gt;
&lt;li&gt;记录用户偏好（语言、格式化风格等）&lt;/li&gt;
&lt;li&gt;避免记录可从代码或 git 历史自动推导的信息&lt;/li&gt;
&lt;li&gt;定期用 &lt;code&gt;/recall&lt;/code&gt; 检查记忆的有效性&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;小结&lt;/h2&gt;
&lt;p&gt;Claude Code 的斜杠命令体系涵盖了从会话管理、代码审查、配置调整到自动化编排的完整开发工作流。掌握这些命令可以大幅提升你在终端中的开发效率——将 AI 从「对话伙伴」升级为「可编排的编程环境」。&lt;/p&gt;
&lt;p&gt;核心原则：&lt;strong&gt;能说的就直接说，需要精确控制时用命令&lt;/strong&gt;。大部分日常操作通过自然语言即可完成，斜杠命令用于配置固化、会话管理、多步骤编排等需要明确控制的场景。&lt;/p&gt;
</content:encoded></item><item><title>服务器环境配置指南</title><link>https://pinellia.uk/posts/server-env-setup/</link><guid isPermaLink="true">https://pinellia.uk/posts/server-env-setup/</guid><description>在无 root 权限的 Linux 服务器上，从零搭建完整的命令行与 Python 开发环境，包含 zsh 编译、micromamba 部署、Python 环境创建与镜像配置</description><pubDate>Fri, 12 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;本文记录在一台无 root 权限的 Linux 服务器上，完成基础开发环境初始化的完整流程。目标是从裸机状态搭建出一套可用、稳定的命令行交互与 Python 开发环境。&lt;/p&gt;
&lt;p&gt;主要内容包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Shell 环境初始化与 &lt;code&gt;zsh&lt;/code&gt; 编译安装&lt;/li&gt;
&lt;li&gt;&lt;code&gt;oh-my-zsh&lt;/code&gt; 配置与 &lt;code&gt;Powerlevel10k&lt;/code&gt; 主题&lt;/li&gt;
&lt;li&gt;&lt;code&gt;micromamba&lt;/code&gt; 部署与初始化&lt;/li&gt;
&lt;li&gt;个人共享目录与项目工作区建立&lt;/li&gt;
&lt;li&gt;Python 环境创建&lt;/li&gt;
&lt;li&gt;pip 国内镜像配置&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以下步骤均无需 &lt;code&gt;sudo&lt;/code&gt; 或 root 权限，仅在用户目录下操作。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;1. Shell 环境升级：编译安装 zsh&lt;/h2&gt;
&lt;p&gt;大部分 Linux 服务器预装的是 &lt;code&gt;bash&lt;/code&gt;，但如果你习惯 &lt;code&gt;zsh&lt;/code&gt; 的补全和主题生态，建议自行编译一份用户态 &lt;code&gt;zsh&lt;/code&gt;。&lt;/p&gt;
&lt;h3&gt;1.1 准备编译依赖&lt;/h3&gt;
&lt;p&gt;由于没有 root 权限，需要借助 &lt;code&gt;micromamba&lt;/code&gt; 创建临时环境来提供编译工具链：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 下载 micromamba 二进制（详见下一节）
curl -Ls https://micro.mamba.pm/api/micromamba/linux-64/latest | tar -xvj .local/micromamba
chmod +x .local/micromamba/micromamba

# 创建一个用于编译的环境
./.local/micromamba/micromamba create -n make make ncurses
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1.2 下载并解压 zsh 源码&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 下载 zsh 源码包
wget https://sourceforge.net/projects/zsh/files/zsh/5.9.1/zsh-5.9.1.tar.xz/download -O zsh-5.9.1.tar.xz
tar -xJf zsh-5.9.1.tar.xz
cd zsh-5.9.1
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1.3 配置与编译&lt;/h3&gt;
&lt;p&gt;设置编译环境变量，让编译器找到 &lt;code&gt;micromamba&lt;/code&gt; 环境中安装的 &lt;code&gt;ncurses&lt;/code&gt; 库：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ENV_PATH=&quot;$HOME/.local/micromamba/envs/make&quot;

make distclean || rm -f config.cache

./configure --prefix=&quot;$HOME/.local/zsh&quot; \
    CFLAGS=&quot;-I${ENV_PATH}/include -I${ENV_PATH}/include/ncurses&quot; \
    CPPFLAGS=&quot;-I${ENV_PATH}/include -I${ENV_PATH}/include/ncurses&quot; \
    LDFLAGS=&quot;-L${ENV_PATH}/lib -Wl,-rpath,${ENV_PATH}/lib&quot; \
    --with-termlib=ncurses

make &amp;amp;&amp;amp; make install
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;编译完成后，&lt;code&gt;zsh&lt;/code&gt; 会被安装到 &lt;code&gt;$HOME/.local/zsh&lt;/code&gt; 下。&lt;/p&gt;
&lt;h3&gt;1.4 切换默认 Shell&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 确认 zsh 路径
which zsh
# 输出: ~/.local/zsh/bin/zsh

# 查看当前系统已登记的 shell
cat /etc/shells

# 切换默认登录 shell
chsh -s &quot;$HOME/.local/zsh/bin/zsh&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;[!TIP]
如果 &lt;code&gt;chsh&lt;/code&gt; 在服务器上可用（部分共享服务器允许用户自行切换），该命令会直接生效。重新登录后即为 &lt;code&gt;zsh&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;若 &lt;code&gt;chsh&lt;/code&gt; 不可用，可在 &lt;code&gt;~/.bash_profile&lt;/code&gt; 末尾添加 &lt;code&gt;exec $HOME/.local/zsh/bin/zsh&lt;/code&gt;，每次登录时自动进入 &lt;code&gt;zsh&lt;/code&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;1.5 安装 oh-my-zsh 与 Powerlevel10k 主题&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://ohmyz.sh&quot;&gt;oh-my-zsh&lt;/a&gt; 是 zsh 最流行的配置框架，提供丰富的主题和插件生态。&lt;a href=&quot;https://github.com/romkatv/powerlevel10k&quot;&gt;Powerlevel10k&lt;/a&gt;（p10k）是一款高性能的 oh-my-zsh 主题，提供清晰的信息展示和便捷的配置向导。&lt;/p&gt;
&lt;h4&gt;1.5.1 安装 oh-my-zsh&lt;/h4&gt;
&lt;p&gt;通过 curl 一键安装：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sh -c &quot;$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装脚本会自动备份已有的 &lt;code&gt;~/.zshrc&lt;/code&gt; 并生成一份新的默认配置。&lt;/p&gt;
&lt;h4&gt;1.5.2 安装 Powerlevel10k 主题&lt;/h4&gt;
&lt;p&gt;将 p10k 主题克隆到 oh-my-zsh 的自定义主题目录下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone --depth=1 https://github.com/romkatv/powerlevel10k.git \
    &quot;${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;1.5.3 启用主题&lt;/h4&gt;
&lt;p&gt;编辑 &lt;code&gt;~/.zshrc&lt;/code&gt;，将主题设置为 &lt;code&gt;powerlevel10k/powerlevel10k&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 修改前
ZSH_THEME=&quot;robbyrussell&quot;

# 修改后
ZSH_THEME=&quot;powerlevel10k/powerlevel10k&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;1.5.4 运行配置向导&lt;/h4&gt;
&lt;p&gt;重新加载 &lt;code&gt;~/.zshrc&lt;/code&gt; 或新开一个终端标签页，p10k 会自动启动交互式配置向导：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;source ~/.zshrc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配置向导会依次询问：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;字体&lt;/strong&gt;：是否安装 Meslo Nerd Font（推荐安装，否则部分图标显示异常）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;样式&lt;/strong&gt;：经典、纯净、彩虹、瘦线等多种样式可选&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;提示符元素&lt;/strong&gt;：选择要显示的信息（时间、电池、Python 虚拟环境、git 状态等）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;间距与换行&lt;/strong&gt;：单行或双行提示符&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;配置完成后，p10k 会自动生成 &lt;code&gt;~/.p10k.zsh&lt;/code&gt; 文件，后续可通过 &lt;code&gt;p10k configure&lt;/code&gt; 随时重新运行向导。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!TIP]
如果终端连接后图标显示为乱码或方框，说明缺少 Nerd Font。可以在本地终端（如 iTerm2、Windows Terminal）中下载安装 &lt;a href=&quot;https://github.com/romkatv/powerlevel10k/#fonts&quot;&gt;Meslo Nerd Font&lt;/a&gt;，并将终端字体设置为 &lt;code&gt;MesloLGS NF&lt;/code&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!TIP]
p10k 配置向导提供了丰富的自定义选项，强烈建议首次使用时花几分钟过一遍向导，后续使用体验会好很多。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;2. 安装 Micromamba&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;micromamba&lt;/code&gt; 是 &lt;code&gt;conda&lt;/code&gt; 的 C++ 重实现，静态链接、启动速度快、无环境嵌套问题，非常适合在无 root 权限的环境下管理 Python 版本和包。&lt;/p&gt;
&lt;h3&gt;2.1 下载与安装&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;curl -Ls https://micro.mamba.pm/api/micromamba/linux-64/latest | tar -xvj .local/micromamba
chmod +x .local/micromamba/micromamba
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2.2 初始化 Shell&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;./.local/micromamba/micromamba shell init -s bash
# 如果使用 zsh，替换为：
./.local/micromamba/micromamba shell init -s zsh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;初始化完成后，重新加载 shell 配置文件或重新登录即可使用 &lt;code&gt;micromamba&lt;/code&gt; 命令。&lt;/p&gt;
&lt;h3&gt;2.3 验证安装&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;micromamba env list
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果正确输出了环境列表（即使为空），说明安装成功。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;3. 建立目录结构&lt;/h2&gt;
&lt;h3&gt;3.1 服务器摸底&lt;/h3&gt;
&lt;p&gt;在新服务器上，先确认磁盘容量、配额和共享目录情况：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;df -h                          # 查看磁盘挂载与容量
quota -v                       # 查看用户配额
groups                         # 查看所属组
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2 创建个人工作目录&lt;/h3&gt;
&lt;p&gt;根据共享存储的布局，建议建立标准化的个人目录结构。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这样做的目的是将自己的文件（代码、数据、模型、产出）存放在&lt;strong&gt;干净的独立目录&lt;/strong&gt;中，与 &lt;code&gt;~/.cache&lt;/code&gt;、shell 配置文件、micromamba 环境等系统/工具生成的文件彻底分离。这样无论是备份、迁移还是清理缓存，都不会误伤自己的数据。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;/share/&amp;lt;group_name&amp;gt;/&amp;lt;username&amp;gt;/
├── Datasets/     # 数据集
├── Models/       # 预训练模型
├── Outputs/      # 输出与实验结果
└── Projects/     # 项目工作区
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;创建命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SHARE_BASE=&quot;/share/liurui_group/niuhongkai&quot;
mkdir -p &quot;${SHARE_BASE}&quot;/{Datasets,Models,Outputs,Projects}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.3 创建项目工作区&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p ~/Projects/work1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;建议将工作区与共享目录配合使用，项目产出可以软链接或直接存放到共享目录中，便于团队协作。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;4. 创建 Python 环境&lt;/h2&gt;
&lt;h3&gt;4.1 基础 Python 环境&lt;/h3&gt;
&lt;p&gt;创建一个通用 Python 3.10 环境：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;micromamba create -n py10 python=3.10
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.2 环境管理常用命令&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;micromamba env list                    # 列出所有环境
micromamba activate py10               # 激活环境
micromamba deactivate                  # 退出当前环境
micromamba remove -n py10 --all        # 删除环境
micromamba install -n py10 &amp;lt;package&amp;gt;   # 安装包
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;5. 配置 pip 国内镜像&lt;/h2&gt;
&lt;p&gt;在国内网络环境下，配置 pip 镜像源可以显著提升包下载速度。&lt;/p&gt;
&lt;h3&gt;5.1 写入配置文件&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p ~/.config/pip
cat &amp;gt; ~/.config/pip/pip.conf &amp;lt;&amp;lt;&apos;EOF&apos;
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
trusted-host = pypi.tuna.tsinghua.edu.cn
EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.2 验证配置&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;micromamba run -n py10 python -m pip config list
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出中应包含 &lt;code&gt;index-url&lt;/code&gt; 指向清华源，即配置生效。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;6. 启动配置文件整理&lt;/h2&gt;
&lt;p&gt;初始化过程中需要调整以下 shell 配置文件，确保每次登录环境正确：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;文件&lt;/th&gt;
&lt;th&gt;用途&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;~/.bashrc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;bash 交互式 shell 的配置文件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;~/.bash_profile&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;bash 登录时读取的配置文件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;~/.zshrc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;zsh 的配置文件&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;建议将 &lt;code&gt;micromamba&lt;/code&gt; 的初始化代码、环境变量（如 &lt;code&gt;PATH&lt;/code&gt;、&lt;code&gt;LD_LIBRARY_PATH&lt;/code&gt;）统一写入对应 shell 的配置文件中。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;7. 配置 Git 提交模板&lt;/h2&gt;
&lt;p&gt;在服务器上进行开发时，经常需要提交代码。配置一个标准化的提交信息模板可以让每次 &lt;code&gt;git commit&lt;/code&gt; 时都有结构化的提示，避免遗漏关键信息。&lt;/p&gt;
&lt;h3&gt;7.1 创建模板文件&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;gt; ~/.git-commit-template.txt &amp;lt;&amp;lt; &apos;EOF&apos;

**note:**
-

---
**todo:**
- []
---
**fixed:**
- []

EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;模板分为三个区域：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;区域&lt;/th&gt;
&lt;th&gt;用途&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;**note:**&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;备注说明、背景信息、相关上下文&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;**todo:**&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;待完成的待办项，使用 &lt;code&gt;- []&lt;/code&gt; 标记&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;**fixed:**&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;本次提交修复的问题或完成的事项&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;7.2 配置 Git 使用模板&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;git config --global commit.template ~/.git-commit-template.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;[!TIP]
如果希望只对特定项目生效，去掉 &lt;code&gt;--global&lt;/code&gt;，在对应仓库目录下执行 &lt;code&gt;git config commit.template ~/.git-commit-template.txt&lt;/code&gt; 即可。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;7.3 效果&lt;/h3&gt;
&lt;p&gt;配置完成后，每次执行 &lt;code&gt;git commit&lt;/code&gt;（不带 &lt;code&gt;-m&lt;/code&gt;）时，编辑器会自动打开并预填充模板：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
**note:**
-

---
**todo:**
- []
---
**fixed:**
- []

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;只需在对应位置填写内容即可。使用 &lt;code&gt;-m&lt;/code&gt; 参数时模板不会生效，适用于简单的一次性提交。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;初始化结果确认&lt;/h2&gt;
&lt;p&gt;完成以上步骤后，你的服务器环境应具备以下能力：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[x] 用户态 &lt;code&gt;micromamba&lt;/code&gt; 已安装，可管理 Python 环境&lt;/li&gt;
&lt;li&gt;[x] &lt;code&gt;zsh&lt;/code&gt; 已编译安装并设为默认登录 shell&lt;/li&gt;
&lt;li&gt;[x] 个人共享目录与标准子目录结构已建立&lt;/li&gt;
&lt;li&gt;[x] 项目工作区已创建&lt;/li&gt;
&lt;li&gt;[x] Python 3.10 环境（&lt;code&gt;py10&lt;/code&gt;）已创建&lt;/li&gt;
&lt;li&gt;[x] pip 已配置清华镜像源&lt;/li&gt;
&lt;li&gt;[x] Git 提交模板已配置（note/todo/fixed 三段式）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这套环境可以支撑后续的数据集管理、模型下载、实验脚本开发等工作，且不依赖系统级权限。&lt;/p&gt;
</content:encoded></item><item><title>Zsh 中的 Conda 自定义命令框架</title><link>https://pinellia.uk/posts/conda-json-command-framework/</link><guid isPermaLink="true">https://pinellia.uk/posts/conda-json-command-framework/</guid><description>通过 JSON 注册表 + 通用分发器 + 独立函数实现，构建可扩展、可维护的 conda/micromamba 自定义命令框架。</description><pubDate>Thu, 16 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在日常使用 &lt;code&gt;conda&lt;/code&gt; 或 &lt;code&gt;micromamba&lt;/code&gt; 时，很多人都会逐渐积累一些“高频但非官方”的操作，比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;根据当前目录自动激活某个环境&lt;/li&gt;
&lt;li&gt;快速停用当前环境&lt;/li&gt;
&lt;li&gt;维护“项目目录 -&amp;gt; 环境名”的映射关系&lt;/li&gt;
&lt;li&gt;给 &lt;code&gt;conda&lt;/code&gt; 增加一些自己的子命令&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最直接的做法，通常是在 &lt;code&gt;~/.zshrc&lt;/code&gt; 里写一个很长的 &lt;code&gt;conda()&lt;/code&gt; 函数，用 &lt;code&gt;case&lt;/code&gt; 分发不同子命令。这个方案能用，但随着逻辑增加，会很快出现几个问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;~/.zshrc&lt;/code&gt; 越来越臃肿&lt;/li&gt;
&lt;li&gt;子命令扩展不方便&lt;/li&gt;
&lt;li&gt;help 信息难以维护&lt;/li&gt;
&lt;li&gt;实现和注册耦合太紧，不利于长期演进&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这篇文章介绍一种更适合持续扩展的方案：把自定义 &lt;code&gt;conda&lt;/code&gt; 子命令做成一个小型框架，结构分成三层：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;JSON&lt;/code&gt; 指令定义&lt;/li&gt;
&lt;li&gt;通用分发器&lt;/li&gt;
&lt;li&gt;各自独立的实现函数&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;最终效果是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;~/.zshrc&lt;/code&gt; 中只保留一行 &lt;code&gt;source&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;执行 &lt;code&gt;conda&lt;/code&gt; 时，除了原有 &lt;code&gt;micromamba&lt;/code&gt; help，还能显示你自己注册的子命令和说明&lt;/li&gt;
&lt;li&gt;新增一个子命令时，只需要：
&lt;ul&gt;
&lt;li&gt;在 JSON 中注册&lt;/li&gt;
&lt;li&gt;写一个实现函数&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;不需要再去修改一大段 &lt;code&gt;case&lt;/code&gt; 分支&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;一、适用场景&lt;/h2&gt;
&lt;p&gt;这套方案适合下面这些人：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用 &lt;code&gt;zsh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;底层环境管理器是 &lt;code&gt;micromamba&lt;/code&gt;，但希望继续使用 &lt;code&gt;conda&lt;/code&gt; 这个命令入口&lt;/li&gt;
&lt;li&gt;想给 &lt;code&gt;conda&lt;/code&gt; 增加自己的快捷子命令&lt;/li&gt;
&lt;li&gt;希望自定义命令具备“可注册、可扩展、可维护”的结构&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你平时会做下面这些操作，这套方案会特别顺手：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;conda ac&lt;/code&gt;：按目录映射自动激活环境&lt;/li&gt;
&lt;li&gt;&lt;code&gt;conda de&lt;/code&gt;：快速停用环境&lt;/li&gt;
&lt;li&gt;&lt;code&gt;conda map curr&lt;/code&gt;：把当前目录和当前环境写入映射表&lt;/li&gt;
&lt;li&gt;&lt;code&gt;conda map&lt;/code&gt;：直接编辑映射配置&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;二、最终结构&lt;/h2&gt;
&lt;p&gt;建议把相关文件拆成下面这样：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;~/.zshrc
~/.zsh/
  conda-wrapper.zsh
  conda-commands.json
~/.conda_map.ini
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;各文件职责如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;~/.zshrc&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;只负责初始化 shell，并 &lt;code&gt;source&lt;/code&gt; 你的自定义框架&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~/.zsh/conda-wrapper.zsh&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;框架主逻辑&lt;/li&gt;
&lt;li&gt;包含注册表加载、命令分发、help 输出、各实现函数&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~/.zsh/conda-commands.json&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;子命令注册表&lt;/li&gt;
&lt;li&gt;声明每个命令的类型、目标和说明&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~/.conda_map.ini&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;保存“路径 -&amp;gt; 环境”的映射关系&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;三、整体设计思路&lt;/h2&gt;
&lt;p&gt;核心思想很简单：&lt;/p&gt;
&lt;h3&gt;1. &lt;code&gt;conda&lt;/code&gt; 不再直接硬编码全部逻辑&lt;/h3&gt;
&lt;p&gt;不再写这种结构：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;conda() {
  case &quot;$1&quot; in
    ac) ... ;;
    de) ... ;;
    map) ... ;;
    *) micromamba &quot;$@&quot; ;;
  esac
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;而是改成：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;先看看 &lt;code&gt;$1&lt;/code&gt; 是否在 JSON 注册表里&lt;/li&gt;
&lt;li&gt;如果在：
&lt;ul&gt;
&lt;li&gt;按注册信息执行对应逻辑&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;如果不在：
&lt;ul&gt;
&lt;li&gt;回落到原始 &lt;code&gt;micromamba &quot;$@&quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这样你自己的子命令和 &lt;code&gt;micromamba&lt;/code&gt; 原生能力就自然共存了。&lt;/p&gt;
&lt;h3&gt;2. JSON 只管声明，不管实现&lt;/h3&gt;
&lt;p&gt;JSON 负责定义：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;命令名&lt;/li&gt;
&lt;li&gt;命令类型&lt;/li&gt;
&lt;li&gt;目标动作&lt;/li&gt;
&lt;li&gt;help 描述&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ac&lt;/code&gt; 对应某个 zsh 函数&lt;/li&gt;
&lt;li&gt;&lt;code&gt;de&lt;/code&gt; 对应 &lt;code&gt;micromamba deactivate&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;map&lt;/code&gt; 对应某个 zsh 函数&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这就是“注册”和“实现”分离。&lt;/p&gt;
&lt;h3&gt;3. 实现函数彼此独立&lt;/h3&gt;
&lt;p&gt;每个子命令的业务逻辑用独立函数承载，比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;_conda_cmd_ac&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;_conda_cmd_map&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这样新增功能时不需要碰已有命令逻辑，只需要加新函数和注册项。&lt;/p&gt;
&lt;h2&gt;四、部署步骤&lt;/h2&gt;
&lt;p&gt;下面按完整部署流程介绍。&lt;/p&gt;
&lt;h3&gt;第一步：确保 &lt;code&gt;micromamba&lt;/code&gt; 已初始化&lt;/h3&gt;
&lt;p&gt;你的 &lt;code&gt;~/.zshrc&lt;/code&gt; 中应先有 &lt;code&gt;micromamba shell init&lt;/code&gt; 生成的初始化内容，典型形式如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# &amp;gt;&amp;gt;&amp;gt; mamba initialize &amp;gt;&amp;gt;&amp;gt;
export MAMBA_EXE=&quot;$HOME/micromamba/micromamba&quot;
export MAMBA_ROOT_PREFIX=&quot;$HOME/micromamba&quot;
__mamba_setup=&quot;$(&quot;$MAMBA_EXE&quot; shell hook --shell zsh --root-prefix &quot;$MAMBA_ROOT_PREFIX&quot; 2&amp;gt; /dev/null)&quot;
if [ $? -eq 0 ]; then
    eval &quot;$__mamba_setup&quot;
else
    alias micromamba=&quot;$MAMBA_EXE&quot;
fi
unset __mamba_setup
# &amp;lt;&amp;lt;&amp;lt; mamba initialize &amp;lt;&amp;lt;&amp;lt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这一段的作用是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;设置 &lt;code&gt;MAMBA_EXE&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;设置 &lt;code&gt;MAMBA_ROOT_PREFIX&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;把 &lt;code&gt;micromamba&lt;/code&gt; 的 shell hook 注入当前 shell&lt;/li&gt;
&lt;li&gt;让 &lt;code&gt;activate/deactivate&lt;/code&gt; 等命令在 shell 环境里生效&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;注意：这一步非常关键。因为环境激活本质上不是一个普通子进程动作，而是要修改当前 shell 的环境变量。&lt;/p&gt;
&lt;h3&gt;第二步：在 &lt;code&gt;~/.zshrc&lt;/code&gt; 里只保留简短加载语句&lt;/h3&gt;
&lt;p&gt;在 &lt;code&gt;mamba initialize&lt;/code&gt; 之后添加：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;source &quot;$HOME/.zsh/conda-wrapper.zsh&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样 &lt;code&gt;~/.zshrc&lt;/code&gt; 本身就不会塞满业务逻辑。&lt;/p&gt;
&lt;p&gt;推荐结构：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# &amp;gt;&amp;gt;&amp;gt; mamba initialize &amp;gt;&amp;gt;&amp;gt;
# ... micromamba init generated block ...
# &amp;lt;&amp;lt;&amp;lt; mamba initialize &amp;lt;&amp;lt;&amp;lt;

source &quot;$HOME/.zsh/conda-wrapper.zsh&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;第三步：创建注册表文件 &lt;code&gt;~/.zsh/conda-commands.json&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;这个文件是整个框架的命令声明中心。&lt;/p&gt;
&lt;p&gt;示例：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;commands&quot;: {
    &quot;ac&quot;: {
      &quot;type&quot;: &quot;function&quot;,
      &quot;target&quot;: &quot;_conda_cmd_ac&quot;,
      &quot;description&quot;: &quot;根据当前目录匹配 ~/.conda_map.ini 并激活对应环境（可用于手动触发）。&quot;
    },
    &quot;de&quot;: {
      &quot;type&quot;: &quot;micromamba&quot;,
      &quot;target&quot;: &quot;deactivate&quot;,
      &quot;description&quot;: &quot;停用当前环境（等价于 micromamba deactivate）。&quot;
    },
    &quot;map&quot;: {
      &quot;type&quot;: &quot;function&quot;,
      &quot;target&quot;: &quot;_conda_cmd_map&quot;,
      &quot;description&quot;: &quot;维护路径-&amp;gt;环境映射：map curr 写入当前目录；map 打开 ~/.conda_map.ini。&quot;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;字段说明：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;commands&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;所有自定义子命令的集合&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;每个子命令 key，例如 &lt;code&gt;ac&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;就是用户执行的 &lt;code&gt;conda ac&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;type&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;命令类型&lt;/li&gt;
&lt;li&gt;当前支持：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;function&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;micromamba&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;target&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;目标执行体&lt;/li&gt;
&lt;li&gt;若 &lt;code&gt;type=function&lt;/code&gt;，则是 zsh 函数名&lt;/li&gt;
&lt;li&gt;若 &lt;code&gt;type=micromamba&lt;/code&gt;，则是转发给 &lt;code&gt;micromamba&lt;/code&gt; 的子命令&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;description&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;用于 help 输出的说明文字&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这一步完成后，你的子命令元信息就集中管理起来了。&lt;/p&gt;
&lt;h3&gt;第四步：创建框架主文件 &lt;code&gt;~/.zsh/conda-wrapper.zsh&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;这是整个系统的核心。它一般需要包含下面几部分：&lt;/p&gt;
&lt;h4&gt;1. 注册表缓存结构&lt;/h4&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;typeset -g _CONDA_CMD_REGISTRY_FILE=&quot;$HOME/.zsh/conda-commands.json&quot;
typeset -g _CONDA_CMD_REGISTRY_LOADED=0
typeset -gA _CONDA_CMD_TYPE_MAP
typeset -gA _CONDA_CMD_TARGET_MAP
typeset -gA _CONDA_CMD_DESC_MAP
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;作用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;保存 JSON 文件位置&lt;/li&gt;
&lt;li&gt;标记是否已经加载过注册表&lt;/li&gt;
&lt;li&gt;用关联数组缓存命令类型、目标和说明&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这样 shell 会在首次使用时读取 JSON，之后直接用内存数据，不需要每次反复解析文件。&lt;/p&gt;
&lt;h4&gt;2. 统一执行 &lt;code&gt;micromamba&lt;/code&gt; 的函数&lt;/h4&gt;
&lt;p&gt;建议做一个包装器：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;_conda_exec_mamba() {
    if command -v micromamba &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then
        micromamba &quot;$@&quot;
    elif [[ -n &quot;$MAMBA_EXE&quot; &amp;amp;&amp;amp; -x &quot;$MAMBA_EXE&quot; ]]; then
        &quot;$MAMBA_EXE&quot; &quot;$@&quot;
    else
        echo &quot;未找到 micromamba，请先完成 micromamba 初始化。&quot; &amp;gt;&amp;amp;2
        return 127
    fi
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个函数解决两个问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;micromamba&lt;/code&gt; 在某些子 shell 中可能不在 PATH&lt;/li&gt;
&lt;li&gt;但 &lt;code&gt;MAMBA_EXE&lt;/code&gt; 可能已经可用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;统一封装后，你后续所有转发都走它，避免到处重复写兜底逻辑。&lt;/p&gt;
&lt;h4&gt;3. 注册表加载器&lt;/h4&gt;
&lt;p&gt;这是最关键的一部分。思路是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用 &lt;code&gt;python3&lt;/code&gt; 解析 JSON&lt;/li&gt;
&lt;li&gt;输出 tab 分隔的数据&lt;/li&gt;
&lt;li&gt;zsh 再把这些内容读进关联数组&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;典型实现思路如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;_conda_load_command_registry() {
    (( _CONDA_CMD_REGISTRY_LOADED )) &amp;amp;&amp;amp; return 0
    [[ -f &quot;$_CONDA_CMD_REGISTRY_FILE&quot; ]] || return 1

    local key type target desc
    while IFS=$&apos;\t&apos; read -r key type target desc; do
        [[ -z &quot;$key&quot; || -z &quot;$type&quot; || -z &quot;$target&quot; ]] &amp;amp;&amp;amp; continue
        _CONDA_CMD_TYPE_MAP[$key]=&quot;$type&quot;
        _CONDA_CMD_TARGET_MAP[$key]=&quot;$target&quot;
        _CONDA_CMD_DESC_MAP[$key]=&quot;$desc&quot;
    done &amp;lt; &amp;lt;(
        python3 - &quot;$_CONDA_CMD_REGISTRY_FILE&quot; &amp;lt;&amp;lt;&apos;PY&apos;
import json
import sys

path = sys.argv[1]
with open(path, &quot;r&quot;, encoding=&quot;utf-8&quot;) as f:
    data = json.load(f)

for key, spec in data.get(&quot;commands&quot;, {}).items():
    cmd_type = str(spec.get(&quot;type&quot;, &quot;&quot;)).strip()
    target = str(spec.get(&quot;target&quot;, &quot;&quot;)).strip()
    desc = str(spec.get(&quot;description&quot;, &quot;&quot;)).strip()
    desc = desc.replace(&quot;\t&quot;, &quot; &quot;).replace(&quot;\n&quot;, &quot; &quot;)
    if key and cmd_type and target:
        print(f&quot;{key}\t{cmd_type}\t{target}\t{desc}&quot;)
PY
    )

    _CONDA_CMD_REGISTRY_LOADED=1
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里有几个细节很重要：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;read -r key type target desc&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;必须读 4 列&lt;/li&gt;
&lt;li&gt;如果只读 3 列，&lt;code&gt;description&lt;/code&gt; 就不会进缓存&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;desc.replace(&quot;\t&quot;, &quot; &quot;).replace(&quot;\n&quot;, &quot; &quot;)&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;防止描述里出现换行或 tab，破坏 shell 侧解析&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;_CONDA_CMD_REGISTRY_LOADED&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;避免每次都反复解析 JSON，提高性能&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;4. 通用分发器&lt;/h4&gt;
&lt;p&gt;分发器根据注册表决定如何执行命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;_conda_dispatch() {
    local subcommand=&quot;$1&quot;
    shift

    _conda_load_command_registry || return 1

    local cmd_type=&quot;${_CONDA_CMD_TYPE_MAP[$subcommand]}&quot;
    local target=&quot;${_CONDA_CMD_TARGET_MAP[$subcommand]}&quot;
    [[ -z &quot;$cmd_type&quot; || -z &quot;$target&quot; ]] &amp;amp;&amp;amp; return 1

    case &quot;$cmd_type&quot; in
        function)
            if typeset -f &quot;$target&quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then
                &quot;$target&quot; &quot;$@&quot;
            else
                echo &quot;conda 子命令 &apos;$subcommand&apos; 对应函数 &apos;$target&apos; 不存在。&quot; &amp;gt;&amp;amp;2
                return 1
            fi
            ;;
        micromamba)
            _conda_exec_mamba &quot;$target&quot; &quot;$@&quot;
            ;;
        *)
            echo &quot;conda 子命令 &apos;$subcommand&apos; 的类型 &apos;$cmd_type&apos; 不支持。&quot; &amp;gt;&amp;amp;2
            return 1
            ;;
    esac
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这段逻辑的价值在于：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;conda&lt;/code&gt; 本身不再关心每个命令细节&lt;/li&gt;
&lt;li&gt;它只负责查注册表，然后调用正确执行方式&lt;/li&gt;
&lt;li&gt;后续如果你想支持更多类型，比如：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;alias&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;script&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;shell&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;python&lt;/code&gt;
也可以继续扩展&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;5. 自定义 help 输出&lt;/h4&gt;
&lt;p&gt;当用户只输入 &lt;code&gt;conda&lt;/code&gt; 时，希望除了原生 &lt;code&gt;micromamba&lt;/code&gt; help，还能看到自定义命令及说明。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;_conda_print_custom_help() {
    _conda_load_command_registry || return 0

    local cmd
    echo &quot;&quot;
    echo &quot;Custom subcommands:&quot;
    for cmd in ${(k)_CONDA_CMD_TYPE_MAP}; do
        local desc=&quot;${_CONDA_CMD_DESC_MAP[$cmd]}&quot;
        if [[ -n &quot;$desc&quot; ]]; then
            echo &quot;  ${cmd} - ${desc}&quot;
        else
            echo &quot;  ${cmd}&quot;
        fi
    done
    echo &quot;&quot;
    echo &quot;Use &apos;conda &amp;lt;subcommand&amp;gt; ...&apos; to run a custom command.&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出效果类似：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Custom subcommands:
  de - 停用当前环境（等价于 micromamba deactivate）。
  ac - 根据当前目录匹配 ~/.conda_map.ini 并激活对应环境（可用于手动触发）。
  map - 维护路径-&amp;gt;环境映射：map curr 写入当前目录；map 打开 ~/.conda_map.ini。

Use &apos;conda &amp;lt;subcommand&amp;gt; ...&apos; to run a custom command.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样用户执行 &lt;code&gt;conda&lt;/code&gt; 时，既不会丢掉原生帮助，又能顺便看到你自己的扩展命令。&lt;/p&gt;
&lt;h4&gt;6. &lt;code&gt;conda()&lt;/code&gt; 统一入口&lt;/h4&gt;
&lt;p&gt;最后把入口收束成一个非常干净的函数：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;conda() {
    if [[ $# -eq 0 ]]; then
        _conda_exec_mamba
        _conda_print_custom_help
        return 0
    fi

    local subcommand=&quot;$1&quot;
    if [[ -n &quot;$subcommand&quot; ]] &amp;amp;&amp;amp; _conda_dispatch &quot;$subcommand&quot; &quot;${@:2}&quot;; then
        return $?
    fi
    _conda_exec_mamba &quot;$@&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里的行为很自然：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;无参数：显示原生 help + 自定义 help&lt;/li&gt;
&lt;li&gt;注册命令：走自定义逻辑&lt;/li&gt;
&lt;li&gt;非注册命令：回落到原始 &lt;code&gt;micromamba&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这就是整个框架的主入口。&lt;/p&gt;
&lt;h2&gt;五、如何实现具体子命令&lt;/h2&gt;
&lt;h3&gt;1. &lt;code&gt;ac&lt;/code&gt;：根据目录映射激活环境&lt;/h3&gt;
&lt;p&gt;这个命令通常会依赖两个辅助函数：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;_load_auto_map&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;_find_env_for_dir&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;然后由 &lt;code&gt;_auto_activate_on_cd&lt;/code&gt; 决定是否切换环境，最后由 &lt;code&gt;_conda_cmd_ac&lt;/code&gt; 调用它。&lt;/p&gt;
&lt;p&gt;思路如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;读取 &lt;code&gt;~/.conda_map.ini&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;找到与当前目录最匹配的前缀&lt;/li&gt;
&lt;li&gt;如果找到目标环境且当前环境不同，则执行 &lt;code&gt;conda activate&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;如果没找到目标环境且当前环境不是 &lt;code&gt;base&lt;/code&gt;，则执行 &lt;code&gt;conda deactivate&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这样你只需要运行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;conda ac
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;就可以手动按目录切环境。&lt;/p&gt;
&lt;h3&gt;2. &lt;code&gt;de&lt;/code&gt;：快速停用环境&lt;/h3&gt;
&lt;p&gt;这个命令最适合注册成 &lt;code&gt;micromamba&lt;/code&gt; 类型：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;de&quot;: {
  &quot;type&quot;: &quot;micromamba&quot;,
  &quot;target&quot;: &quot;deactivate&quot;,
  &quot;description&quot;: &quot;停用当前环境（等价于 micromamba deactivate）。&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样无需写实现函数，框架会自动转发到：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;micromamba deactivate
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;优点是非常轻量。&lt;/p&gt;
&lt;h3&gt;3. &lt;code&gt;map&lt;/code&gt;：维护目录和环境映射&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;map&lt;/code&gt; 适合写成函数型命令，因为它有分支逻辑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;conda map curr&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;把当前目录和当前激活环境写入 &lt;code&gt;~/.conda_map.ini&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;conda map&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;直接打开 &lt;code&gt;~/.conda_map.ini&lt;/code&gt; 编辑&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这类“带业务状态、带文件读写”的命令，用函数承载更清晰。&lt;/p&gt;
&lt;h2&gt;六、目录环境映射文件怎么设计&lt;/h2&gt;
&lt;p&gt;映射文件 &lt;code&gt;~/.conda_map.ini&lt;/code&gt; 可以做成很简单的键值格式：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/home/niuhongkai/project/a = py38
/home/niuhongkai/project/b = ml
/home/niuhongkai/workspace/demo = testenv
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;解析规则可以是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一行一个映射&lt;/li&gt;
&lt;li&gt;&lt;code&gt;=&lt;/code&gt; 左边是目录&lt;/li&gt;
&lt;li&gt;&lt;code&gt;=&lt;/code&gt; 右边是环境名&lt;/li&gt;
&lt;li&gt;支持注释行&lt;/li&gt;
&lt;li&gt;支持去除首尾空白&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;匹配时使用“最长前缀优先”，例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;当前目录：&lt;code&gt;/home/niuhongkai/project/a/subdir&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;已有映射：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/home/niuhongkai/project = base-env&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/home/niuhongkai/project/a = py38&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最终应选择 &lt;code&gt;py38&lt;/code&gt;，因为它的路径前缀更长、更具体。&lt;/p&gt;
&lt;p&gt;这是很实用的一个策略。&lt;/p&gt;
&lt;h2&gt;七、新增一个子命令要怎么做&lt;/h2&gt;
&lt;p&gt;这是这套框架最重要的价值所在。&lt;/p&gt;
&lt;p&gt;假设你想新增一个 &lt;code&gt;conda lsmap&lt;/code&gt;，用于打印当前所有映射。&lt;/p&gt;
&lt;h3&gt;方式一：函数型命令&lt;/h3&gt;
&lt;p&gt;先在 JSON 中注册：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;lsmap&quot;: {
  &quot;type&quot;: &quot;function&quot;,
  &quot;target&quot;: &quot;_conda_cmd_lsmap&quot;,
  &quot;description&quot;: &quot;列出当前所有目录到环境的映射。&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;再在 &lt;code&gt;conda-wrapper.zsh&lt;/code&gt; 中实现：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;_conda_cmd_lsmap() {
    local file=&quot;$HOME/.conda_map.ini&quot;
    if [[ ! -f &quot;$file&quot; ]]; then
        echo &quot;映射文件不存在：$file&quot;
        return 1
    fi
    sed &apos;/^\s*[#;]/d; /^\s*$/d&apos; &quot;$file&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后重新加载：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;source ~/.zshrc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;现在就能使用：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;conda lsmap
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;并且 &lt;code&gt;conda&lt;/code&gt; help 中也会自动出现对应说明。&lt;/p&gt;
&lt;h3&gt;方式二：直接转发到 &lt;code&gt;micromamba&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;如果你只是想做某个简短别名，也可以直接注册成 &lt;code&gt;micromamba&lt;/code&gt; 类型。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;rm&quot;: {
  &quot;type&quot;: &quot;micromamba&quot;,
  &quot;target&quot;: &quot;remove&quot;,
  &quot;description&quot;: &quot;删除当前环境中的包（等价于 micromamba remove）。&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样就能用：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;conda rm numpy
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;它会等价执行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;micromamba remove numpy
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;八、为什么这种设计比在 &lt;code&gt;~/.zshrc&lt;/code&gt; 里硬写 &lt;code&gt;case&lt;/code&gt; 更好&lt;/h2&gt;
&lt;h3&gt;1. 结构更清晰&lt;/h3&gt;
&lt;p&gt;原先所有逻辑混在一个函数里，新增命令时越来越乱。现在分成：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;注册&lt;/li&gt;
&lt;li&gt;分发&lt;/li&gt;
&lt;li&gt;实现&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;职责很明确。&lt;/p&gt;
&lt;h3&gt;2. 扩展成本更低&lt;/h3&gt;
&lt;p&gt;新增命令只需要：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;改 JSON&lt;/li&gt;
&lt;li&gt;加函数&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不需要反复修改分发主逻辑。&lt;/p&gt;
&lt;h3&gt;3. help 自动生成&lt;/h3&gt;
&lt;p&gt;命令和说明写在同一个 JSON 中，不容易出现“实现变了、帮助文案没改”的情况。&lt;/p&gt;
&lt;h3&gt;4. &lt;code&gt;~/.zshrc&lt;/code&gt; 更干净&lt;/h3&gt;
&lt;p&gt;把复杂逻辑移出 &lt;code&gt;~/.zshrc&lt;/code&gt; 后，shell 初始化文件更易读，也更方便迁移和备份。&lt;/p&gt;
&lt;h3&gt;5. 后续可继续演化&lt;/h3&gt;
&lt;p&gt;比如未来你可以进一步加上：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;hidden: true&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;usage&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;examples&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;aliases&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;group&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;order&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;把这个小框架逐步做成真正可维护的 CLI 扩展层。&lt;/p&gt;
&lt;h2&gt;九、部署时的常见坑&lt;/h2&gt;
&lt;h3&gt;1. &lt;code&gt;description&lt;/code&gt; 没显示&lt;/h3&gt;
&lt;p&gt;这是最容易踩的坑之一。&lt;/p&gt;
&lt;p&gt;如果你 JSON 里有：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;description&quot;: &quot;xxx&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但 help 里没显示，通常原因是 shell 读取时没有把描述字段读出来。&lt;/p&gt;
&lt;p&gt;比如如果你写成：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;while IFS=$&apos;\t&apos; read -r key type target; do
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;那就只读了 3 列，第四列 &lt;code&gt;desc&lt;/code&gt; 会丢失。&lt;/p&gt;
&lt;p&gt;正确写法必须是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;while IFS=$&apos;\t&apos; read -r key type target desc; do
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;并且要写入：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;_CONDA_CMD_DESC_MAP[$key]=&quot;$desc&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. &lt;code&gt;micromamba&lt;/code&gt; 在某些 shell 中不可用&lt;/h3&gt;
&lt;p&gt;有时你手动 &lt;code&gt;source&lt;/code&gt; 某个文件时，&lt;code&gt;micromamba&lt;/code&gt; 不一定在 PATH 里。建议统一通过 &lt;code&gt;_conda_exec_mamba&lt;/code&gt; 执行，并回退到 &lt;code&gt;$MAMBA_EXE&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;否则会出现：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;command not found: micromamba
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. JSON 描述里包含换行或 tab&lt;/h3&gt;
&lt;p&gt;如果你直接把 JSON 的 &lt;code&gt;description&lt;/code&gt; 原样打印为 tab 分隔数据，shell 解析时可能错位。&lt;/p&gt;
&lt;p&gt;建议在 Python 侧先做清理：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;desc = desc.replace(&quot;\t&quot;, &quot; &quot;).replace(&quot;\n&quot;, &quot; &quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4. &lt;code&gt;activate&lt;/code&gt; / &lt;code&gt;deactivate&lt;/code&gt; 需要在 shell 环境生效&lt;/h3&gt;
&lt;p&gt;环境切换不是普通可执行程序逻辑。如果 &lt;code&gt;micromamba shell hook&lt;/code&gt; 没有正确初始化，&lt;code&gt;activate/deactivate&lt;/code&gt; 就可能行为不符合预期。&lt;/p&gt;
&lt;p&gt;所以一定要确保 &lt;code&gt;mamba initialize&lt;/code&gt; 块有效。&lt;/p&gt;
&lt;h2&gt;十、可以继续增强的方向&lt;/h2&gt;
&lt;p&gt;这套框架已经够实用，但如果你想把它继续产品化，还可以加这些能力。&lt;/p&gt;
&lt;h3&gt;1. 命令顺序控制&lt;/h3&gt;
&lt;p&gt;现在 help 中的顺序通常取决于解析和关联数组的枚举方式，不一定稳定。你可以在 JSON 中增加：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;order&quot;: 10
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后在 Python 解析时按 &lt;code&gt;order&lt;/code&gt; 排序输出。&lt;/p&gt;
&lt;h3&gt;2. 支持别名&lt;/h3&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;deactivate&quot;: {
  &quot;type&quot;: &quot;micromamba&quot;,
  &quot;target&quot;: &quot;deactivate&quot;,
  &quot;description&quot;: &quot;停用当前环境。&quot;,
  &quot;aliases&quot;: [&quot;de&quot;]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样 help 中可以同时显示别名，或者允许多个入口指向同一个实现。&lt;/p&gt;
&lt;h3&gt;3. 支持示例输出&lt;/h3&gt;
&lt;p&gt;增加：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;examples&quot;: [
  &quot;conda map curr&quot;,
  &quot;conda ac&quot;
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后在 &lt;code&gt;conda help &amp;lt;subcommand&amp;gt;&lt;/code&gt; 中展示更详细帮助。&lt;/p&gt;
&lt;h3&gt;4. 支持 &lt;code&gt;conda commands&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;可以新增一个框架级命令，列出所有已注册命令及类型、说明，用于调试注册表。&lt;/p&gt;
&lt;h3&gt;5. 自动监听 &lt;code&gt;cd&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;你当前的自动激活逻辑如果只是手动调用 &lt;code&gt;conda ac&lt;/code&gt;，已经够稳。如果想进一步实现“每次 &lt;code&gt;cd&lt;/code&gt; 自动切环境”，可以挂载 &lt;code&gt;chpwd&lt;/code&gt; hook。&lt;/p&gt;
&lt;p&gt;不过这个行为更激进，建议先确认你确实需要，否则有时会让 shell 行为变得过于“主动”。&lt;/p&gt;
&lt;h2&gt;十一、一套可落地的最小工作流程&lt;/h2&gt;
&lt;p&gt;如果你现在要从零部署，推荐按下面顺序：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;保证 &lt;code&gt;micromamba shell init&lt;/code&gt; 已在 &lt;code&gt;~/.zshrc&lt;/code&gt; 中生效&lt;/li&gt;
&lt;li&gt;新建目录：&lt;pre&gt;&lt;code&gt;mkdir -p ~/.zsh
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;创建注册表：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;~/.zsh/conda-commands.json&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;创建主逻辑文件：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;~/.zsh/conda-wrapper.zsh&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;在 &lt;code&gt;~/.zshrc&lt;/code&gt; 中加入：&lt;pre&gt;&lt;code&gt;source &quot;$HOME/.zsh/conda-wrapper.zsh&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;重新加载：&lt;pre&gt;&lt;code&gt;source ~/.zshrc
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;验证：&lt;pre&gt;&lt;code&gt;conda
conda ac
conda de
conda map
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;十二、总结&lt;/h2&gt;
&lt;p&gt;这套方案本质上是把 shell 中零散的“命令快捷方式”升级成了一个简易命令框架。&lt;/p&gt;
&lt;p&gt;它的核心价值不在于“能不能跑”，而在于：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;是否容易维护&lt;/li&gt;
&lt;li&gt;是否容易扩展&lt;/li&gt;
&lt;li&gt;是否能把命令定义、说明和实现分开&lt;/li&gt;
&lt;li&gt;是否能让 &lt;code&gt;~/.zshrc&lt;/code&gt; 保持干净&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;通过 &lt;code&gt;JSON 注册 + 通用分发 + 独立实现&lt;/code&gt; 这三层结构，你就可以把原本容易失控的 &lt;code&gt;conda()&lt;/code&gt; 包装函数，整理成一个长期可演进的小系统。&lt;/p&gt;
&lt;p&gt;如果你的 shell 中已经存在越来越多的“我自己常用的小命令”，这类思路其实不只适用于 &lt;code&gt;conda&lt;/code&gt;，同样也可以推广到：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git&lt;/code&gt; 增强命令&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker&lt;/code&gt; 快捷命令&lt;/li&gt;
&lt;li&gt;项目脚手架命令&lt;/li&gt;
&lt;li&gt;本地开发环境切换命令&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一句话总结：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;把 shell 自定义从“堆脚本”升级成“可注册的命令层”，你会明显感受到维护成本下降。&lt;/strong&gt;&lt;/p&gt;
</content:encoded></item><item><title>机器学习 环境配置</title><link>https://pinellia.uk/posts/mechine-learning-env/</link><guid isPermaLink="true">https://pinellia.uk/posts/mechine-learning-env/</guid><description>如何在无root权限的服务器上进行初步环境配置？ conda 隔离一切</description><pubDate>Tue, 28 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;conda-&amp;gt;micromamba&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;micromamba &lt;/code&gt; 是一个使用 &lt;code&gt;conda-forge&lt;/code&gt;  channel 的 conda 替代品，优势如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;为静态链接的 C++ 可执行文件，速度快&lt;/li&gt;
&lt;li&gt;默认采用 &lt;code&gt;conda-forge&lt;/code&gt; channel 更新更全&lt;/li&gt;
&lt;li&gt;非root环境下易于安装卸载，同时占用空间极小&lt;/li&gt;
&lt;li&gt;拥有更全面的提示以及进度条&lt;/li&gt;
&lt;li&gt;没有conda的环境嵌套激活问题，用着放心&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;[!TIP]
现在可以使用conda进行jdk,node,甚至cuda的安装管理以及隔离&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;how 2 install&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!TIP]
鉴于 homebrew 下载较为臃肿，不建议使用 homebrew&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;官方指导：&lt;a href=&quot;https://mamba.readthedocs.io/en/latest/installation/micromamba-installation.html&quot;&gt;link&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;mac, linux, windows git bash:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;${SHELL}&quot; &amp;lt;(curl -L micro.mamba.pm/install.sh)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;自动升级：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;micromamba self-update
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;conda 环境自动加载&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;使用bashrc自动加载(&lt;strong&gt;仅在终端创建时自动&lt;/strong&gt;)文件夹的 conda 环境&lt;/p&gt;
&lt;p&gt;可使用man命令来加载最合适的环境(未指定则用父文件夹的)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- ~/.zshrc --&amp;gt;
# --- 自动按路径激活 micromamba 环境（从 ~/.conda_map.ini 读取） ---
_load_auto_map() {
    local file=&quot;$HOME/.conda_map.ini&quot;
    typeset -gA AUTO_ACTIVATE_MAP
    [[ -f &quot;$file&quot; ]] || return
    local line key val
    while IFS= read -r line || [[ -n &quot;$line&quot; ]]; do
        # 删除注释（# 或 ;）和首尾空白
        line=&quot;${line%%[#;]*}&quot;
        line=&quot;${line#&quot;${line%%[![:space:]]*}&quot;}&quot;
        line=&quot;${line%&quot;${line##*[![:space:]]}&quot;}&quot;
        [[ -z &quot;$line&quot; ]] &amp;amp;&amp;amp; continue
        if [[ &quot;$line&quot; == *=* ]]; then
            key=&quot;${line%%=*}&quot;
            val=&quot;${line#*=}&quot;
            key=&quot;${key#&quot;${key%%[![:space:]]*}&quot;}&quot;; key=&quot;${key%&quot;${key##*[![:space:]]}&quot;}&quot;
            val=&quot;${val#&quot;${val%%[![:space:]]*}&quot;}&quot;; val=&quot;${val%&quot;${val##*[![:space:]]}&quot;}&quot;
            AUTO_ACTIVATE_MAP[$key]=&quot;$val&quot;
        fi
    done &amp;lt; &quot;$file&quot;
}

_find_env_for_dir() {
    local pwd=&quot;$PWD&quot;
    local best_prefix=&quot;&quot;
    local best_env=&quot;&quot;
    local prefix
    for prefix in &quot;${(@k)AUTO_ACTIVATE_MAP}&quot;; do
        # 确保以目录前缀匹配（支持不带斜杠的写法）
        if [[ &quot;${pwd%/}&quot; == &quot;${prefix%/}&quot;* ]]; then
            if (( ${#prefix} &amp;gt; ${#best_prefix} )); then
                best_prefix=&quot;$prefix&quot;
                best_env=&quot;${AUTO_ACTIVATE_MAP[$prefix]}&quot;
            fi
        fi
    done
    printf &apos;%s&apos; &quot;$best_env&quot;
}

_auto_activate_on_cd() {
    _load_auto_map
    local target_env cur_env
    target_env=&quot;$(_find_env_for_dir)&quot;

    cur_env=&quot;${CONDA_DEFAULT_ENV:-}&quot;
    if [[ -z &quot;$cur_env&quot; &amp;amp;&amp;amp; -n &quot;$CONDA_PREFIX&quot; ]]; then
        cur_env=&quot;$(basename &quot;$CONDA_PREFIX&quot;)&quot;
    fi

    if [[ -n &quot;$target_env&quot; ]]; then
        if [[ &quot;$cur_env&quot; != &quot;$target_env&quot; ]]; then
            conda activate &quot;$target_env&quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || true
        fi
    else
        if [[ -n &quot;$cur_env&quot; &amp;amp;&amp;amp; &quot;$cur_env&quot; != &quot;base&quot; ]]; then
            conda deactivate &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || true
        fi
    fi
}
_auto_activate_on_cd
alias ac=_auto_activate_on_cd
# ac 来手动激活对应环境（前缀匹配激活，子文件夹都可用）
# --- 结束 自动激活 ---
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- ~/.bashrc --&amp;gt;
# --- 自动按路径激活 micromamba 环境（从 ~/.conda_map.ini 读取） ---
_load_auto_map() {
    local file=&quot;$HOME/.conda_map.ini&quot;
    # 使用全局关联数组
    declare -gA AUTO_ACTIVATE_MAP=()
    [[ -f &quot;$file&quot; ]] || return
    local line key val
    while IFS= read -r line || [[ -n &quot;$line&quot; ]]; do
        # 删除注释（# 或 ;）和首尾空白
        line=&quot;${line%%[#;]*}&quot;
        line=&quot;${line#&quot;${line%%[![:space:]]*}&quot;}&quot;
        line=&quot;${line%&quot;${line##*[![:space:]]}&quot;}&quot;
        [[ -z &quot;$line&quot; ]] &amp;amp;&amp;amp; continue
        if [[ &quot;$line&quot; =~ ^([^=]+)=(.+)$ ]]; then
            key=&quot;${BASH_REMATCH[1]}&quot;
            val=&quot;${BASH_REMATCH[2]}&quot;
            key=&quot;${key#&quot;${key%%[![:space:]]*}&quot;}&quot;; key=&quot;${key%&quot;${key##*[![:space:]]}&quot;}&quot;
            val=&quot;${val#&quot;${val%%[![:space:]]*}&quot;}&quot;; val=&quot;${val%&quot;${val##*[![:space:]]}&quot;}&quot;
            AUTO_ACTIVATE_MAP[&quot;$key&quot;]=&quot;$val&quot;
        fi
    done &amp;lt; &quot;$file&quot;
}

_find_env_for_dir() {
    local pwd=&quot;$PWD&quot;
    local best_prefix=&quot;&quot;
    local best_env=&quot;&quot;
    local prefix
    for prefix in &quot;${!AUTO_ACTIVATE_MAP[@]}&quot;; do
        # 确保以目录前缀匹配（支持不带斜杠的写法）
        if [[ &quot;${pwd%/}&quot; == &quot;${prefix%/}&quot;* ]]; then
            if (( ${#prefix} &amp;gt; ${#best_prefix} )); then
                best_prefix=&quot;$prefix&quot;
                best_env=&quot;${AUTO_ACTIVATE_MAP[$prefix]}&quot;
            fi
        fi
    done
    printf &apos;%s&apos; &quot;$best_env&quot;
}

_auto_activate_on_cd() {
    _load_auto_map
    local target_env cur_env
    target_env=&quot;$(_find_env_for_dir)&quot;

    cur_env=&quot;${CONDA_DEFAULT_ENV:-}&quot;
    if [[ -z &quot;$cur_env&quot; &amp;amp;&amp;amp; -n &quot;$CONDA_PREFIX&quot; ]]; then
        cur_env=&quot;$(basename &quot;$CONDA_PREFIX&quot;)&quot;
    fi

    if [[ -n &quot;$target_env&quot; ]]; then
        if [[ &quot;$cur_env&quot; != &quot;$target_env&quot; ]]; then
            conda activate &quot;$target_env&quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || true
        fi
    else
        if [[ -n &quot;$cur_env&quot; &amp;amp;&amp;amp; &quot;$cur_env&quot; != &quot;base&quot; ]]; then
            conda deactivate &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || true
        fi
    fi
}
_auto_activate_on_cd
alias ac=_auto_activate_on_cd
# ac 来手动激活对应环境（前缀匹配激活，子文件夹都可用）
# --- 结束 自动激活 ---
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;总结&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;推荐使用 &lt;code&gt;Miniconda&lt;/code&gt;，日常使用稳定，缺点是环境构建稍慢。&lt;/li&gt;
&lt;li&gt;可尝试 &lt;code&gt;conda-forge + mamba&lt;/code&gt;，但部分 forge channel 可能体验一般。&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>mihomo 设置指南</title><link>https://pinellia.uk/posts/mihomo-config/</link><guid isPermaLink="true">https://pinellia.uk/posts/mihomo-config/</guid><description>配置文件的补充说明</description><pubDate>Sun, 05 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Android&lt;/h1&gt;
&lt;p&gt;机端新模块&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;adb push /Users/nhk/Downloads/TT/Clash配置.yaml /sdcard/Android/Clash
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;MAC&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;mac版本的 verge rev 天天死机，直接跑内核还快一点&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;macOS sudo mv mihomo.plist /Library/LaunchDaemons
# 加载服务
sudo launchctl load /Library/LaunchDaemons/mihomo.plist
# 查看服务
sudo launchctl list | grep mihomo
# 卸载停止服务
sudo launchctl unload /Library/LaunchDaemons/mihomo.plist

# 启动服务
sudo launchctl start mihomo
# 停止服务
sudo launchctl stop mihomo


&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>vscode mac c++ 环境配置</title><link>https://pinellia.uk/posts/vscode-mac-cpp/</link><guid isPermaLink="true">https://pinellia.uk/posts/vscode-mac-cpp/</guid><description>配置 vscode mac c++ 运行调试环境</description><pubDate>Wed, 27 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;使用的插件&lt;/h1&gt;
&lt;p&gt;C++系列，code runner&lt;/p&gt;
&lt;h1&gt;配置文件&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;tasks/launch 文件用来完善f5调试&lt;/li&gt;
&lt;li&gt;settings 文件主要用来完善cpp代码万能头，以及 code runner 运行参数&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- launch.json --&amp;gt;
{
    &quot;version&quot;: &quot;0.2.0&quot;,
    &quot;configurations&quot;: [
        {
            &quot;name&quot;: &quot;Debug C++&quot;,
            &quot;type&quot;: &quot;lldb&quot;,
            &quot;request&quot;: &quot;launch&quot;,
            &quot;program&quot;: &quot;${fileDirname}/bin/${fileBasenameNoExtension}&quot;,
            &quot;args&quot;: [],
            &quot;cwd&quot;: &quot;${workspaceFolder}&quot;,
            &quot;preLaunchTask&quot;: &quot;build&quot;,
            &quot;console&quot;: &quot;integratedTerminal&quot;
        }
    ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- tasks.json --&amp;gt;
{
    &quot;version&quot;: &quot;2.0.0&quot;,
    &quot;tasks&quot;: [
        {
            &quot;label&quot;: &quot;build&quot;,
            &quot;type&quot;: &quot;shell&quot;,
            &quot;command&quot;: &quot;mkdir&quot;,
            &quot;args&quot;: [
                &quot;-p&quot;,
                &quot;${fileDirname}/bin&quot;,
                &quot;&amp;amp;&amp;amp;&quot;,
                &quot;g++&quot;,
                &quot;-std=c++17&quot;,
                &quot;-g&quot;,
                &quot;${file}&quot;,
                &quot;-o&quot;,
                &quot;${fileDirname}/bin/${fileBasenameNoExtension}&quot;
            ],
            &quot;group&quot;: &quot;build&quot;,
            &quot;problemMatcher&quot;: [
                &quot;$gcc&quot;
            ]
        }
    ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!--settings.json -&amp;gt;
{
    // C++扩展配置
    &quot;C_Cpp.default.includePath&quot;: [
        &quot;${workspaceFolder}/cpp_includes&quot;,
        &quot;${workspaceFolder}/**&quot;
    ],
    &quot;C_Cpp.default.compilerPath&quot;: &quot;/usr/bin/g++&quot;,
    &quot;C_Cpp.default.cppStandard&quot;: &quot;c++17&quot;,
    &quot;C_Cpp.default.intelliSenseMode&quot;: &quot;macos-gcc-arm64&quot;,

    // Code Runner配置 - 与C++扩展保持一致的头文件路径
    &quot;code-runner.executorMap&quot;: {
        &quot;cpp&quot;: &quot;cd$workspaceRoot &amp;amp;&amp;amp; mkdir -p bin &amp;amp;&amp;amp; g++ -std=c++17 -O2 -g -I cpp_includes $fullFileName -o ./bin/$fileNameWithoutExt &amp;amp;&amp;amp; ./bin/$fileNameWithoutExt&quot;
    },
    &quot;code-runner.runInTerminal&quot;: true,
    &quot;code-runner.saveFileBeforeRun&quot;: true,
    &quot;code-runner.clearPreviousOutput&quot;: false,
    &quot;code-runner.preserveFocus&quot;: false,
    &quot;code-runner.showExecutionMessage&quot;: true,

    // 文件关联
    &quot;files.associations&quot;: {
        &quot;*.h&quot;: &quot;cpp&quot;,
        &quot;*.hpp&quot;: &quot;cpp&quot;,
        &quot;*.cpp&quot;: &quot;cpp&quot;,
        &quot;*.cc&quot;: &quot;cpp&quot;,
        &quot;*.cxx&quot;: &quot;cpp&quot;
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>leetcode刷题列表</title><link>https://pinellia.uk/posts/leetcode-list/</link><guid isPermaLink="true">https://pinellia.uk/posts/leetcode-list/</guid><description>力扣文字刷题列表</description><pubDate>Tue, 26 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;第⼀章、基础数据结构&lt;/h2&gt;
&lt;h3&gt;数组双指针&lt;/h3&gt;
&lt;h4&gt;⼆分搜索&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;在排序数组中查找元素的第⼀个和最后⼀个位置&lt;/li&gt;
&lt;li&gt;⼆分查找&lt;/li&gt;
&lt;li&gt;搜索插⼊位置&lt;/li&gt;
&lt;li&gt;俄罗斯套娃信封问题&lt;/li&gt;
&lt;li&gt;判断⼦序列&lt;/li&gt;
&lt;li&gt;阶乘函数后 K 个零&lt;/li&gt;
&lt;li&gt;爱吃⾹蕉的珂珂&lt;/li&gt;
&lt;li&gt;在 D 天内送达包裹的能⼒&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;滑动窗⼝&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;⽆重复字符的最⻓⼦串&lt;/li&gt;
&lt;li&gt;最⼩覆盖⼦串&lt;/li&gt;
&lt;li&gt;找到字符串中所有字⺟异位词&lt;/li&gt;
&lt;li&gt;字符串的排列&lt;/li&gt;
&lt;li&gt;滑动窗⼝最⼤值&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;其他题⽬&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;三数之和&lt;/li&gt;
&lt;li&gt;四数之和&lt;/li&gt;
&lt;li&gt;⼩于 K 的两数之和&lt;/li&gt;
&lt;li&gt;删除有序数组中的重复项&lt;/li&gt;
&lt;li&gt;移除元素&lt;/li&gt;
&lt;li&gt;移动零&lt;/li&gt;
&lt;li&gt;最接近的三数之和&lt;/li&gt;
&lt;li&gt;区间列表的交集&lt;/li&gt;
&lt;li&gt;盛最多⽔的容器&lt;/li&gt;
&lt;li&gt;接⾬⽔&lt;/li&gt;
&lt;li&gt;优势洗牌&lt;/li&gt;
&lt;li&gt;较⼩的三数之和&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;链表双指针&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;两数相加&lt;/li&gt;
&lt;li&gt;删除链表的倒数第 N 个结点&lt;/li&gt;
&lt;li&gt;合并两个有序链表&lt;/li&gt;
&lt;li&gt;合并 K 个升序链表&lt;/li&gt;
&lt;li&gt;环形链表&lt;/li&gt;
&lt;li&gt;环形链表 II&lt;/li&gt;
&lt;li&gt;相交链表&lt;/li&gt;
&lt;li&gt;链表的中间结点&lt;/li&gt;
&lt;li&gt;K 个⼀组翻转链表&lt;/li&gt;
&lt;li&gt;删除排序链表中的重复元素&lt;/li&gt;
&lt;li&gt;反转链表 II&lt;/li&gt;
&lt;li&gt;回⽂链表&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;前缀和&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;区域和检索 - 数组不可变&lt;/li&gt;
&lt;li&gt;⼆维区域和检索 - 矩阵不可变&lt;/li&gt;
&lt;li&gt;和为 K 的⼦数组&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;差分数组&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;区间加法&lt;/li&gt;
&lt;li&gt;拼⻋&lt;/li&gt;
&lt;li&gt;航班预订统计&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;队列/栈算法&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;有效的括号&lt;/li&gt;
&lt;li&gt;使括号有效的最少添加&lt;/li&gt;
&lt;li&gt;平衡括号字符串的最少插⼊次数&lt;/li&gt;
&lt;li&gt;最⻓有效括号&lt;/li&gt;
&lt;li&gt;⽤队列实现栈&lt;/li&gt;
&lt;li&gt;⽤栈实现队列&lt;/li&gt;
&lt;li&gt;滑动窗⼝最⼤值&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;⼆叉堆&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;合并 K 个升序链表&lt;/li&gt;
&lt;li&gt;数组中的第 K 个最⼤元素&lt;/li&gt;
&lt;li&gt;数据流的中位数&lt;/li&gt;
&lt;li&gt;数据流中的第 K ⼤元素&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;数据结构设计&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;LRU 缓存机制&lt;/li&gt;
&lt;li&gt;扁平化嵌套列表迭代器&lt;/li&gt;
&lt;li&gt;O(1) 时间插⼊、删除和获取随机元素&lt;/li&gt;
&lt;li&gt;LFU 缓存&lt;/li&gt;
&lt;li&gt;最⼤频率栈&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;第⼆章、进阶数据结构&lt;/h2&gt;
&lt;h4&gt;⼆叉树&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;⼆叉树的中序遍历&lt;/li&gt;
&lt;li&gt;相同的树&lt;/li&gt;
&lt;li&gt;⼆叉树的层序遍历在线⽹站&lt;/li&gt;
&lt;li&gt;⼆叉树的锯⻮形层序遍历&lt;/li&gt;
&lt;li&gt;⼆叉树的最⼤深度&lt;/li&gt;
&lt;li&gt;从前序与中序遍历序列构造⼆叉树&lt;/li&gt;
&lt;li&gt;从中序与后序遍历序列构造⼆叉树&lt;/li&gt;
&lt;li&gt;最⼤⼆叉树&lt;/li&gt;
&lt;li&gt;⼆叉树的层序遍历 II&lt;/li&gt;
&lt;li&gt;⼆叉树的最⼩深度&lt;/li&gt;
&lt;li&gt;⼆叉树展开为链表&lt;/li&gt;
&lt;li&gt;填充每个节点的下⼀个右侧节点指针&lt;/li&gt;
&lt;li&gt;翻转⼆叉树&lt;/li&gt;
&lt;li&gt;⼆叉树的前序遍历&lt;/li&gt;
&lt;li&gt;⼆叉树的后序遍历&lt;/li&gt;
&lt;li&gt;完全⼆叉树的节点个数&lt;/li&gt;
&lt;li&gt;⼆叉树的最近公共祖先&lt;/li&gt;
&lt;li&gt;⼆叉树的序列化与反序列化&lt;/li&gt;
&lt;li&gt;扁平化嵌套列表迭代器&lt;/li&gt;
&lt;li&gt;⼆叉搜索树中的众数&lt;/li&gt;
&lt;li&gt;⼆叉树的直径&lt;/li&gt;
&lt;li&gt;N 叉树的最⼤深度&lt;/li&gt;
&lt;li&gt;N 叉树的前序遍历&lt;/li&gt;
&lt;li&gt;N 叉树的后序遍历&lt;/li&gt;
&lt;li&gt;寻找重复的⼦树&lt;/li&gt;
&lt;li&gt;单值⼆叉树&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;⼆叉搜索树&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;不同的⼆叉搜索树 II&lt;/li&gt;
&lt;li&gt;不同的⼆叉搜索树&lt;/li&gt;
&lt;li&gt;验证⼆叉搜索树&lt;/li&gt;
&lt;li&gt;删除⼆叉搜索树中的节点&lt;/li&gt;
&lt;li&gt;⼆叉搜索树中的搜索&lt;/li&gt;
&lt;li&gt;⼆叉搜索树中的插⼊操作&lt;/li&gt;
&lt;li&gt;⼆叉搜索树中第 K ⼩的元素&lt;/li&gt;
&lt;li&gt;把⼆叉搜索树转换为累加树&lt;/li&gt;
&lt;li&gt;把⼆叉搜索树转换为累加树&lt;/li&gt;
&lt;li&gt;⼆叉搜索树中的众数&lt;/li&gt;
&lt;li&gt;⼆叉搜索树的最⼩绝对差&lt;/li&gt;
&lt;li&gt;⼆叉搜索树节点最⼩距离&lt;/li&gt;
&lt;li&gt;⼆叉搜索⼦树的最⼤键值和&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;图论算法&lt;/h3&gt;
&lt;h4&gt;图的遍历&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;所有可能的路径&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;⼆分图&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;判断⼆分图&lt;/li&gt;
&lt;li&gt;可能的⼆分法#### 环检测/拓扑排序&lt;/li&gt;
&lt;li&gt;课程表&lt;/li&gt;
&lt;li&gt;课程表 II&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;并查集算法&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;被围绕的区域&lt;/li&gt;
&lt;li&gt;等式⽅程的可满⾜性&lt;/li&gt;
&lt;li&gt;情侣牵⼿&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;最⼩⽣成树&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;以图判树&lt;/li&gt;
&lt;li&gt;最低成本联通所有城市&lt;/li&gt;
&lt;li&gt;连接所有点的最⼩费⽤&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;最短路径&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;⽹络延迟时间&lt;/li&gt;
&lt;li&gt;概率最⼤的路径&lt;/li&gt;
&lt;li&gt;最⼩体⼒消耗路径&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;第三章、暴⼒搜索算法&lt;/h2&gt;
&lt;h4&gt;回溯算法&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;电话号码的字⺟组合&lt;/li&gt;
&lt;li&gt;括号⽣成&lt;/li&gt;
&lt;li&gt;解数独&lt;/li&gt;
&lt;li&gt;组合总和&lt;/li&gt;
&lt;li&gt;全排列&lt;/li&gt;
&lt;li&gt;组合&lt;/li&gt;
&lt;li&gt;⼦集&lt;/li&gt;
&lt;li&gt;N 皇后&lt;/li&gt;
&lt;li&gt;⼆叉树的最⼤深度&lt;/li&gt;
&lt;li&gt;⽬标和&lt;/li&gt;
&lt;li&gt;划分为 k 个相等的⼦集&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;DFS 算法&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;被围绕的区域&lt;/li&gt;
&lt;li&gt;岛屿数量&lt;/li&gt;
&lt;li&gt;不同的岛屿数量&lt;/li&gt;
&lt;li&gt;岛屿的最⼤⾯积&lt;/li&gt;
&lt;li&gt;⻜地的数量&lt;/li&gt;
&lt;li&gt;统计封闭岛屿的数⽬&lt;/li&gt;
&lt;li&gt;统计⼦岛屿&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;BFS 算法&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;⼆叉树的层序遍历&lt;/li&gt;
&lt;li&gt;⼆叉树的锯⻮形层序遍历&lt;/li&gt;
&lt;li&gt;⼆叉树的层序遍历 II&lt;/li&gt;
&lt;li&gt;⼆叉树的最⼩深度&lt;/li&gt;
&lt;li&gt;打开转盘锁&lt;/li&gt;
&lt;li&gt;滑动谜题&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;第四章、动态规划算法&lt;/h2&gt;
&lt;h4&gt;⼀维 DP&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;跳跃游戏 II&lt;/li&gt;
&lt;li&gt;跳跃游戏&lt;/li&gt;
&lt;li&gt;最⼤⼦序和&lt;/li&gt;
&lt;li&gt;爬楼梯&lt;/li&gt;
&lt;li&gt;打家劫舍&lt;/li&gt;
&lt;li&gt;打家劫舍 II&lt;/li&gt;
&lt;li&gt;打家劫舍 III&lt;/li&gt;
&lt;li&gt;最⻓递增⼦序列&lt;/li&gt;
&lt;li&gt;零钱兑换&lt;/li&gt;
&lt;li&gt;俄罗斯套娃信封问题&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;⼆维 DP&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;正则表达式匹配&lt;/li&gt;
&lt;li&gt;不同路径&lt;/li&gt;
&lt;li&gt;最⼩路径和&lt;/li&gt;
&lt;li&gt;编辑距离&lt;/li&gt;
&lt;li&gt;买卖股票的最佳时机&lt;/li&gt;
&lt;li&gt;买卖股票的最佳时机 II&lt;/li&gt;
&lt;li&gt;买卖股票的最佳时机 III&lt;/li&gt;
&lt;li&gt;买卖股票的最佳时机 IV&lt;/li&gt;
&lt;li&gt;最佳买卖股票时机含冷冻期&lt;/li&gt;
&lt;li&gt;买卖股票的最佳时机含⼿续费&lt;/li&gt;
&lt;li&gt;地下城游戏&lt;/li&gt;
&lt;li&gt;戳⽓球&lt;/li&gt;
&lt;li&gt;分割等和⼦集&lt;/li&gt;
&lt;li&gt;⽬标和&lt;/li&gt;
&lt;li&gt;⾃由之路&lt;/li&gt;
&lt;li&gt;零钱兑换 II&lt;/li&gt;
&lt;li&gt;两个字符串的删除操作&lt;/li&gt;
&lt;li&gt;两个字符串的最⼩ ASCII 删除和&lt;/li&gt;
&lt;li&gt;最⻓公共⼦序列&lt;/li&gt;
&lt;li&gt;K 站中转内最便宜的航班&lt;/li&gt;
&lt;li&gt;鸡蛋掉落&lt;/li&gt;
&lt;li&gt;下降路径最⼩和&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;背包问题&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;分割等和⼦集&lt;/li&gt;
&lt;li&gt;⽬标和&lt;/li&gt;
&lt;li&gt;零钱兑换 II&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;第五章、其他经典算法&lt;/h2&gt;
&lt;h4&gt;数学算法&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;电话号码的字⺟组合&lt;/li&gt;
&lt;li&gt;组合&lt;/li&gt;
&lt;li&gt;⼦集&lt;/li&gt;
&lt;li&gt;加油站&lt;/li&gt;
&lt;li&gt;只出现⼀次的数字&lt;/li&gt;
&lt;li&gt;位 1 的个数&lt;/li&gt;
&lt;li&gt;2 的幂&lt;/li&gt;
&lt;li&gt;阶乘后的零&lt;/li&gt;
&lt;li&gt;阶乘函数后 K 个零&lt;/li&gt;
&lt;li&gt;计数质数&lt;/li&gt;
&lt;li&gt;丢失的数字&lt;/li&gt;
&lt;li&gt;Nim 游戏&lt;/li&gt;
&lt;li&gt;灯泡开关&lt;/li&gt;
&lt;li&gt;⽯⼦游戏&lt;/li&gt;
&lt;li&gt;数据流的中位数&lt;/li&gt;
&lt;li&gt;超级次⽅&lt;/li&gt;
&lt;li&gt;链表随机节点&lt;/li&gt;
&lt;li&gt;随机数索引&lt;/li&gt;
&lt;li&gt;完美矩形&lt;/li&gt;
&lt;li&gt;斐波那契数&lt;/li&gt;
&lt;li&gt;错误的集合&lt;/li&gt;
&lt;li&gt;⿊名单中的随机数&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;区间问题&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;合并区间&lt;/li&gt;
&lt;li&gt;区间列表的交集&lt;/li&gt;
&lt;li&gt;删除被覆盖区间&lt;/li&gt;
&lt;li&gt;⽆重叠区间&lt;/li&gt;
&lt;li&gt;⽤最少数量的箭引爆⽓球&lt;/li&gt;
&lt;li&gt;视频拼接&lt;/li&gt;
&lt;li&gt;单线程 CPU&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>夹带私货--简单文件隐写</title><link>https://pinellia.uk/posts/document-hide/</link><guid isPermaLink="true">https://pinellia.uk/posts/document-hide/</guid><description>使用cat以及binwalk进行简单的文件隐写，偷摸夹带私货</description><pubDate>Wed, 20 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;简单介绍&lt;/h1&gt;
&lt;p&gt;懒得写了： https://zhuanlan.zhihu.com/p/590378572&lt;/p&gt;
&lt;h2&gt;实现&lt;/h2&gt;
&lt;h3&gt;隐写&lt;/h3&gt;
&lt;p&gt;使用 &lt;code&gt;cat a.zip &amp;gt;&amp;gt; b.png&lt;/code&gt;命令实现将pdf追加到png后面&lt;/p&gt;
&lt;p&gt;效果为主图没有变化，只是文件大小上变大了
&amp;lt;p align=&quot;center&quot;&amp;gt;
&amp;lt;img src=&quot;https://ipfs.pinellia.uk/ipfs/QmTMVbJQhP77CQm4bT5BEudQBCEbExLsDT2ybNQFHTTzGZ&quot; alt=&quot;&quot; width=&quot;40%&quot; /&amp;gt;
&amp;lt;br/&amp;gt;
&amp;lt;img src=&quot;https://ipfs.pinellia.uk/ipfs/QmXrvW7ob9uXPcmQcdCFBXXX7hbnH6KeXin3kXtyXdcJLZ&quot; alt=&quot;&quot; width=&quot;40%&quot; /&amp;gt;
&amp;lt;/p&amp;gt;&lt;/p&gt;
&lt;h3&gt;拆解&lt;/h3&gt;
&lt;p&gt;这里借用 &lt;code&gt;binwalk&lt;/code&gt;命令进行拆解，也可以使用其他的，建议参考上面的知乎。&lt;/p&gt;
&lt;p&gt;使用 &lt;code&gt;binwalk b.png&lt;/code&gt;查看文件结构：
&lt;img src=&quot;https://ipfs.pinellia.uk/ipfs/QmaJNcm8N1shbqZRBbURjCsLh5WfQ9Tc4yLbBPMxr93S5G&quot; alt=&quot;&quot; /&gt;
可以看到，被识别为了一个正常图像以及一个压缩包文件&lt;/p&gt;
&lt;p&gt;使用 &lt;code&gt;binwalk -e b.png&lt;/code&gt;将文件提取出来
&lt;img src=&quot;https://ipfs.pinellia.uk/ipfs/QmcY28Q3CDDAEphWpiNH7gYr85r6oXFE3TiC8gp8Vn4unp&quot; alt=&quot;&quot; /&gt;
可以看到，提取出的文件夹如下，在以zip文件开始地址命名的文件夹下直接解出了压缩包内的文件
&lt;img src=&quot;https://ipfs.pinellia.uk/ipfs/QmasDZYXmVZMc14CeqJChtWjiMfTa1mviaSLT3c1GGFRUt&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;https://ipfs.pinellia.uk/ipfs/QmbqUQSSxruM84e4qZTswg9KbaD4YD5ZbLipGmGXDJHd2J&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;TIPS&lt;/h2&gt;
&lt;p&gt;建议将文件打压缩包后再进行隐写，因为例如word文档以及pdf本身就是一个文件集合，这样会导致binwalk无法正确的识别文件类型并提取。
&lt;img src=&quot;https://ipfs.pinellia.uk/ipfs/QmddebmCSkKv33jM7X1BVrZPP3QwKyeWp3KaqJrH6r5Cv4&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;当然，这样加密效果会更好，而且知道文件开始结束位置可以使用dd命令手动提取。&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>cf加速实践</title><link>https://pinellia.uk/posts/better-cf/</link><guid isPermaLink="true">https://pinellia.uk/posts/better-cf/</guid><description>尝试加速cf的服务国内访问，但失败</description><pubDate>Wed, 20 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;参考&lt;/h1&gt;
&lt;p&gt;https://cmliussss.com/p/BestWorkers/&lt;/p&gt;
&lt;h2&gt;结果记录&lt;/h2&gt;
&lt;p&gt;尝试加速本博客 blog.pinellia.uk为例&lt;/p&gt;
&lt;h3&gt;itdog tcping全绿：&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://ipfs.pinellia.uk/ipfs/QmYaCGNTTrshP8FbKaCkbfCfpqWMBE3aVE3G8UtmNF2s2U&quot; alt=&quot;1755619518954&quot; /&gt;&lt;/p&gt;
&lt;p&gt;但本地的设备包括电脑手机，在走直连的情况下，访问极其受限，大部分情况下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl报错为curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to blog.pinellia.uk 
浏览器报错：ERR_CONNECTION_CLOSED
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;确认非dns问题&lt;/h3&gt;
&lt;p&gt;clash的dns结果与itdog吻合：&lt;/p&gt;
&lt;p&gt;&amp;lt;div style=&quot;display: flex; gap: 16px;&quot;&amp;gt;
&amp;lt;img src=&quot;https://ipfs.pinellia.uk/ipfs/QmfHVxTswG6Yr3B4ZJVjTMzkSzg5BszYAiLabQH6UN3iXt&quot; alt=&quot;1755619893625&quot; style=&quot;width: 49%;&quot;&amp;gt;
&amp;lt;img src=&quot;https://ipfs.pinellia.uk/ipfs/QmQ1x4uCyp56m4X7q65sS3DJbACVn79DnKv87b2JpjMbpM&quot; alt=&quot;1755619405601&quot; style=&quot;width: 49%;&quot;&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;尝试指定
找不到无法访问的原因，走代理的情况下能连接。
可以ping通解析出来的ip&lt;/p&gt;
&lt;p&gt;rec：
平板和电脑等了很长时间莫名其妙就能连接了&lt;/p&gt;
</content:encoded></item><item><title>Python 环境配置</title><link>https://pinellia.uk/posts/conda/</link><guid isPermaLink="true">https://pinellia.uk/posts/conda/</guid><description>怎样配置 Python 环境？推荐使用 Miniconda</description><pubDate>Fri, 08 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;介绍视频&lt;/h1&gt;
&lt;p&gt;&amp;lt;div style=&quot;position: relative; width: 60%; aspect-ratio: 16/9; border-bottom: 20px solid #ffffff00;&quot;&amp;gt;
&amp;lt;iframe src=&quot;https://player.bilibili.com/player.html?bvid=BV1Fm4ZzDEeY&quot;
style=&quot;position: absolute; top: 0; left: 0; width: 100%; height: 100%;&quot;
scrolling=&quot;no&quot; border=&quot;0&quot; frameborder=&quot;no&quot; framespacing=&quot;0&quot; allowfullscreen=&quot;true&quot;&amp;gt;
&amp;lt;/iframe&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;h1&gt;总结&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;推荐使用 &lt;code&gt;Miniconda&lt;/code&gt;，日常使用稳定，缺点是环境构建稍慢。&lt;/li&gt;
&lt;li&gt;可尝试 &lt;code&gt;conda-forge + mamba&lt;/code&gt;，但部分 forge channel 可能体验一般。&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>PTA天梯赛L1刷题总结（二）10分题型</title><link>https://pinellia.uk/posts/pta-l1-2/</link><guid isPermaLink="true">https://pinellia.uk/posts/pta-l1-2/</guid><description>PTA 刷题记录-第二部分</description><pubDate>Wed, 26 Feb 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;从这里开始，题目通常都是先给N，然后给出N行数据，虽然题目中看上去输出样例是一起输出，但是我们在编译器里可以是针对每一个样例给出结果（不用把示例都输入后再输出结果），意味着不需要用数组储存（或者使用结构体），可以节省代码量。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;一般情况下，题目还会要求行尾不能有空格，那么我们可以在输出时分两种情况，如if(i==n)时 输出xxx, else 输出xxx 以及空格。&lt;/strong&gt; &lt;strong&gt;测试时注意使用英文的标点符号&lt;/strong&gt; &lt;strong&gt;最好在变量需要时再进行初始化，这样也比较方便（但是好像Code Blocks不支持这样操作，需要一开始就定义变量）。&lt;/strong&gt; &lt;strong&gt;在计数时注意赋初始值( 一般为0)，否则该变量数值不确定&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;接下来说说10分题出现的题型（旁边是题号）&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;给一个整数，输出每一位上的数字 7&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;L1-007 念数字 (10分)&lt;/strong&gt; &lt;strong&gt;输入一个整数，输出每个数字对应的拼音。当整数为负数时，先输出fu字。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;如果是过去的思维，通常会采用C语言的switch-case结构，先读入整数，再获取每一位上的数字，用switch-case结构来读出每一位的拼音&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;如果是用更聪明的想法，其实数字和拼音是****存在一个一一映射的关系(hash)&lt;/strong&gt;，那么可以用读入字符串的方式读入输入示例。如果是char型数组的话，可以用二维数组char&lt;a href=&quot;http://blog.pinellia.uk/2025/02/ptal110.html#&quot;&gt;m&lt;/a&gt;定义，因为二维数组中的每个一维数组都存储着拼音，当然如果使用string数组就更方便了。或者使用STL容器的map来做也很快（后面大题再说）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;下面以三种做法为例进行对比&lt;/strong&gt; &lt;strong&gt;1）读入整型法&lt;/strong&gt; &lt;strong&gt;这里涉及到如何获取每一位的数字的做法。很容易理解，以106为例，106%10，余数为6，即个位，然后106/10后再取余，循环的终止条件在于/10之后为0。这样依次获取的数字是从右往左读的，所以在输出时需注意。在这里我的做法是把获取的每一位数存入数组，在倒序输出。&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

void num(int s)
{
switch (s)
{
case 1:
printf(&quot;yi&quot;);break;
case 2:
printf(&quot;er&quot;);break;
case 3:
printf(&quot;san&quot;);break;
case 4:
printf(&quot;si&quot;);break;
case 5:
printf(&quot;wu&quot;);break;
case 6:
printf(&quot;liu&quot;);break;
case 7:
printf(&quot;qi&quot;);break;
case 8:
printf(&quot;ba&quot;);break;
case 9:
printf(&quot;jiu&quot;);break;
case 0:
printf(&quot;ling&quot;);break;
}
}
int main()
{
int n,i,j;
int a[100]={0};
scanf(&quot;%d&quot;,&amp;amp;n);
if(n&amp;lt;0)
  {
       printf(&quot;fu &quot;);
       n*=(-1);
  }
   i=0;
   while(n/10)
  {
       a[i++]=n%10;
       n/=10;
  }
   a[i]=n;
   for(j=i;j&amp;gt;=0;j--)
  {
       if(j==0) num(a[j]);
       else
      {
           num(a[j]);
           printf(&quot; &quot;);
      }
  }
return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;2）二维数组法&lt;/strong&gt; &lt;strong&gt;len = strlen(s);获取字符数组的长度 &lt;strong&gt;s[i]-&apos;0&apos;获得的就是该字符对应的整数&lt;/strong&gt;&lt;/strong&gt; &lt;strong&gt;如&apos;6&apos;-&apos;0&apos;=6&lt;/strong&gt; &lt;strong&gt;另外在if-else如果只有两种情况（****非此即彼）&lt;/strong&gt;，那么就可用xxx?a:b xxx表示判断条件，&lt;strong&gt;如果满足则执行a,否则执行b。这样来简化写法&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include&amp;lt;cstring&amp;gt;
#include&amp;lt;cstdio&amp;gt;
using namespace std;
int main() {
   char a[10][10] = {&quot;ling&quot;, &quot;yi&quot;, &quot;er&quot;, &quot;san&quot;, &quot;si&quot;, &quot;wu&quot;, &quot;liu&quot;, &quot;qi&quot;, &quot;ba&quot;, &quot;jiu&quot;};
   char s[1000];
   scanf(&quot;%s&quot;,s);
   int len=strlen(s);
   int flag = s[0] == &apos;-&apos; ? 1 : 0;
   if(flag == 1)
      printf(&quot;fu&quot;);
   for(int i = flag; i &amp;lt; len; i++)
  {
       if(i == 0)
      {
           printf(&quot;%s&quot;,a[s[i]-&apos;0&apos;]);
           continue;
      }
       
       printf(&quot; %s&quot;,a[s[i]-&apos;0&apos;]);
  }
   return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;3）string数组法&lt;/strong&gt; &lt;strong&gt;在很多题目中，我们会采用标志位flag来标记，通常初始化为0，如果满足某条件标记为1，这样可以容易地判断是否满足某一条件。在这道题中，如果a[0]==&apos;-&apos;，就说明这个数是负数，输出&quot;fu&quot;，注意在读入string类型的a时，应该用的是英文的单引号&apos;&apos;，而非双引号.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;string&amp;gt;

using namespace std;

int main()
{
   string s[10]={&quot;ling&quot;,&quot;yi&quot;,&quot;er&quot;,&quot;san&quot;,&quot;si&quot;,&quot;wu&quot;,&quot;liu&quot;,&quot;qi&quot;,&quot;ba&quot;,&quot;jiu&quot;};
   string a;
   int h;
   int i,flag;
   flag=0;
   cin&amp;gt;&amp;gt;a;
   if(a[0]==&apos;-&apos;)
  {
       flag=1;
       cout&amp;lt;&amp;lt;&quot;fu &quot;;
  }
   for(int i=flag;a[i]!=&apos;\0&apos;;i++)
  {
        h = a[i]-&apos;0&apos;;
       if(i&amp;lt;a.length()-1)
           cout&amp;lt;&amp;lt;s[h]&amp;lt;&amp;lt;&quot; &quot;;
       else
            cout&amp;lt;&amp;lt;s[h];
  }

   return 0;
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;2.排序 10&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;具体排序方法有很多，这里介绍STL容器中的sort,注意要加头文件 #include &amp;lt; algorithm &amp;gt;基本用法是定义了数组之后，sort(数组的起始位置，结束的****下一个位置&lt;/strong&gt;,cmp)，第三个参数不加时默认时从小到大排序，否则需要自定义一个cmp函数，规定排序的顺序&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;L1-010 比较大小 (10分)&lt;/strong&gt; &lt;strong&gt;要求将输入的任意3个整数从小到大输出。&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;algorithm&amp;gt;
using namespace std;

int main()
{
   int a[3];
   cin&amp;gt;&amp;gt;a[0]&amp;gt;&amp;gt;a[1]&amp;gt;&amp;gt;a[2];
   sort(a,a+3);
   for(int i=0;i&amp;lt;3;i++)
  {
       if(i&amp;lt;2)
           cout&amp;lt;&amp;lt;a[i]&amp;lt;&amp;lt;&quot;-&amp;gt;&quot;;
       else cout&amp;lt;&amp;lt;a[i];
  }
   return 0;
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;3.格式化输出 不足补充 靠右 8 18 37（分类讨论）&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;关于格式化输出，在上一节已作讨论，在这里来说以下靠右的做法，例如&lt;/strong&gt; &lt;strong&gt;左对齐-%10d &lt;strong&gt;右对齐%10d。数字宽度为10，若不足10，在左边补足空格&lt;/strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;以L1-008 求整数段和 (10分)为例&lt;/strong&gt; &lt;strong&gt;首先顺序输出从A到B的所有整数，每5个数字占一行，每个数字占5个字符宽度，向右对齐。最后在一行中按Sum = X的格式输出全部数字的和X。&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;这道题需要特别注意的是换行，可以用一个变量cnt来递增，若cnt%5==0说明此时该换行，另外一个测试点在于如果最后一个数不 是在最后一行最后一个位置，不需要换行&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;cstdio&amp;gt;

using namespace std;

int main()
{
   int m,n,flag,sum;
   cin&amp;gt;&amp;gt;m&amp;gt;&amp;gt;n;
   sum=flag=0;
   for(int i=m;i&amp;lt;=n;i++)
  {
       printf(&quot;%5d&quot;,i);
       flag++;
       if(flag%5==0&amp;amp;&amp;amp;i!=n)
           printf(&quot;\n&quot;);
       sum+=i;
  }
   cout&amp;lt;&amp;lt;endl;
   cout&amp;lt;&amp;lt;&quot;Sum = &quot;&amp;lt;&amp;lt;sum;
   return 0;
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;4.简单计算 阶乘计算（嵌套循环） 13 31 40&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;以L1-031 到底是不是太胖了 (10分)为例&lt;/strong&gt; &lt;strong&gt;说此题的原因在于&lt;/strong&gt; &lt;strong&gt;abs(x) 要加头文件 #include x必须为整数 &lt;strong&gt;浮点型用math.h下的fabs()&lt;/strong&gt;&lt;/strong&gt; &lt;strong&gt;注意在if 的时候不要把公共部分放在else中，否则不会输出公共内容&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;math.h&amp;gt;
using namespace std;

int main()
{
   int n,W,w,H;
   cin&amp;gt;&amp;gt;n;
   while(n--)
  {
       cin&amp;gt;&amp;gt;H&amp;gt;&amp;gt;W;
       w=(H-100)*1.8;
       if(fabs(W-w)&amp;lt;w*0.1)
           cout&amp;lt;&amp;lt;&quot;You are wan mei!&quot;&amp;lt;&amp;lt;endl;
       else if(W&amp;gt;w)
           cout&amp;lt;&amp;lt;&quot;You are tai pang le!&quot;&amp;lt;&amp;lt;endl;
       else
           cout&amp;lt;&amp;lt;&quot;You are tai shou le!&quot;&amp;lt;&amp;lt;endl;
  }
   return 0;
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;5.简单题 22 47 53 61&lt;/strong&gt; &lt;strong&gt;不多说&lt;/strong&gt; &lt;strong&gt;6.判断素数 28&lt;/strong&gt; &lt;strong&gt;判断素数****需要用到sqrt()求平方根缩小循环的范围&lt;/strong&gt;，否则可能会超时，注意加上头文件&amp;lt;math.h&amp;gt; &lt;strong&gt;L1-028 判断素数 (10分)&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;math.h&amp;gt;
#include &amp;lt;cstdio&amp;gt;
using namespace std;

int main()
{
   int i,j,n,m;
   cin&amp;gt;&amp;gt;n;
   for(i=0;i&amp;lt;n;i++)
  {
        int flag=0;
        cin&amp;gt;&amp;gt;m;
       for(j=2;j&amp;lt;=sqrt(m);j++)
      {
           if(m%j==0)
          {
               flag=1;
               break;
          }
      }
           if(flag==1||m==1)
               cout&amp;lt;&amp;lt;&quot;No&quot;&amp;lt;&amp;lt;endl;
           else if(flag==0)
               cout&amp;lt;&amp;lt;&quot;Yes&quot;&amp;lt;&amp;lt;endl;      
  }
   return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;7.达到某条件即break 41&lt;/strong&gt; &lt;strong&gt;一般达到某条件则用break退出循环&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;L1-041 寻找250 (10分)&lt;/strong&gt; &lt;strong&gt;输入在一行中给出不知道多少个绝对值不超过1000的整数&lt;/strong&gt; &lt;strong&gt;在一行中输出第一次出现的&quot;250&quot;是对方扔过来的第几个数字（计数从1开始）&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;这样的情况就是不能够知道到底扔来多少数，这时候就可以用while(1)不断接收数字，一旦满足此数为250即退出循环&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;string&amp;gt;
#define N 10010
using namespace std;

int main()
{
   int i;
   int m=0;
   do
  {
       cin&amp;gt;&amp;gt;i;
       if(i==250)
      {
           cout&amp;lt;&amp;lt;m+1;
           break;
      }
       m++;
  }while(1);

   return 0;
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;8.根据题意求解 55 63&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;以L1-055 谁是赢家 (10分)为例&lt;/strong&gt; &lt;strong&gt;每次安排两位艺人表演，他们的胜负由观众投票和 3名评委投票两部分共同决定。如果一位艺人的观众票数高，且得到至少 1名评委的认可，该艺人就胜出；或艺人的观众票数低，但得到全部评委的认可，也可以胜出。数字 0 代表投票给 a，数字 1 代表投票给&lt;/strong&gt; &lt;strong&gt;b，其间以一个空格分隔。&lt;/strong&gt; &lt;strong&gt;这题思路不难，用几个变量存储一下观众和评委得票数，根据题意进行描述即可&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;cstdio&amp;gt;
using namespace std;

int main()
{
   int i,pa,pb,a,b,c,qa,qb;
   cin&amp;gt;&amp;gt;pa&amp;gt;&amp;gt;pb;
   qa=qb=0;
   for(i=0;i&amp;lt;3;i++)
  {
        cin&amp;gt;&amp;gt;a;
        a==0?qa++:qb++;
  }
   if((pa&amp;gt;pb&amp;amp;&amp;amp;qa&amp;gt;=1)||(pa&amp;lt;pb&amp;amp;&amp;amp;qa==3))
       cout&amp;lt;&amp;lt;&quot;The winner is &quot;&amp;lt;&amp;lt;&quot;a&quot;&amp;lt;&amp;lt;&quot;: &quot;&amp;lt;&amp;lt;pa&amp;lt;&amp;lt;&quot; + &quot;&amp;lt;&amp;lt;qa;
   else
       cout&amp;lt;&amp;lt;&quot;The winner is &quot;&amp;lt;&amp;lt;&quot;b&quot;&amp;lt;&amp;lt;&quot;: &quot;&amp;lt;&amp;lt;pb&amp;lt;&amp;lt;&quot; + &quot;&amp;lt;&amp;lt;qb;
   return 0;
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>pta天梯赛l1刷题总结（三）15分题型</title><link>https://pinellia.uk/posts/pta-l1-3/</link><guid isPermaLink="true">https://pinellia.uk/posts/pta-l1-3/</guid><description>PTA 刷题记录-第三部分</description><pubDate>Wed, 26 Feb 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;首先对20道题进行一个分类吧~&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;目录&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.pinellia.uk/2025/02/ptal115.html#%E4%B8%80%E3%80%81%E5%93%88%E5%B8%8C%E6%98%A0%E5%B0%84%E9%97%AE%E9%A2%98&quot;&gt;一、哈希映射问题&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.pinellia.uk/2025/02/ptal115.html#%E4%BA%8C%E3%80%81%E7%BB%93%E6%9E%84%E4%BD%93%E9%97%AE%E9%A2%98&quot;&gt;二、结构体问题&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.pinellia.uk/2025/02/ptal115.html#%E4%B8%89%E3%80%81%E7%AE%80%E5%8D%95%E9%A2%98%EF%BC%88%E6%8C%89%E9%A2%98%E6%84%8F%E8%A6%81%E6%B1%82%E5%86%99%E5%B0%B1%E8%A1%8C%EF%BC%8C%E9%83%A8%E5%88%86%E9%A2%98%E7%BB%99%E5%87%BA%E4%BB%A3%E7%A0%81%EF%BC%89&quot;&gt;三、简单题（按题意要求写就行，部分题给出代码）&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.pinellia.uk/2025/02/ptal115.html#%E5%9B%9B%E3%80%81%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%A4%84%E7%90%86&quot;&gt;四、字符串处理&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.pinellia.uk/2025/02/ptal115.html#%E4%BA%94%E3%80%81%E7%9F%A9%E9%98%B5%E5%A4%84%E7%90%86&quot;&gt;五、矩阵处理&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h4&gt;&lt;em&gt;一、哈希映射问题&lt;/em&gt;&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;L1-003 个位数统计&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;此题中N是一个不超过 1000 位的正整数，遇到这样的问题一般采用字符串遍历的方式解决。（超出了整型的范围）。题目要求对 N 中每一种不同的个位数字，以 D:M 的格式在一行中输出该位数字 D 及其在 N 中出现的次数 M。要求按 D 的升序输出。&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;**回顾一下int类型和long long类型有多少位 **&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;int类型 -2&lt;/strong&gt;31~2&lt;strong&gt;31 -1 【int类型在C语言中占4个字节，即32个二进制位，最高位为符号位】&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;long long类型  −2&lt;/strong&gt;63,2&lt;strong&gt;63−1【long long类型在C语言中占8个字节，即64个二进制位】&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;int&lt;/strong&gt;&lt;em&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;只能表示到10^9，而long long 可以表示到10^18&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;。****&lt;strong&gt;根据不同的情况需定义不同的数据类型。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;根据题目的要求，第一想到的是用哈希表来存储每位数字对应的次数，这个是一一映射的关系。每一位上就是0到9十个数字，用一个长度为10的整型数组就行。对于出现次数为0的，就不用输出了。这里加个判断就可以。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;对于字符串问题，首先先读入每一个字符，遇到一个字符，则对应出现次数+1。最后输出时如果映射的值不为0，则按照格式输出即可。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;本题有两个注意点&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1） memset(s,0,sizeof(s)); 是关键，对数组初始化都设置为0，否则会出错。用到这个时需要加上头文件 #include &amp;lt;string.h&amp;gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2） 注意遍历时str[i]是一个字符，要str[i]-&apos;0&apos;来转化为int类型&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;string&amp;gt;
#include &amp;lt;string.h&amp;gt;

using namespace std;

int main()
{
   string str;
   int s[10];
   int i;
   cin&amp;gt;&amp;gt;str;
   memset(s,0,sizeof(s)); //关键，对数组初始化都设置为0，否则会出错
   for(i=0;i&amp;lt;str.length();i++)
  {
       s[str[i]-&apos;0&apos;]++;    //注意str[i]是一个字符，要str[i]-&apos;0&apos;来转化为int类型
  }
   for(i=0;i&amp;lt;10;i++)
  {
       if(s[i]!=0)
           cout&amp;lt;&amp;lt;i&amp;lt;&amp;lt;&quot;:&quot;&amp;lt;&amp;lt;s[i]&amp;lt;&amp;lt;endl;
  }
   return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;下面给出****第二种方法&lt;/strong&gt;，博主去刷力扣时的常用方法。我们可以利用map来解决这个哈希数组问题。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;这种方法有几个学习点&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**1）定义map的时候记得**&lt;strong&gt;加上头文件#include &lt;strong&gt;&lt;code&gt;&amp;lt;map&amp;gt;&lt;/code&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;** 如map&amp;lt;string,int&amp;gt;就是代表从string类型到int类型的映射，且****map默认是按key值从小到大排序。**&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2）访问map容器内元素方法，一个是通过访问下标，比如下方的mp[c-’0’]，还有一种就是通过迭代器（如map&amp;lt;int, int&amp;gt;::iterator it）。通过it-&amp;gt;first访问键，it-&amp;gt;second访问值。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;下边的写法可以这么写&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;for(map&amp;lt;int,int&amp;gt;::iterator it = mp.begin();it!=mp.end();it++)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**    cout &amp;lt;&amp;lt; it-&amp;gt;first &amp;lt;&amp;lt; &quot;:&quot; &amp;lt;&amp;lt; it-&amp;gt;second &amp;lt;&amp;lt; endl;**&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3）for(char c:str)这是for循环的一个简便写法，遍历字符串str的每一个字符就是c，也就是方法一中的str[i]，比方法一的遍历要方便很多对吧。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;string&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;map&amp;gt;

using namespace std;

int main()
{
   string str;
   cin&amp;gt;&amp;gt;str;
   map&amp;lt;int,int&amp;gt; mp;
   for(char c:str)
  {
       mp[c-&apos;0&apos;]++;
  }
   map&amp;lt;int, int&amp;gt;::iterator it = mp.begin();

while (it != mp.end()) {
cout &amp;lt;&amp;lt; it-&amp;gt;first &amp;lt;&amp;lt; &quot;:&quot; &amp;lt;&amp;lt; it-&amp;gt;second &amp;lt;&amp;lt; endl;
it++;
}

   return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;二、结构体问题&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;L1-005 考试座位号&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;针对本题，题目的要求是对应每个需要查询的试机座位号码，在一行中输出对应考生的准考证号和考试座位号码，中间用 1 个空格分隔。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**    考虑到每个人是有准考证号、试机座位号、考场座位号的。这时候考虑用结构体代表每个学生。**&lt;strong&gt;特别是在不同数据类型的变量或数组组合在一起的时候应用结构体能够便于存储。&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;比如struct studentInfo{int id; char gender; string name;}Bob,stu[10];&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;其中studentInfo是结构体名，Bob是结构体变量，stu[10]是结构体数组（包含了10个学生的信息）。访问结构体可以通过.或者-&amp;gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;实现：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;准考证号是16位数字，可以考虑用string类型来存储。首先遍历给定的N个学生的信息。再依次读入试机号，遍历结构体中是否有相同的试机号，相同则输出其准考证号和考试座位号。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;当遍历的次数和循环的内容没有关系时，可以用while(m--)作循环&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;cstdio&amp;gt;
#define N 100000
using namespace std;

struct node
{
   string z;
   int s,k;
}stu[N];
int main()
{
   int i,m,n,l;
   cin&amp;gt;&amp;gt;n;
   for(i=0;i&amp;lt;n;i++)
  {
      cin&amp;gt;&amp;gt;stu[i].z&amp;gt;&amp;gt;stu[i].s&amp;gt;&amp;gt;stu[i].k;
  }
   cin&amp;gt;&amp;gt;m;
   while(m--)
  {
       cin&amp;gt;&amp;gt;l;
       for(i=0;i&amp;lt;n;i++)
      {
           if(stu[i].s==l)
               cout&amp;lt;&amp;lt;stu[i].z&amp;lt;&amp;lt;&quot; &quot;&amp;lt;&amp;lt;stu[i].k&amp;lt;&amp;lt;endl;
      }
  }
   return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;或者我们可以优化一下，建立试机号到结构体（准考证号，座位号）的映射。下面给出****第二种方法&lt;/strong&gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;cstdio&amp;gt;
#include &amp;lt;map&amp;gt;
#define N 100000
using namespace std;

struct node
{
   string z;//准考证号
   int k; //考场座位号
}stu;

int main()
{
   int i,m,n,l;
   map&amp;lt;int,node&amp;gt; mp;
   cin&amp;gt;&amp;gt;n;
   int s;
   for(i=0;i&amp;lt;n;i++)
  {
      cin&amp;gt;&amp;gt;stu.z&amp;gt;&amp;gt;s&amp;gt;&amp;gt;stu.k;
      mp[s] = stu;
  }
   cin&amp;gt;&amp;gt;m;
   while(m--)
  {
       cin&amp;gt;&amp;gt;l;
       cout&amp;lt;&amp;lt;mp[l].z&amp;lt;&amp;lt;&quot; &quot;&amp;lt;&amp;lt;mp[l].k&amp;lt;&amp;lt;endl;
  }
   return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;L1-030 一帮一&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;**    得到全班学生的排名后，在当前尚未分组的学生中，将名次最靠前的学生与名次最靠后的**&lt;em&gt;&lt;strong&gt;异性&lt;/strong&gt;&lt;/em&gt;学生分为一组。每行输出一组两个学生的姓名。小组的输出顺序按照前面学生的名次从高到低排列。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**因为这道题我们不仅要存这个学生排名、姓名、还要存性别。**&lt;strong&gt;考虑用结构体来代表每一个学生。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;输入已经按照名次大小排列了，那遍历的边界在哪里呢？是n/2。要不然再后面差一点的学生就排到前面去了。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;因为要和异性组队，那么是不是有可能出现第一名和最后一名同学是同性，于是第一名和倒数第二名同学组队了，那第二名和最后一名是异性，他们组队。那这时候就得****考虑有个标志位来记录这个同学是不是组过队了。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实现：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;结构体我们上面已经说了，可以定义一个大小为N的结构体数组，在头部宏定义#define N 10000&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**在输入第i个学生的性别和姓名时，**&lt;strong&gt;初始化是否组队的标记位为0。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;在输出时，按照名词顺序，用两重循环，外层循环先输出名次高的同学名字，再嵌套一个循环，从j=n-1开始，若不满足j&amp;gt;i则跳出。如果这个同学之前未匹配并且和名次高的同学性别不同，则匹配成功，输出这个同学姓名，并置标记位为1。否则break（****只会跳出这一层循环！&lt;/strong&gt;）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#define N 10000
using namespace std;
struct node
{
   int x,f;
   string m;
}s[N];
int main()
{
   int i,j,n;
   cin&amp;gt;&amp;gt;n;
   for(i=0;i&amp;lt;n;i++)
  {
       cin&amp;gt;&amp;gt;s[i].x&amp;gt;&amp;gt;s[i].m;
       s[i].f=0;
  }
   for(i=0;i&amp;lt;n/2;i++)
  {
       for(j=n-1;j&amp;gt;i;j--)
      {
           if(s[i].x!=s[j].x&amp;amp;&amp;amp;s[j].f!=1)
          {
               cout&amp;lt;&amp;lt;s[i].m&amp;lt;&amp;lt;&quot; &quot;&amp;lt;&amp;lt;s[j].m&amp;lt;&amp;lt;endl;
               s[j].f=1;
               break;
          }
      }
  }
   return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;三、简单题（按题意要求写就行，部分题给出代码）&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;L1-015 跟奥巴马一起画方块&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;题目要求是输入在一行中给出正方形边长N&lt;/strong&gt;**，**输出由给定字符C画出的正方形，且输出的行数实际上是列数的50%（四舍五入取整）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;双重循环，外层代表多少行，内层代表多少列。要求行数是列数的50%。给定的边长其实就是列数，那行数是四舍五入求整。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**本题比较简单，****注意点:**&lt;strong&gt;int类型除法是向下取整&lt;/strong&gt;，如果要做到四舍五入的话应写为l=(n+1)/2;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;L1-016 查验身份证&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;定义两个数组，一个存储权重，一个存储校验码，按题意对比取模后对应校验码的值是否与身份证最后一位相同即可。为了便于核对，可用字符串类型存储身份证。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;L1-017 到底有多二&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;**输入第一行给出一个的整数N。一个整数“**&lt;em&gt;&lt;strong&gt;犯二的程度&lt;/strong&gt;&lt;/em&gt;”定义为该数字中包含2的个数与其位数的比值。如果这个数是负数，则程度增加0.5倍；如果还是个偶数，则再增加1倍。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;首先依题意N不超过50位，考虑用字符串类型定义N。遍历字符串记录2的个数。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注意位数需要排除符号位&lt;/strong&gt;，如果首位是负号，用一个flag位标记是否*1.5（增加0.5倍）那么长度为s.length(）-1（可以用l-flag表示位数）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;看末位是否能被2整除，如果是结果*2。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**注意点：**小数点后保留两位  printf(&quot;%.2f&quot;,b);。&lt;strong&gt;比值要转为double类型&lt;/strong&gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;cstdio&amp;gt;
using namespace std;

int main()
{
   string s;
   double b;
   int i,cnt=0;
   cin&amp;gt;&amp;gt;s;
   int flag=0;
   if(s[0]==&apos;-&apos;) flag=1;
   int l = s.length();
   for(i=flag;i&amp;lt;s.length();i++)
  {
       if(s[i]-&apos;0&apos;==2)
           cnt++;
  }
   b = (double)cnt/(l-flag)*100;
   if(flag==1)
       b*=1.5;
   if((s[l-1]-&apos;0&apos;)%2==0)
       b*=2;
   printf(&quot;%.2f&quot;,b);
   cout&amp;lt;&amp;lt;&quot;%&quot;;
   return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;L1-019 谁先倒&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这题关键点在于判断谁赢谁输。比如甲输的条件是什么？注意同输是进入下一轮的，不喝酒。因此if中有两个判断条件。谁输了谁喝的杯数+1。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;在for循环中我们每次遍历都看看是不是有人已经到达他的酒量了。有人倒下就终止（喝的杯数&amp;gt;酒量），输出输家和赢家喝的杯数，用break跳出循环。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注意点：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;输入的时候用到getchar();  目的是清空回车符，从标准输入流读取一个字符，读回车符时退出&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最好定义的变量名能够很好的体现含义，特别这题一行四个变量，要避免后面写乱了。&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;cstdio&amp;gt;
using namespace std;

int main()
{
   int a,b,n,i,yf,jf,yh,jh,ma,mb;
   ma=mb=0;
   cin&amp;gt;&amp;gt;a&amp;gt;&amp;gt;b;
   getchar();  //不用也可以，目的是清空回车符，从标准输入流读取一个字符，读回车符时退出
   cin&amp;gt;&amp;gt;n;
   for(i=0;i&amp;lt;n;i++)
  {
       cin&amp;gt;&amp;gt;jh&amp;gt;&amp;gt;jf&amp;gt;&amp;gt;yh&amp;gt;&amp;gt;yf;
       if(jf==jh+yh&amp;amp;&amp;amp;yf!=jh+yh)
           ma++;
       if(yf==jh+yh&amp;amp;&amp;amp;jf!=jh+yh)
           mb++;
       if(ma&amp;gt;a||mb&amp;gt;b)
      {
         if(mb&amp;gt;b)
          {
               cout&amp;lt;&amp;lt;&quot;B&quot;&amp;lt;&amp;lt;endl;
               cout&amp;lt;&amp;lt;ma;
          }
          if(ma&amp;gt;a)
          {
              cout&amp;lt;&amp;lt;&quot;A&quot;&amp;lt;&amp;lt;endl;
              cout&amp;lt;&amp;lt;mb;
          }
          break;
      }

  }

   return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;L1-062 幸运彩票&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;用字符串保存字符串，再依题意判断输出即可。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;L1-069 胎压监测&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**    这题可以用数组存储各个轮胎的值。求数组中最大值可以用到max()。注意读题内容准确，遍历每个轮胎，看最大值与此轮胎气压差大于阈值或者这个轮胎气压值小于最低气压时，轮胎异常数+1，并且标记轮胎编号。对于异常轮胎个数用一个变量表示，最后根据轮胎异常数为0,1还是&amp;gt;1的情况分别输出结果。**&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;cstdio&amp;gt;
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;cmath&amp;gt;
using namespace std;

int main()
{
   int a[4];
   int yu,ya;
   scanf(&quot;%d %d %d %d&quot;,&amp;amp;a[0],&amp;amp;a[1],&amp;amp;a[2],&amp;amp;a[3]);
   scanf(&quot;%d %d&quot;,&amp;amp;ya,&amp;amp;yu);
   
   int maxY = 0,cnt =0,index,i;
   for(i=0;i&amp;lt;4;i++)
  {
       maxY = max(maxY,a[i]);
  }
   for(i=0;i&amp;lt;4;i++)
  {
       if(maxY-a[i]&amp;gt;yu||a[i]&amp;lt;ya)
      {
           cnt++;
           index = i;
      }
  }
   if(cnt==0) cout&amp;lt;&amp;lt;&quot;Normal&quot;;
   else if(cnt==1) printf(&quot;Warning: please check #%d!&quot;,index+1);
   else cout&amp;lt;&amp;lt;&quot;Warning: please check all the tires!&quot;;
   return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;L1-077 大笨钟的心情&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;**这道题也是不知道有多少行输入的，在遇到非法数据（不在[0,23]区间）时停止。那就把while循环()里内容改为while(cin&amp;gt;&amp;gt;n&amp;amp;&amp;amp;n&amp;gt;=0&amp;amp;&amp;amp;n&amp;lt;=23)。**&lt;strong&gt;注意格式正确。&lt;/strong&gt;&lt;/p&gt;
&lt;h4&gt;四、字符串处理&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;1、字符串转化为整型&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;L1-025 正整数A+B&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A和B都在区间[1,1000] A、B有时候可能是超出范围的数字、负数、带小数点的实数、甚至是一堆乱码。把输入中出现的第1个空格认为是A和B的分隔。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**    首先A、B不一定都是整数，可能是乱码，因此采用字符串来存储A、B。读入A之后一定要加getchar()读入缓冲区中的空格，getline(cin,str)读入整行字符串B。**&lt;/p&gt;
&lt;p&gt;**    对于不符合条件的数字用?代替，只要加法的任一加数为？，结果均为？ **&lt;/p&gt;
&lt;p&gt;**    我们只对符合条件的两个加数进行计算。由于A、B都是[1,1000]的数，因此我们可以把他们转化为整型再相加获得结果，这里可以****专门写一个函数来实现字符串到整型的转换**。如果返回值为-1，表示这个数不符合条件，否则返回转化为整型的值。最后以规定的格式输出等式。&lt;/p&gt;
&lt;p&gt;**    输出结果时有四种可能：一是两个都是整数，第二、三种是A或B满足条件，另一个不符合条件，第四种是A、B都不符合条件。可用if进行判断。**&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实现：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**    那么这个函数要怎么写呢？我们将字符串和字符串长度作为参数传入（只传一个字符串也没有关系）。遍历这个字符串，如果出现这个字符&amp;lt;’0’且&amp;gt;’9’就说明这个字符串不符合条件了，这时直接返回-1，别继续遍历了。否则，**&lt;strong&gt;sum=sum10+a[i]-&apos;0&apos;;&lt;/strong&gt; 想想是不是这样。最后返回这个sum，也就是转化的结果。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;cstdio&amp;gt;
#include &amp;lt;string&amp;gt;
using namespace std;

int pan(string a,int len)
{
   int i,sum=0;
   for(i=0;i&amp;lt;len;i++)
  {
       if(a[i]&amp;lt;&apos;0&apos;||a[i]&amp;gt;&apos;9&apos;)
           return -1;
       else
           sum=sum*10+a[i]-&apos;0&apos;;
  }

   return sum;
}
int main()
{
   string a,b;
   cin&amp;gt;&amp;gt;a;
   getchar();
   getline(cin,b);
   int lena = a.length();
   int lenb = b.length();
   int A = pan(a,lena);
   int B = pan(b,lenb);
   if((A&amp;gt;0&amp;amp;&amp;amp;A&amp;lt;=1000)&amp;amp;&amp;amp;(B&amp;gt;0&amp;amp;&amp;amp;B&amp;lt;=1000))
       cout&amp;lt;&amp;lt;A&amp;lt;&amp;lt;&quot; + &quot;&amp;lt;&amp;lt;B&amp;lt;&amp;lt;&quot; = &quot;&amp;lt;&amp;lt;A+B;
   if((A&amp;gt;0&amp;amp;&amp;amp;A&amp;lt;=1000)&amp;amp;&amp;amp;(B&amp;lt;1||B&amp;gt;1000))
       cout&amp;lt;&amp;lt;A&amp;lt;&amp;lt;&quot; + ? = ?&quot;;
   if(B&amp;gt;0&amp;amp;&amp;amp;B&amp;lt;=1000&amp;amp;&amp;amp;(A&amp;lt;1||A&amp;gt;1000))
       cout&amp;lt;&amp;lt;&quot;? + &quot;&amp;lt;&amp;lt;B&amp;lt;&amp;lt;&quot; = ?&quot;;
   if((A&amp;lt;1||A&amp;gt;1000)&amp;amp;&amp;amp;(B&amp;lt;1||B&amp;gt;1000))
       cout&amp;lt;&amp;lt;&quot;? + ? = ?&quot;;
   return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;2、提取整数的每一位数字&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;L1-033 出生年&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;**    输入在一行中给出出生年份y和目标年份中不同数字的个数n，其中y在[1, 3000]之间。根据输入，输出x和能达到要求的年份。数字间以1个空格分隔，行首尾不得有多余空格。注意不足4位的年份要在前面补零**&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;题目已经说了****所谓“n个数字都不相同”是指不同的数字正好是n个。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;考虑到set不会存放相同的元素&lt;/strong&gt;，可以把当前年份所含的数字insert()加入到集合中，如果集合中数字个数==n就break退出。返回年龄和当前年份（注意输出格式！）。起始值为出生年份，循环到能找到这个年份为止（年份一年一年往上加）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实现：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**    这里就和上题不同的是，不需将年份转化为字符串，而是需要将整型的一位位取出来。怎么取呢？假设当前处理的年份是n，这里****也不需要按顺序来存**，所以每次把n%10添加到set中（取出当前数的末位数字），再n/10。循环多少次呢?因为y在[1, 3000]，&lt;strong&gt;保证是个4位数&lt;/strong&gt;。设置j的起始值为4就可以了。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;while(j--)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;{    s.insert(n%10);&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**     n/=10;**&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意这时候n的值已经发生改变，用一个变量来保存一下它。&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;cstring&amp;gt;
#include &amp;lt;cstdio&amp;gt;
#include &amp;lt;set&amp;gt;
using namespace std;

int main()
{
   int y,n,m;
   cin&amp;gt;&amp;gt;y&amp;gt;&amp;gt;n;
   m = y;
   
   while(1)
  {
      int h = m;
      set&amp;lt;int&amp;gt; s;   //注意定义的位置
      int j=4;
      while(j--)
      {
          s.insert(h%10);
          h/=10;
      }
       if(s.size()==n) break;
       m++;
  }
   printf(&quot;%d %04d&quot;,m-y,m);
   return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;3、遇到某个特定字符串停止输入（不知道循环多少次的情况）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;还有种情况就是给一行字符串，我们使用****getline(cin,str)后用s.length()就知道字符串的长度&lt;/strong&gt;，便可以用for循环遍历整个字符串了。（如58题）&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;L1-035 情人节&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;输入按照点赞的先后顺序给出不知道多少个点赞的人名，每个人名占一行，为不超过10个英文字母的非空单词，以回车结束。一个英文句点.标志输入的结束。若存在第2个人A和第14个人B，则输出“A and B are inviting you to dinner...”；若只有A没有B，则输出“A is the only one for you...”；若连A都没有，则输出“Momo... No one is for you ...”。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;输入时注意条件是不知道多少个点赞的人名（可用字符串表示），这时候就可以用while循环，特别是题目说了用英文句点.标志输入的结束。倘若读入的字符串是’.’，就可以跳出循环。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**因为要输出第2和第14个人名，因此需要存储人名。**&lt;strong&gt;可以用字符串数组，也可以单纯存放第2个和第14个人名。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这题在输出的时候考虑如题所示的三种情况。如果人数&amp;gt;=14,输出…… 如果人数&amp;gt;=2且&amp;lt;14，需要输出……如果人数&amp;lt;2,输出…… 这时候还需要一个变量来标记点赞人数（有多少次循环）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**第一种方法是用字符串数组来存储人名，**&lt;strong&gt;用while(1)循环&lt;/strong&gt;，直到遇到‘.’break跳出循环。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#define N 10000
using namespace std;

int main()
{
   string s[N];
   int i=0;
   while(1)
  {
       cin&amp;gt;&amp;gt;s[i];
       if(s[i][0]==&apos;.&apos;)
           break;
       i++;

  }
   if(i&amp;gt;1&amp;amp;&amp;amp;i&amp;lt;=13)
           cout&amp;lt;&amp;lt;s[1]&amp;lt;&amp;lt;&quot; is the only one for you...&quot;;
   if(i&amp;lt;=1)
       cout&amp;lt;&amp;lt;&quot;Momo... No one is for you ...&quot;;
   if(i&amp;gt;13)
           cout&amp;lt;&amp;lt;s[1]&amp;lt;&amp;lt;&quot; and &quot;&amp;lt;&amp;lt;s[13]&amp;lt;&amp;lt;&quot; are inviting you to dinner...&quot;;
   return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;第二种方法&lt;/strong&gt;是用字符串数组来存储人名，用&lt;strong&gt;while(****cin&amp;gt;&amp;gt;s&amp;amp;&amp;amp;s!=&quot;.&quot;&lt;/strong&gt;)**（注意是双引号！）**来看是否进入循环。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#define N 10000
using namespace std;

int main()
{
   string s,A,B;
   int i=0;
   while(cin&amp;gt;&amp;gt;s&amp;amp;&amp;amp;s!=&quot;.&quot;)
  {
       i++;
       if(i==2) A = s;
       if(i==14) B = s;

  }
   if(i&amp;gt;1&amp;amp;&amp;amp;i&amp;lt;=13)
           cout&amp;lt;&amp;lt;A&amp;lt;&amp;lt;&quot; is the only one for you...&quot;;
   else if(i&amp;lt;=1)
       cout&amp;lt;&amp;lt;&quot;Momo... No one is for you ...&quot;;
   else
        cout&amp;lt;&amp;lt;A&amp;lt;&amp;lt;&quot; and &quot;&amp;lt;&amp;lt;B&amp;lt;&amp;lt;&quot; are inviting you to dinner...&quot;;
   return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;L1-044 稳赢&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;根据对方的出招，给出对应的赢招。需要每隔K次就让一个平局。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**这题石头剪刀布有个很巧的方法，我们不要专门设一个函数，比如传入参数为剪刀，返回石头；出石头，返回布……而是可以用一个字符串数组的方法，比如string s[3]={&quot;ChuiZi&quot;,&quot;JianDao&quot;,&quot;Bu&quot;};比如锤子，我们用布来对。布就用剪刀。****（规律：差2 再对三取模）**s[(i+2)%3]就是本局要赢对应的划拳。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;因此对于输入的字符串我们可以遍历下字符串数组，看当前的字符串在字符串数组的索引i（一个个比较是否相等）。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;其次注意K是间隔次数，每隔K局就输出一个和输入的字符串相同的划拳。（比如k=2，前两局赢了，我第三局就要平局）这时就要用一个变量表示局数（初始化为1），如果局数%(k+1)==0就说明这句要平局。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;输入到End就退出循环，这个方法和上一题一样，就不再赘述。&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;

using namespace std;

int main()
{
   string s[3]={&quot;ChuiZi&quot;,&quot;JianDao&quot;,&quot;Bu&quot;};
   string str;
   int n,i;
   cin&amp;gt;&amp;gt;n;
   int c=1;
   while(1)
  {
       cin&amp;gt;&amp;gt;str;
       if(str==&quot;End&quot;)
           break;
       for(i=0;i&amp;lt;3;i++)
      {
           if(str==s[i])
          {
               if(c%(n+1)!=0)
                   cout&amp;lt;&amp;lt;s[(i+2)%3]&amp;lt;&amp;lt;endl;
               else cout&amp;lt;&amp;lt;s[i]&amp;lt;&amp;lt;endl;
          }
      }
        c++;
  }

   return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;L1-058 6翻了&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;从左到右扫描输入的句子：如果句子中有超过 3 个连续的 6，则将这串连续的 6 替换成 9；但如果有超过 9 个连续的 6，则将这串连续的 6 替换成 27。其他内容不受影响，原样输出。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这道题的难点就在于如何看有多少个连续的6，以及把连续的6替换为对应数字。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实现：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;首先 用getline(cin,s)读入这行句子。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**考虑用string类型中的replace()函数， **&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;str.replace(pos,len,str2);表示用str2替换str中从pos位置开始长度为len的子串。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;

using namespace std;

int main()
{
    string s;
   int i,j,n;
   getline(cin,s);
   for(i=0;i&amp;lt;s.length();i++)
  {
       for(j=0;i+j&amp;lt;s.size()&amp;amp;&amp;amp;s[i+j]==&apos;6&apos;;j++);//记得这里有个分号，只是这样求一串6的长度
if(j&amp;gt;9) s.replace(i,j,&quot;27&quot;);//j就是一串6的长度
else if(j&amp;gt;3) s.replace(i,j,&quot;9&quot;);  
  }
   cout&amp;lt;&amp;lt;s;
   return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;4、字符串包含问题（是否包含某一子串）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;L1-070 吃火锅&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;自动检查你朋友给你发来的信息里有没有 chi1 huo3 guo1。输入每行给出一句不超过 80 个字符的、以回车结尾的朋友信息。当读到某一行只有一个英文句点 . 时，输入结束，此行不算在朋友信息里。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;首先在一行中输出朋友信息的总条数。然后对朋友的每一行信息，检查其中是否包含 chi1 huo3 guo1，并且统计这样厉害的信息有多少条。在第二行中首先输出第一次出现 chi1 huo3 guo1 的信息是第几条（从 1 开始计数），然后输出这类信息的总条数，其间以一个空格分隔。题目保证输出的所有数字不超过 100。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;如果朋友从头到尾都没提 chi1 huo3 guo1 这个关键词，则在第二行输出一个表情 -_-#。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;首先要看看朋友到底发了多少条信息。这里每行就是一条，看有多少行。&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意二者区别   cin&amp;gt;&amp;gt;str：遇到空格将停止输入 getline()：获得完整一行字符串&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;怎么体现遇到chi1 huo3 guo1呢？输入的这一行字符串包含这个字符串即可。这里插入一个知识点：&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;在string类型中有一个find()函数，str.find(str2)，如果str包含str2，就返回在str中第一次出现str2的位置，否则返回string::npos。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意用一个变量来存储第一次出现“chi1 huo3 guo1”的行数以及出现”chi1 huo3 guo1”的条数。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注意是****提到次数为0&lt;/strong&gt;时而不是行数为0时输出表情！这个在定义变量的时候做好区分。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;cstdio&amp;gt;
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;string&amp;gt;

using namespace std;
int main()
{
   string s;
   string str = &quot;chi1 huo3 guo1&quot;;
   int cnt = 0,ans = 0,first = 0,flag=0 ;
   while(getline(cin,s)&amp;amp;&amp;amp;s!=&quot;.&quot;)
  {
       cnt++;
       if(s.find(str)!=string::npos)
      {
           ans++;
           if(ans == 1)  first = cnt;    
      }
  }
   cout&amp;lt;&amp;lt;cnt&amp;lt;&amp;lt;endl;
   if(ans ==0)  cout&amp;lt;&amp;lt;&quot;-_-#&quot;;
else cout&amp;lt;&amp;lt;first&amp;lt;&amp;lt;&quot; &quot;&amp;lt;&amp;lt;ans;
return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;L1-078 吉老师的回归&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这题看题目很长的样子，简单来说就是某行字符串里有 qiandao 或者 easy&lt;/strong&gt;***（区分大小写）***的话，吉老师会跳过不做这题。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;输入表示本次天梯赛有 N 道题目，吉老师现在做完了 M 道。在一行中输出吉老师当前正在做的题目对应的题面（即做完了 M 道题目后，吉老师正在做哪个题）。如果吉老师已经把所有他打算做的题目做完了，输出一行 Wo AK le。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;思路（本题脑子清醒比较重要）：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;如果吉老师没把想做的题目做完，就输出吉老师正在做哪题（第m+1个不包含qiandao 或者 easy的题面）。如果吉老师都做完了，就输出指定内容。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这里就需要遍历完每一行的题面，看看究竟有多少题吉老师要完成的（与M比对是否已做完）。这就需要一个变量来记录吉老师做的题数，不包含：题数+1。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**当题数==M+1时，输出第M+1个不包含qiandao 或者 easy的题面。(**&lt;strong&gt;注意在判断时二者是&amp;amp;&amp;amp;关系&lt;/strong&gt;)。字符串包含的问题上题已说明。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;什么情况下吉老师做完所有题目呢？ t&amp;lt;=m 也就是已完成的题数&amp;gt;=需要做的题数的情况&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**注意：**此题的输入  要么cin&amp;gt;&amp;gt;n&amp;gt;&amp;gt;m;之后跟上一个getchar()接收一下回车 再接着循环存储题面。要么就是scanf(&quot;%d %d\n&quot;,&amp;amp;n,&amp;amp;m);进行输入。否则会出错！&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;cstdio&amp;gt;
#include &amp;lt;string&amp;gt;

using namespace std;

int main()
{
   int n,m,t=0;
   cin&amp;gt;&amp;gt;n&amp;gt;&amp;gt;m;
   //scanf(&quot;%d %d\n&quot;,&amp;amp;n,&amp;amp;m);
   getchar();
   string s;
   for(int i=0;i&amp;lt;n;i++)
  {
       getline(cin,s);
       //if(s.find(&quot;qiandao&quot;)==string::npos&amp;amp;&amp;amp;s.find(&quot;easy&quot;)==string::npos)
       if(s.find(&quot;qiandao&quot;)==-1&amp;amp;&amp;amp;s.find(&quot;easy&quot;)==-1)    //也可以用-1表示string::npos，虽然会显示等号两边类型不匹配的warning
      {
           t++;
      }
       if(t==m+1)
      {
          cout&amp;lt;&amp;lt;s;
          break;
      }
  }
   if(t&amp;lt;=m) cout&amp;lt;&amp;lt;&quot;Wo AK le&quot;&amp;lt;&amp;lt;endl;
   return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;5、规律题&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;L1-050 倒数第N个字符串&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;给定一个完全由小写英文字母组成的字符串等差递增序列，该序列中的每个字符串的长度固定为 L，从 L 个 a 开始，以 1 为步长递增。对于任意给定的 L，本题要求你给出对应序列倒数第 N 个字符串。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;给定一个完全由小写英文字母组成的字符串等差递增序列，该序列中的每个字符串的长度固定为 L，从 L 个 a 开始，以 1 为步长递增。对于任意给定的 L，本题要求你给出对应序列倒数第 N 个字符串。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;倒数第N个字符串，转化为正数第M个字符串来解决。L个字母会产生26^L个字符串，用函数表示就是pow(26,l);&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;感觉过去像是个找规律的问题，比如说aaaa、aaab…aaaz、aaba、aabb、aabc……zzzz。就好比满26了向前进1。可以看出到第28个（第一个记为0）时，把28%26的值为当前最低位（‘a’+2），接着28/26为1，对26求余为1，也就是倒数第二位。然后不断把这个值/26再对26求模（循环l次），就可以从最后一位往前推当前位的字符，结果是aabc。最后逆序逐个输出每一位上的字符。(这题对我来说还挺难想的…）&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;math.h&amp;gt;
#define N 10
using namespace std;

int main()
{
   int l,n,m,i,t;
   char r[N];
   cin&amp;gt;&amp;gt;l&amp;gt;&amp;gt;n;
   t = pow(26,l);
   m = t-n;
   for(i=l-1;i&amp;gt;=0;i--)
  {
       r[i] =&apos;a&apos;+m%26;
       m/=26;
  }
   for(i=0;i&amp;lt;l;i++)
       cout&amp;lt;&amp;lt;r[i];
   
   return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;五、矩阵处理&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;1、矩阵相乘&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;L1-048 矩阵A乘以B&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;输入先后给出两个矩阵A和B。对于每个矩阵，首先在一行中给出其行数R和列数C。只有Ca与Rb相等时，两个矩阵才能相乘。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;若输入的两个矩阵的规模是匹配的，则按照输入的格式输出乘积矩阵AB，否则输出Error: Ca != Rb&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;可以在草稿纸上模拟一下矩阵相乘有什么特点。首先结果是Ra×Cb大小的矩阵c。比如c&lt;/strong&gt;&lt;a href=&quot;http://blog.pinellia.uk/2025/02/ptal115.html#&quot;&gt;i&lt;/a&gt;的结果为a的第i行分别与b的第j列元素相乘结果再相加。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实现：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;首先输入两个矩阵，用二维数组a和b来存储（在输入矩阵a的行数和列数时就创建符合大小的二维数组）。存入数组元素也不难，双重循环读入每个位置元素就可以了。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;其次对Ca和Rb进行比较，不相等直接输出Error，就不要进行矩阵相乘了。可以用个if-else判断&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实现起来是不是a&lt;/strong&gt;&lt;a href=&quot;http://blog.pinellia.uk/2025/02/ptal115.html#&quot;&gt;i&lt;/a&gt;*c&lt;a href=&quot;http://blog.pinellia.uk/2025/02/ptal115.html#&quot;&gt;k&lt;/a&gt;。这个k的范围就是a的列数，即b的行数。因此设置三层循环，最里层计算sum+=a&lt;a href=&quot;http://blog.pinellia.uk/2025/02/ptal115.html#&quot;&gt;i&lt;/a&gt;*b&lt;a href=&quot;http://blog.pinellia.uk/2025/02/ptal115.html#&quot;&gt;k&lt;/a&gt;;  第二层循环需要更新sum=0;&lt;/p&gt;
&lt;p&gt;**注意！**行首尾没有多余的空格。可用一个变量来标记此时是这一行第几个元素（若初始化为0）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;非每行末尾元素，我们输出结果时再加一个空格。如果当前计数==Cb-1 就输出结果并换行即可。&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;cstdio&amp;gt;
#include &amp;lt;cstring&amp;gt;
using namespace std;

int main()
{
   int i,j,k,ra,ca,rb,cb,sum;
   cin&amp;gt;&amp;gt;ra&amp;gt;&amp;gt;ca;
   int a[ra][ca];
   for(i=0;i&amp;lt;ra;i++)
  {
       for(j=0;j&amp;lt;ca;j++)
           cin&amp;gt;&amp;gt;a[i][j];
  }
   cin&amp;gt;&amp;gt;rb&amp;gt;&amp;gt;cb;
   int b[rb][cb];
   for(i=0;i&amp;lt;rb;i++)
  {
       for(j=0;j&amp;lt;cb;j++)
           cin&amp;gt;&amp;gt;b[i][j];
  }
   if(ca!=rb) printf(&quot;Error: %d != %d&quot;,ca,rb);
   else
  {
       cout&amp;lt;&amp;lt;ra&amp;lt;&amp;lt;&quot; &quot;&amp;lt;&amp;lt;cb&amp;lt;&amp;lt;endl;
       for(i=0;i&amp;lt;ra;i++)
      {
           for(j=0;j&amp;lt;cb;j++)
          {
                int sum=0;
                for(k=0;k&amp;lt;rb;k++)
                   sum+=a[i][k]*b[k][j];
               if(j==cb-1) cout&amp;lt;&amp;lt;sum&amp;lt;&amp;lt;endl;
               else  cout&amp;lt;&amp;lt;sum&amp;lt;&amp;lt;&quot; &quot;;
          }
      }    
  }
   return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;2、倒置矩阵&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;L1-054 福到了&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;读入字符和网格规模，输出倒置的网格，如样例所示。但是，如果这个字正过来倒过去是一样的，就先输出bu yong dao le，然后再用输入指定的字符将其输出。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;思路：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**看到这题想法是应该用一个二维数组/字符串数组来存储这个网格。然后创建一个同样大小的网格把原始网格倒置存储。但是怎么判断这是一个不用倒了的网格呢？是判断每个有字符的地方都处于它对应的位置吗？****比如在原始NN网格中一个元素位置是a&lt;a href=&quot;http://blog.pinellia.uk/2025/02/ptal115.html#&quot;&gt;i&lt;/a&gt;，那么倒置之后它的位置在a&lt;a href=&quot;http://blog.pinellia.uk/2025/02/ptal115.html#&quot;&gt;n-i-1&lt;/a&gt;，**注意用给定字符替代。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;但是，或许我们根本不需要再额外花费空间来存储倒后的元素，可以直接输出呢？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实现：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**注意：**读入字符和规模N之后要getchar();（上文L1-078中已说过类似问题）再接着进行网格内容输入。可以用字符串数组来输入，一行就是getline(cin,s[i]);&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;因为如果不用倒了，就说明这个网格是对称的，那它倒过来的时候元素对应位置一定是有字符的。一旦发现倒置后位置没有字符，就用置标志位flag为1（初始化为0），然后break跳出循环。根据flag的值判断是否需要输出“不用倒了”。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;在输出的时候，通过判断它（要输出的网格）倒置的位置（也就是原来的网格规模）是否有元素决定输出的地方是输出空格还是指定字符，注意到达每行尾部时换行。&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;cstdio&amp;gt;
#define N 1000
using namespace std;

int main()
{
   char c;
   int n,i,j;
   int flag=0;
   cin&amp;gt;&amp;gt;c&amp;gt;&amp;gt;n;
   getchar();
   string s[N];
   char m[n][n];
   for(i=0;i&amp;lt;n;i++)
  {
       getline(cin,s[i]);
  }
   for(i=0;i&amp;lt;n;i++)
  {
       for(j=0;j&amp;lt;n;j++)
      {
           if(s[i][j]!=s[n-i-1][n-j-1])
              {
                 flag=1;
                 break;
              }
      }
  }
   if(!flag) cout&amp;lt;&amp;lt;&quot;bu yong dao le&quot;&amp;lt;&amp;lt;endl;
   for(i=0;i&amp;lt;n;i++)
  {
       for(j=0;j&amp;lt;n;j++)
          {
               if(s[n-1-i][n-1-j]!=&apos;@&apos;)
                   cout&amp;lt;&amp;lt;&quot; &quot;;
               else cout&amp;lt;&amp;lt;c;
          }
       cout&amp;lt;&amp;lt;endl;
  }
   return 0;
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>景深 虚化 动态模糊——光圈和快门对照片的影响</title><link>https://pinellia.uk/posts/photop3/</link><guid isPermaLink="true">https://pinellia.uk/posts/photop3/</guid><description>摄影学习记录</description><pubDate>Fri, 31 Jan 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;1.光圈 可影响亮度、景深、虚化；对焦的本质；对焦和光圈的关系&lt;/p&gt;
&lt;p&gt;2.快门 可影响亮度，决定动态模糊；慢门的运用&lt;/p&gt;
&lt;p&gt;3.倒过来思考也是一样:想要动态模糊→改变快门；想要虚化→改变光圈&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;1、光圈的大小除了影响亮度，还影响景深、虚化。&lt;/h2&gt;
&lt;p&gt;①景深:从镜头发散出去，只有一部分区域的景象是清晰的，其他的会模糊。而清晰的区域，就叫做景深。（如图）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://ipfs.pinellia.uk/ipfs/Qmbz1on3QEdRU6ByBL5smoMa1P6KmFB2ecUxo3Aa73mBhC&quot; alt=&quot;&quot; /&gt;
大光圈→浅景深。即清晰的区域小，背景会模糊。⬇️&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://ipfs.pinellia.uk/ipfs/QmP8vV9ZE3KMahLc1vsXADTNwrk3C9jDs1pcmN3bypgEKk&quot; alt=&quot;&quot; /&gt;
小光圈→深景深。即清晰的区域大，背景也清晰。⬇️（简单理解为近视眼更喜欢眯缝着看人吧）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://ipfs.pinellia.uk/ipfs/QmP8vV9ZE3KMahLc1vsXADTNwrk3C9jDs1pcmN3bypgEKk&quot; alt=&quot;&quot; /&gt;
②虚化&lt;/p&gt;
&lt;p&gt;大光圈，背景虚化越强⬇️&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://ipfs.pinellia.uk/ipfs/QmQHyUhvEvkdPtXHCzrBL3JsE62PsjbKcHAcH1mFhksqDJ&quot; alt=&quot;&quot; /&gt;
小光圈，背景虚化越弱⬇️&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://ipfs.pinellia.uk/ipfs/QmUS394ov5o7NJyYqjKt1GkbK3mow6U6gEWq4SnVKqonq3&quot; alt=&quot;&quot; /&gt;
③虚化强弱的理解&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;光斑的形状来源于光圈扇叶形成的圆洞&lt;/strong&gt;
[&lt;img src=&quot;https://ipfs.pinellia.uk/ipfs/QmV1s9osojYYsVgdBSuk3gJF2ffMKc8LC8c19C281gDa3y&quot; alt=&quot;&quot; /&gt;
假如用卡纸剪出心形置于镜头前，光斑也成心形⬇️&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://ipfs.pinellia.uk/ipfs/QmZEjzyReiSeLp1h34DvHsBffTGbS1nemLgkKMYXLWsCyS&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://ipfs.pinellia.uk/ipfs/QmbuZtrtU44MBvrjevDqX1bUH89A9u2wZZVbnYoYPjziuj&quot; alt=&quot;&quot; /&gt;
④虚化的不止背景，还可以有前景。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;前景虚化&lt;/strong&gt; ，可增添照片的梦幻感⬇️&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://ipfs.pinellia.uk/ipfs/QmVs1MscQWeFa3NADBe1wu1L1D5HzGExsBZ4NjTaqkh64W&quot; alt=&quot;&quot; /&gt;
⑤光圈与对焦的关系&lt;/p&gt;
&lt;p&gt;光圈越大，越难对焦&lt;/p&gt;
&lt;p&gt;运动类照片，若用大光圈，则很难对焦。建议小光圈。&lt;/p&gt;
&lt;p&gt;【对焦，就是让清晰的区域（景深）与拍摄主体有重合，因此，小光圈易于对焦运动中的主体。】&lt;/p&gt;
&lt;h2&gt;2、快门&lt;/h2&gt;
&lt;p&gt;①影响了画面亮度，决定了动态模糊&lt;/p&gt;
&lt;p&gt;②动态模糊:&lt;/p&gt;
&lt;p&gt;慢快门时，假如相机抖动，将导致光在CMOS上有运动轨迹，进而导致照片糊掉&lt;/p&gt;
&lt;p&gt;自动挡时，使用大光圈，增大ISO，闪光灯或补光灯照亮主体，使用三脚架，可以尽可能避免相机使用慢快门，进而避免拍摄时，相机抖动导致照片糊掉。&lt;/p&gt;
&lt;p&gt;③&lt;strong&gt;慢速快门&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;是一种拍摄技巧，可用于拍摄光绘，星轨，车流，火花，王家卫式电影，运动类题材。&lt;/p&gt;
&lt;p&gt;eg:&lt;/p&gt;
&lt;p&gt;车流（为防止糊片，需要三脚架固定）⬇️
&lt;img src=&quot;https://ipfs.pinellia.uk/ipfs/QmVs1MscQWeFa3NADBe1wu1L1D5HzGExsBZ4NjTaqkh64W&quot; alt=&quot;&quot; /&gt;
星轨⬇️&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://ipfs.pinellia.uk/ipfs/QmcE4WUd6Y4r4DDHy4uMh8u2Xyj2ZsRh5Mn3W67JDuAVPF&quot; alt=&quot;&quot; /&gt;
烟花⬇️&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://ipfs.pinellia.uk/ipfs/QmZjFs1aZ1x33ouiisypqfrbikGEtDyW8bLp3FmP6jAuq8&quot; alt=&quot;&quot; /&gt;
运动镜头⬇️&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://ipfs.pinellia.uk/ipfs/QmRVSsDda3Mh4jTj6nJ8a4F7kT7G92Ty8UrJVaztiMgBXX&quot; alt=&quot;&quot; /&gt;
3. up总结&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;光圈大→提高亮度、产生虚化&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;快门慢→提高亮度、动态模糊&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;出题:&lt;/p&gt;
&lt;p&gt;大太阳下，如何既有虚化，又有动态模糊？（可以拍摄出一种运动感、速度感）&lt;/p&gt;
&lt;p&gt;如图⬇️&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://ipfs.pinellia.uk/ipfs/QmRw4jvmt7a1k7Ho5rBrRCgDDmRJbYQk6ZPxhjAr8BPSpy&quot; alt=&quot;&quot; /&gt;
答:___________________________&lt;/p&gt;
&lt;p&gt;Ps:如果大太阳下，即使ISO降到100，画面依然过曝，不得不减小光圈/调快快门。&lt;/p&gt;
&lt;p&gt;此时需要一个新道具——ND滤镜（有固定参数、可变参数两种）&lt;/p&gt;
&lt;p&gt;效果:使用前⬇️&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://ipfs.pinellia.uk/ipfs/QmZHB13kZNuMPYuqG5UbYLsndCT7dTbMDptoEqQW3RRoEW&quot; alt=&quot;&quot; /&gt;
使用后⬇️&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://ipfs.pinellia.uk/ipfs/QmUHxXGmeM42uu4js4pbiobacMcNYFVGLsTN9GnHjGfHQ3&quot; alt=&quot;&quot; /&gt;
4.人对事物理解的四个层次:（勉励自己运用）&lt;/p&gt;
&lt;p&gt;5.作业:拍摄尝试&lt;/p&gt;
</content:encoded></item><item><title>Markdown Extended Features</title><link>https://pinellia.uk/posts/markdown-extended/</link><guid isPermaLink="true">https://pinellia.uk/posts/markdown-extended/</guid><description>Read more about Markdown features in Fuwari</description><pubDate>Wed, 01 May 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;GitHub Repository Cards&lt;/h2&gt;
&lt;p&gt;You can add dynamic cards that link to GitHub repositories, on page load, the repository information is pulled from the GitHub API.&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;Fabrizz/MMM-OnSpotify&quot;}&lt;/p&gt;
&lt;p&gt;Create a GitHub repository card with the code &lt;code&gt;::github{repo=&quot;&amp;lt;owner&amp;gt;/&amp;lt;repo&amp;gt;&quot;}&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;::github{repo=&quot;saicaca/fuwari&quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Admonitions&lt;/h2&gt;
&lt;p&gt;Following types of admonitions are supported: &lt;code&gt;note&lt;/code&gt; &lt;code&gt;tip&lt;/code&gt; &lt;code&gt;important&lt;/code&gt; &lt;code&gt;warning&lt;/code&gt; &lt;code&gt;caution&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;:::note
Highlights information that users should take into account, even when skimming.
:::&lt;/p&gt;
&lt;p&gt;:::tip
Optional information to help a user be more successful.
:::&lt;/p&gt;
&lt;p&gt;:::important
Crucial information necessary for users to succeed.
:::&lt;/p&gt;
&lt;p&gt;:::warning
Critical content demanding immediate user attention due to potential risks.
:::&lt;/p&gt;
&lt;p&gt;:::caution
Negative potential consequences of an action.
:::&lt;/p&gt;
&lt;h3&gt;Basic Syntax&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;:::note
Highlights information that users should take into account, even when skimming.
:::

:::tip
Optional information to help a user be more successful.
:::
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Custom Titles&lt;/h3&gt;
&lt;p&gt;The title of the admonition can be customized.&lt;/p&gt;
&lt;p&gt;:::note[MY CUSTOM TITLE]
This is a note with a custom title.
:::&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::note[MY CUSTOM TITLE]
This is a note with a custom title.
:::
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;GitHub Syntax&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;[!TIP]
&lt;a href=&quot;https://github.com/orgs/community/discussions/16925&quot;&gt;The GitHub syntax&lt;/a&gt; is also supported.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; [!NOTE]
&amp;gt; The GitHub syntax is also supported.

&amp;gt; [!TIP]
&amp;gt; The GitHub syntax is also supported.
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Expressive Code Example</title><link>https://pinellia.uk/posts/expressive-code/</link><guid isPermaLink="true">https://pinellia.uk/posts/expressive-code/</guid><description>How code blocks look in Markdown using Expressive Code.</description><pubDate>Wed, 10 Apr 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Here, we&apos;ll explore how code blocks look using &lt;a href=&quot;https://expressive-code.com/&quot;&gt;Expressive Code&lt;/a&gt;. The provided examples are based on the official documentation, which you can refer to for further details.&lt;/p&gt;
&lt;h2&gt;Expressive Code&lt;/h2&gt;
&lt;h3&gt;Syntax Highlighting&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/key-features/syntax-highlighting/&quot;&gt;Syntax Highlighting&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Regular syntax highlighting&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;console.log(&apos;This code is syntax highlighted!&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Rendering ANSI escape sequences&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;ANSI colors:
- Regular: [31mRed[0m [32mGreen[0m [33mYellow[0m [34mBlue[0m [35mMagenta[0m [36mCyan[0m
- Bold:    [1;31mRed[0m [1;32mGreen[0m [1;33mYellow[0m [1;34mBlue[0m [1;35mMagenta[0m [1;36mCyan[0m
- Dimmed:  [2;31mRed[0m [2;32mGreen[0m [2;33mYellow[0m [2;34mBlue[0m [2;35mMagenta[0m [2;36mCyan[0m

256 colors (showing colors 160-177):
[38;5;160m160 [38;5;161m161 [38;5;162m162 [38;5;163m163 [38;5;164m164 [38;5;165m165[0m
[38;5;166m166 [38;5;167m167 [38;5;168m168 [38;5;169m169 [38;5;170m170 [38;5;171m171[0m
[38;5;172m172 [38;5;173m173 [38;5;174m174 [38;5;175m175 [38;5;176m176 [38;5;177m177[0m

Full RGB colors:
[38;2;34;139;34mForestGreen - RGB(34, 139, 34)[0m

Text formatting: [1mBold[0m [2mDimmed[0m [3mItalic[0m [4mUnderline[0m
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Editor &amp;amp; Terminal Frames&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/key-features/frames/&quot;&gt;Editor &amp;amp; Terminal Frames&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Code editor frames&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;console.log(&apos;Title attribute example&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- src/content/index.html --&amp;gt;
&amp;lt;div&amp;gt;File name comment example&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Terminal frames&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;This terminal frame has no title&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;Write-Output &quot;This one has a title!&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Overriding frame types&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;Look ma, no frame!&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;# Without overriding, this would be a terminal frame
function Watch-Tail { Get-Content -Tail 20 -Wait $args }
New-Alias tail Watch-Tail
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Text &amp;amp; Line Markers&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/key-features/text-markers/&quot;&gt;Text &amp;amp; Line Markers&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Marking full lines &amp;amp; line ranges&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;// Line 1 - targeted by line number
// Line 2
// Line 3
// Line 4 - targeted by line number
// Line 5
// Line 6
// Line 7 - targeted by range &quot;7-8&quot;
// Line 8 - targeted by range &quot;7-8&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Selecting line marker types (mark, ins, del)&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;function demo() {
  console.log(&apos;this line is marked as deleted&apos;)
  // This line and the next one are marked as inserted
  console.log(&apos;this is the second inserted line&apos;)

  return &apos;this line uses the neutral default marker type&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Adding labels to line markers&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;// labeled-line-markers.jsx
&amp;lt;button
  role=&quot;button&quot;
  {...props}
  value={value}
  className={buttonClassName}
  disabled={disabled}
  active={active}
&amp;gt;
  {children &amp;amp;&amp;amp;
    !active &amp;amp;&amp;amp;
    (typeof children === &apos;string&apos; ? &amp;lt;span&amp;gt;{children}&amp;lt;/span&amp;gt; : children)}
&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Adding long labels on their own lines&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;// labeled-line-markers.jsx
&amp;lt;button
  role=&quot;button&quot;
  {...props}

  value={value}
  className={buttonClassName}

  disabled={disabled}
  active={active}
&amp;gt;

  {children &amp;amp;&amp;amp;
    !active &amp;amp;&amp;amp;
    (typeof children === &apos;string&apos; ? &amp;lt;span&amp;gt;{children}&amp;lt;/span&amp;gt; : children)}
&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Using diff-like syntax&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;+this line will be marked as inserted
-this line will be marked as deleted
this is a regular line
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
+this is an actual diff file
-all contents will remain unmodified
 no whitespace will be removed either
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Combining syntax highlighting with diff-like syntax&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;  function thisIsJavaScript() {
    // This entire block gets highlighted as JavaScript,
    // and we can still add diff markers to it!
-   console.log(&apos;Old code to be removed&apos;)
+   console.log(&apos;New and shiny code!&apos;)
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Marking individual text inside lines&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;function demo() {
  // Mark any given text inside lines
  return &apos;Multiple matches of the given text are supported&apos;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Regular expressions&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;console.log(&apos;The words yes and yep will be marked.&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Escaping forward slashes&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;Test&quot; &amp;gt; /home/test.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Selecting inline marker types (mark, ins, del)&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;function demo() {
  console.log(&apos;These are inserted and deleted marker types&apos;);
  // The return statement uses the default marker type
  return true;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Word Wrap&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/key-features/word-wrap/&quot;&gt;Word Wrap&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Configuring word wrap per block&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;// Example with wrap
function getLongString() {
  return &apos;This is a very long string that will most probably not fit into the available space unless the container is extremely wide&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;// Example with wrap=false
function getLongString() {
  return &apos;This is a very long string that will most probably not fit into the available space unless the container is extremely wide&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Configuring indentation of wrapped lines&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;// Example with preserveIndent (enabled by default)
function getLongString() {
  return &apos;This is a very long string that will most probably not fit into the available space unless the container is extremely wide&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;// Example with preserveIndent=false
function getLongString() {
  return &apos;This is a very long string that will most probably not fit into the available space unless the container is extremely wide&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Collapsible Sections&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/plugins/collapsible-sections/&quot;&gt;Collapsible Sections&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// All this boilerplate setup code will be collapsed
import { someBoilerplateEngine } from &apos;@example/some-boilerplate&apos;
import { evenMoreBoilerplate } from &apos;@example/even-more-boilerplate&apos;

const engine = someBoilerplateEngine(evenMoreBoilerplate())

// This part of the code will be visible by default
engine.doSomething(1, 2, 3, calcFn)

function calcFn() {
  // You can have multiple collapsed sections
  const a = 1
  const b = 2
  const c = a + b

  // This will remain visible
  console.log(`Calculation result: ${a} + ${b} = ${c}`)
  return c
}

// All this code until the end of the block will be collapsed again
engine.closeConnection()
engine.freeMemory()
engine.shutdown({ reason: &apos;End of example boilerplate code&apos; })
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Line Numbers&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/plugins/line-numbers/&quot;&gt;Line Numbers&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Displaying line numbers per block&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// This code block will show line numbers
console.log(&apos;Greetings from line 2!&apos;)
console.log(&apos;I am on line 3&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;// Line numbers are disabled for this block
console.log(&apos;Hello?&apos;)
console.log(&apos;Sorry, do you know what line I am on?&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Changing the starting line number&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;console.log(&apos;Greetings from line 5!&apos;)
console.log(&apos;I am on line 6&apos;)
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Simple Guides for Fuwari</title><link>https://pinellia.uk/posts/guide/</link><guid isPermaLink="true">https://pinellia.uk/posts/guide/</guid><description>How to use this blog template.</description><pubDate>Mon, 01 Apr 2024 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;Cover image source: &lt;a href=&quot;https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/208fc754-890d-4adb-9753-2c963332675d/width=2048/01651-1456859105-(colour_1.5),girl,_Blue,yellow,green,cyan,purple,red,pink,_best,8k,UHD,masterpiece,male%20focus,%201boy,gloves,%20ponytail,%20long%20hair,.jpeg&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This blog template is built with &lt;a href=&quot;https://astro.build/&quot;&gt;Astro&lt;/a&gt;. For the things that are not mentioned in this guide, you may find the answers in the &lt;a href=&quot;https://docs.astro.build/&quot;&gt;Astro Docs&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Front-matter of Posts&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;---
title: My First Blog Post
published: 2023-09-09
description: This is the first post of my new Astro blog.
image: ./cover.jpg
tags: [Foo, Bar]
category: Front-end
draft: false
---
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attribute&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;title&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The title of the post.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;published&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The date the post was published.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;description&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A short description of the post. Displayed on index page.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;image&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The cover image path of the post.&lt;code&gt;1. Start with `http://` or `https://`: Use web image&lt;/code&gt;2. Start with &lt;code&gt;/&lt;/code&gt;: For image in &lt;code&gt;public&lt;/code&gt; dir``3. With none of the prefixes: Relative to the markdown file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tags&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The tags of the post.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;category&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The category of the post.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;draft&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;If this post is still a draft, which won&apos;t be displayed.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Where to Place the Post Files&lt;/h2&gt;
&lt;p&gt;Your post files should be placed in &lt;code&gt;src/content/posts/&lt;/code&gt; directory. You can also create sub-directories to better organize your posts and assets.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;src/content/posts/
├── post-1.md
└── post-2/
    ├── cover.png
    └── index.md
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Markdown Example</title><link>https://pinellia.uk/posts/markdown/</link><guid isPermaLink="true">https://pinellia.uk/posts/markdown/</guid><description>A simple example of a Markdown blog post.</description><pubDate>Sun, 01 Oct 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;An h1 header&lt;/h1&gt;
&lt;p&gt;Paragraphs are separated by a blank line.&lt;/p&gt;
&lt;p&gt;2nd paragraph. &lt;em&gt;Italic&lt;/em&gt;, &lt;strong&gt;bold&lt;/strong&gt;, and &lt;code&gt;monospace&lt;/code&gt;. Itemized lists
look like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;this one&lt;/li&gt;
&lt;li&gt;that one&lt;/li&gt;
&lt;li&gt;the other one&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that --- not considering the asterisk --- the actual text
content starts at 4-columns in.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Block quotes are
written like so.&lt;/p&gt;
&lt;p&gt;They can span multiple paragraphs,
if you like.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Use 3 dashes for an em-dash. Use 2 dashes for ranges (ex., &quot;it&apos;s all
in chapters 12--14&quot;). Three dots ... will be converted to an ellipsis.
Unicode is supported. ☺&lt;/p&gt;
&lt;h2&gt;An h2 header&lt;/h2&gt;
&lt;p&gt;Here&apos;s a numbered list:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;first item&lt;/li&gt;
&lt;li&gt;second item&lt;/li&gt;
&lt;li&gt;third item&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Note again how the actual text starts at 4 columns in (4 characters
from the left side). Here&apos;s a code sample:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Let me re-iterate ...
for i in 1 .. 10 { do-something(i) }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you probably guessed, indented 4 spaces. By the way, instead of
indenting the block, you can use delimited blocks, if you like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;define foobar() {
    print &quot;Welcome to flavor country!&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(which makes copying &amp;amp; pasting easier). You can optionally mark the
delimited block for Pandoc to syntax highlight it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import time
# Quick, count to ten!
for i in range(10):
    # (but not *too* quick)
    time.sleep(0.5)
    print i
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;An h3 header&lt;/h3&gt;
&lt;p&gt;Now a nested list:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;First, get these ingredients:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;carrots&lt;/li&gt;
&lt;li&gt;celery&lt;/li&gt;
&lt;li&gt;lentils&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Boil some water.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dump everything in the pot and follow
this algorithm:&lt;/p&gt;
&lt;p&gt;find wooden spoon
uncover pot
stir
cover pot
balance wooden spoon precariously on pot handle
wait 10 minutes
goto first step (or shut off burner when done)&lt;/p&gt;
&lt;p&gt;Do not bump wooden spoon or it will fall.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Notice again how text always lines up on 4-space indents (including
that last line which continues item 3 above).&lt;/p&gt;
&lt;p&gt;Here&apos;s a link to &lt;a href=&quot;http://foo.bar&quot;&gt;a website&lt;/a&gt;, to a &lt;a href=&quot;local-doc.html&quot;&gt;local
doc&lt;/a&gt;, and to a &lt;a href=&quot;#an-h2-header&quot;&gt;section heading in the current
doc&lt;/a&gt;. Here&apos;s a footnote [^1].&lt;/p&gt;
&lt;p&gt;Tables can look like this:&lt;/p&gt;
&lt;p&gt;size material color&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;9 leather brown
10 hemp canvas natural
11 glass transparent&lt;/p&gt;
&lt;p&gt;Table: Shoes, their sizes, and what they&apos;re made of&lt;/p&gt;
&lt;p&gt;(The above is the caption for the table.) Pandoc also supports
multi-line tables:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;keyword text&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;red Sunsets, apples, and
other red or reddish
things.&lt;/p&gt;
&lt;p&gt;green Leaves, grass, frogs
and other things it&apos;s
not easy being.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;A horizontal rule follows.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Here&apos;s a definition list:&lt;/p&gt;
&lt;p&gt;apples
: Good for making applesauce.
oranges
: Citrus!
tomatoes
: There&apos;s no &quot;e&quot; in tomatoe.&lt;/p&gt;
&lt;p&gt;Again, text is indented 4 spaces. (Put a blank line between each
term/definition pair to spread things out more.)&lt;/p&gt;
&lt;p&gt;Here&apos;s a &quot;line block&quot;:&lt;/p&gt;
&lt;p&gt;| Line one
| Line too
| Line tree&lt;/p&gt;
&lt;p&gt;and images can be specified like so:&lt;/p&gt;
&lt;p&gt;Inline math equations go in like so: $\omega = d\phi / dt$. Display
math should get its own line and be put in in double-dollarsigns:&lt;/p&gt;
&lt;p&gt;$$
I = \int \rho R^{2} dV
$$&lt;/p&gt;
&lt;p&gt;$$
\begin{equation*}
\pi
=3.1415926535
;8979323846;2643383279;5028841971;6939937510;5820974944
;5923078164;0628620899;8628034825;3421170679;\ldots
\end{equation*}
$$&lt;/p&gt;
&lt;p&gt;And note that you can backslash-escape any punctuation characters
which you wish to be displayed literally, ex.: `foo`, *bar*, etc.&lt;/p&gt;
&lt;p&gt;[^1]: Footnote text goes here.&lt;/p&gt;
</content:encoded></item><item><title>Include Video in the Posts</title><link>https://pinellia.uk/posts/video/</link><guid isPermaLink="true">https://pinellia.uk/posts/video/</guid><description>This post demonstrates how to include embedded video in a blog post.</description><pubDate>Tue, 01 Aug 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Just copy the embed code from YouTube or other platforms, and paste it in the markdown file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
title: Include Video in the Post
published: 2023-10-19
// ...
---

&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot; src=&quot;https://www.youtube.com/embed/5gIf0_xpFPI?si=N1WTorLKL0uwLsU_&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;YouTube&lt;/h2&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot; src=&quot;https://www.youtube.com/embed/5gIf0_xpFPI?si=N1WTorLKL0uwLsU_&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h2&gt;Bilibili&lt;/h2&gt;
&lt;p&gt;&amp;lt;div style=&quot;position: relative; width: 60%; aspect-ratio: 16/9;&quot;&amp;gt;
&amp;lt;iframe src=&quot;//player.bilibili.com/player.html?bvid=BV1Fm4ZzDEeY&quot;
style=&quot;position: absolute; top: 0; left: 0; width: 100%; height: 100%;&quot;
scrolling=&quot;no&quot; border=&quot;0&quot; frameborder=&quot;no&quot; framespacing=&quot;0&quot; allowfullscreen=&quot;true&quot;&amp;gt;&amp;lt;/iframe&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;h2&gt;m3u8&lt;/h2&gt;
&lt;p&gt;&amp;lt;iframe src=&quot;https://m3u8player.org/player.html?url=https://raw.githubusercontent.com/Pinellia451/m3u8-storge/refs/heads/main/11.m3u8&quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
</content:encoded></item></channel></rss>