<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>技术专栏</title>
		<description>快速发布新文章的个人技术专栏</description>
		<link>https://www.mowchan.me/</link>
		<atom:link href="https://www.mowchan.me/feed.xml" rel="self" type="application/rss+xml"/>
		<pubDate>Thu, 19 Aug 2021 15:23:28 +0800</pubDate>
		<lastBuildDate>Thu, 19 Aug 2021 15:23:28 +0800</lastBuildDate>
		<generator>Jekyll v3.9.0</generator>
		
			<item>
				<title>用 Acrobat 修复因缺少内嵌字体而乱码的 PDF 文件</title>
				<description>&lt;h3 id=&quot;前言&quot;&gt;前言&lt;/h3&gt;

&lt;p&gt;最近在阅读一本电子书的时候发现 PDF 文件中只要是英文、数字、空格的位置都是乱码，影响阅读。这应该是 PDF 文档没有将所需要的所有字体内嵌到文档中，缺少字体导致的。比如某东的电子发票在不同的 PDF 阅读软件上打开会出现不同的字体。&lt;/p&gt;

&lt;p&gt;这里分享一下修复文档的整个过程。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.jsdelivr.net/gh/mowchann/blog-static@master/image/column/post/2021/20210815-124826.webp&quot; alt=&quot;乱码文档&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;需要软件&quot;&gt;需要软件&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Adobe Acrobat Pro DC 2020&lt;/li&gt;
  &lt;li&gt;文件中尚未内嵌的字体（方正EU系列）&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;检查字体缺失&quot;&gt;检查字体缺失&lt;/h3&gt;
&lt;p&gt;PDF 文档出现乱码，首先要检查是否是缺失字体。用 Acrobat 打开 PDF 文件，菜单栏选择“文件”、“属性”、“字体”选项卡，可以看到该 PDF 文档中使用的所有字体。
&lt;img src=&quot;https://cdn.jsdelivr.net/gh/mowchann/blog-static@master/image/column/post/2021/20210815-124829.webp&quot; alt=&quot;缺失字体&quot; /&gt;
已内嵌文档的字体会显示“（已嵌入）”，未嵌入的字体，如图中的&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EU-BX.ttf&lt;/code&gt;字体是方正的西文“白斜”字体，由于不同的 PDF 阅读器遇到字体缺失后会选择一个缺省字体替代，而不同字体的字符集不同，所以会出现乱码的情况。&lt;/p&gt;

&lt;h3 id=&quot;缺失字体修复&quot;&gt;缺失字体修复&lt;/h3&gt;
&lt;p&gt;首先找到缺失的字体文件，安装到电脑中。一般来说，安装好缺失字体后再用 PDF 阅读器查看文档就不会乱码，文档恢复正常。但是 PDF 文件是跨平台的便携式文档，如果要在其它设备上不出问题还是要将所需的字体全部嵌入。&lt;/p&gt;

&lt;p&gt;回到 Acrobat 的“主页”，添加“印刷制作”工具。
&lt;img src=&quot;https://cdn.jsdelivr.net/gh/mowchann/blog-static@master/image/column/post/2021/20210815-124832.webp&quot; alt=&quot;添加“印刷制作”工具&quot; /&gt;
打开要修复的文件，在右侧工具栏选择“印刷制作”、“印前检查”。
&lt;img src=&quot;https://cdn.jsdelivr.net/gh/mowchann/blog-static@master/image/column/post/2021/20210815-124836.webp&quot; alt=&quot;选择“印刷制作”、“印前检查”&quot; /&gt;&lt;/p&gt;

&lt;p&gt;“印前检查”选择“PDF 修正”、“嵌入缺失的字体”，然后点击“分析和修复”，保存修复后的文件，稍等一会。
&lt;img src=&quot;https://cdn.jsdelivr.net/gh/mowchann/blog-static@master/image/column/post/2021/20210815-124839.webp&quot; alt=&quot;印前检查选择“嵌入缺失的字体”&quot; /&gt;
经过一小段时间的修复，如果最终的结果是“没有找到问题”说明文件已成功修复。
&lt;img src=&quot;https://cdn.jsdelivr.net/gh/mowchann/blog-static@master/image/column/post/2021/20210815-124843.webp&quot; alt=&quot;修复完成&quot; /&gt;
打开修复后的文件，查看文档属性，缺失的字体已经嵌入，可以正常显示。
&lt;img src=&quot;https://cdn.jsdelivr.net/gh/mowchann/blog-static@master/image/column/post/2021/20210815-124846.webp&quot; alt=&quot;缺失的字体已嵌入&quot; /&gt;
修复前后的扉页
&lt;img src=&quot;https://cdn.jsdelivr.net/gh/mowchann/blog-static@master/image/column/post/2021/20210815-124849.webp&quot; alt=&quot;修复前后的扉页&quot; /&gt;&lt;/p&gt;
&lt;h3 id=&quot;吐槽&quot;&gt;吐槽&lt;/h3&gt;
&lt;p&gt;PDF 文件格式相当灵活，各种编译器、阅读器在实现上没有统一的标准，所以导致 PDF 文件容易出现各种奇奇怪怪的问题。比如某文档扫描 App 生成的 PDF 无法用 Python 的 PyPDF 编辑，报错原因是页码错误。经过我测试发现是 PDF 不符合标准，将文件转换成 PDF/A 标准的格式就恢复正常了。&lt;/p&gt;

&lt;h3 id=&quot;参考资料&quot;&gt;参考资料&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://blog.csdn.net/u011889952/article/details/92073967&quot;&gt;修复pdf字体嵌入问题_NEWPLAN的专栏-CSDN博客_解决pdf字体嵌入&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
				<pubDate>Sun, 15 Aug 2021 19:00:00 +0800</pubDate>
				<link>https://www.mowchan.me/post/2021/acrobat-fix-pdf-embedded-font.html</link>
				<guid isPermaLink="true">https://www.mowchan.me/post/2021/acrobat-fix-pdf-embedded-font.html</guid>
				
				<category>PDF</category>
				
				<category>Acrobat</category>
				
				
				<category>Operation</category>
				
			</item>
		
			<item>
				<title>GitHub 不再支持用账户密码进行 Git 项目操作</title>
				<description>&lt;p&gt;GitHub 考虑到账户安全，从 2021年8月13日（北京时间14日）起不再允许用 GitHub 账户密码对 Repository 进行操作，也就是无法用 GitHub 账号密码或是 SSH 地址携带密码 Clone 访问受限的 Repository。GitHub 官方推荐使用基于 RSA 的 SSH Key 或者账号的 Token Key 替代。&lt;/p&gt;

&lt;p&gt;但是因为我有两个账户在使用，为了方便主账号采用 SSH Keys 作为全局账号使用，副账号使用账号密码直接操作，但是 Git 全局配置只能有一个全局账号，所以需要做一些调整。&lt;/p&gt;

&lt;h3 id=&quot;解决方法&quot;&gt;解决方法&lt;/h3&gt;

&lt;h4 id=&quot;方法一使用-ssh-keys&quot;&gt;方法一、使用 SSH Keys&lt;/h4&gt;

&lt;p&gt;首先，分别为两个 GitHub 账号生成 SSH 密钥&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~/.ssh
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;ssh-keygen &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; rsa &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; id_rsa_1 &lt;span class=&quot;nt&quot;&gt;-C&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;username1@mail.com&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;ssh-keygen &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; rsa &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; id_rsa_2 &lt;span class=&quot;nt&quot;&gt;-C&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;username2@mail.com&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;在&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.ssh/&lt;/code&gt;（Linux） &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C:\Users\用户名\.ssh\&lt;/code&gt;（Windows）路径下会出现四个文件：&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;id_rsa_1
id_rsa_1.pub
id_rsa_2
id_rsa_2.pub
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;然后在 GitHub 上 &lt;a href=&quot;https://github.com/settings/keys&quot;&gt;https://github.com/settings/keys&lt;/a&gt; 配置 SSH Keys，将公钥（&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*.pub&lt;/code&gt;文件）的所有内容填到 GitHub 上。&lt;/p&gt;

&lt;p&gt;之后在&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.ssh&lt;/code&gt;目录下配置&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;config&lt;/code&gt;文件&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# 第一个账号&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;Host github.com&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;HostName github.com&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;User username1&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;IdentityFile ~/.ssh/id_rsa_1&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# 第二个账号&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;Host github.com&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;HostName github.com&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;User username2&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;IdentityFile ~/.ssh/id_rsa_2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;最后在项目目录下配置该项目的用户名、邮箱&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git config user.name &lt;span class=&quot;s1&quot;&gt;'your_username'&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git config user.email &lt;span class=&quot;s1&quot;&gt;'your_email'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;或者直接编辑项目目录下的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.git/config&lt;/code&gt; 文件&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;name = your_username&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;email = your_email&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;方法二使用-token-keys&quot;&gt;方法二、使用 Token Keys&lt;/h4&gt;

&lt;p&gt;在 &lt;a href=&quot;https://github.com/settings/tokens&quot;&gt;https://github.com/settings/tokens&lt;/a&gt; 配置 Token Keys，如果只需要 Repository 的 Git 基本操作，权限列表中只勾选 Repo 即可，确认后会生成 Token Keys。注意 Token 仅此显示一次，以后不再显示，所以要保存好 Token。&lt;/p&gt;

&lt;p&gt;在项目的目录下配置该项目的用户名、邮箱以及密码&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git config user.name &lt;span class=&quot;s1&quot;&gt;'your_username'&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git config user.email &lt;span class=&quot;s1&quot;&gt;'your_email'&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git config user.password &lt;span class=&quot;s1&quot;&gt;'your_token'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;或者直接编辑 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.git/config&lt;/code&gt; 文件，增加如下几行&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;name = your_username&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;email = your_email&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;password = your_token&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;即可以该账户操作。&lt;/p&gt;

&lt;h3 id=&quot;参考来源&quot;&gt;参考来源&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/&quot;&gt;Token authentication requirements for Git operations | The GitHub Blog&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.github.com/en/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token&quot;&gt;Creating a personal access token - GitHub Docs&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://blog.csdn.net/weixin_30883271/article/details/96297742&quot;&gt;同一个电脑配置两个github账号_weixin_30883271的博客-CSDN博客&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
				<pubDate>Sun, 15 Aug 2021 01:30:00 +0800</pubDate>
				<link>https://www.mowchan.me/post/2021/github-not-allow-password-operation.html</link>
				<guid isPermaLink="true">https://www.mowchan.me/post/2021/github-not-allow-password-operation.html</guid>
				
				<category>GitHub</category>
				
				<category>Git</category>
				
				
				<category>Operation</category>
				
			</item>
		
			<item>
				<title>手动修复损坏的 FLAC 文件头</title>
				<description>&lt;p&gt;最近在使用 MP3Tag 软件给音乐添加标签时会出现文件损坏的情况，使用环境如下：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;添加或修改标签时音乐文件被 Windows Media Player 占用&lt;/p&gt;

  &lt;p&gt;MP3Tag 版本：3.06a&lt;/p&gt;

  &lt;p&gt;系统环境：Windows 10 LTSC 2019 x64&lt;/p&gt;

  &lt;p&gt;损坏文件类型：flac&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.jsdelivr.net/gh/mowchann/blog-static@master/image/column/post/2021/20210705-101844.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;之后我尝试用 FFmpeg、其它主流的格式转换软件修复均告失败。用 WinHex 查看损坏的音乐文件，发现文件开始都是&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;00&lt;/code&gt;填充。合理怀疑是 MP3Tag 在修改或添加标签时把文件头丢了。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.jsdelivr.net/gh/mowchann/blog-static@master/image/column/post/2021/20210705-105248.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;动手修复，最简单的方法是将正常的FLAC文件文件头复制到损坏文件头位置。因为对FLAC文件头格式不了解，如果手动将FLAC文件头含有的标签信息剔除掉仍然无法修复文件，所以只能是带着其它音乐的标签信息一起粘贴过来。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.jsdelivr.net/gh/mowchann/blog-static@master/image/column/post/2021/20210604-112828.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;保存后，可以看到资源管理器已经读出标签信息。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.jsdelivr.net/gh/mowchann/blog-static@master/image/column/post/2021/20210604-112758.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;需要注意的是，要完整地将标签信息复制过来，如果缺少某个字节可能会使得标签文本解析错误，导致资源管理器崩溃。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.jsdelivr.net/gh/mowchann/blog-static@master/image/column/post/2021/20210604-115621.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;最后，再用 MP3Tag 修改为正确的标签，修复完成！&lt;/p&gt;
</description>
				<pubDate>Sat, 05 Jun 2021 04:00:00 +0800</pubDate>
				<link>https://www.mowchan.me/post/2021/flac-header-fix.html</link>
				<guid isPermaLink="true">https://www.mowchan.me/post/2021/flac-header-fix.html</guid>
				
				<category>flac</category>
				
				<category>文件头</category>
				
				
				<category>Operation</category>
				
			</item>
		
			<item>
				<title>让KaTeX支持\ref和\label（引用、标签）功能</title>
				<description>&lt;p&gt;最近在使用 KaTeX 时发现，一般 LaTeX 引擎或者 MathJax 支持的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\ref&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\label&lt;/code&gt;功能在KaTeX中是没有的。而且尽管在 Github 上提出加入这两个指令的 issue 很多，但官方明确说明目前是没有这个计划的。&lt;/p&gt;

&lt;p&gt;受一条 &lt;a href=&quot;https://github.com/falgon/roki-web/issues/34#issuecomment-673056997&quot;&gt;Issue&lt;/a&gt; 启发，我尝试用 KaTeX 的宏功能结合其它可用的指令模拟了&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\ref&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\label&lt;/code&gt;功能，效果很好。&lt;/p&gt;

&lt;p&gt;首先需要对 KaTeX 进行配置。&lt;/p&gt;

&lt;p&gt;KaTeX 默认是禁用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\htmlId&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\href&lt;/code&gt;命令的，因此需要先信任这两条指令。（KaTeX 的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;trust&lt;/code&gt; 配置值类型为&lt;strong&gt;布尔型&lt;/strong&gt;或&lt;strong&gt;函数&lt;/strong&gt;，我之前的&lt;strong&gt;数组&lt;/strong&gt;类型是不符合要求的，在 &lt;a href=&quot;https://github.com/KaTeX/KaTeX/issues/2003#issuecomment-863923688&quot;&gt;GitHub 上的讨论&lt;/a&gt; 指出了这一点错误，正确的配置方法参考&lt;a href=&quot;https://github.com/KaTeX/KaTeX/blob/master/docs/options.md&quot;&gt;官方文档&lt;/a&gt;）&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;trust&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;htmlId&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;includes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;macros&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;eqref&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;href{###1}{(&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;text{#1})}&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;href{###1}{&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;text{#1}}&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;htmlId{#1}{}&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;然后在配置中定义我们需要的宏。&lt;/p&gt;

&lt;p&gt;在KaTeX的宏定义中，可以以&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#数字&lt;/code&gt;的形式设置占位符，按顺序对应定义的参数。如&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\test{1}{2}{3}&lt;/code&gt;宏指令的定义若要依次引用第1、2、3个参数，就以&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#1&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#2&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#3&lt;/code&gt;占位即可。占位符可重复引用，不同的占位符最多9个。&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\label&lt;/code&gt;指令用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\htmlId&lt;/code&gt;模拟，用于生成页面内锚点，在LaTeX中与&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\tag&lt;/code&gt;或&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\caption&lt;/code&gt;配合使用，所以我们在这里也将&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\htmlId&lt;/code&gt;的第二个参数留空，在页面上不做显示。&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\ref&lt;/code&gt;和&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\eqref&lt;/code&gt;指令都是引用，区别在于后者会加上括号，一般用于公式的引用。我们用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\href&lt;/code&gt;指令来模拟，第一个参数是跳转的链接，第二个指令是引用显示。一般引用显示都是数字或字母的编号，为了避免被 KaTeX 引擎识别为变量，加一个&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\text&lt;/code&gt;指令。需要注意的是，由于页面锚点的URL也是用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#&lt;/code&gt;表示，这会引发和宏定义占位符的冲突。所幸 KaTeX 的引擎考虑到了这一点，使用两个&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#&lt;/code&gt;，也就是&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;##&lt;/code&gt;就可以表示&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#&lt;/code&gt;本身，而不会被当作占位符解析（其实是我试出来的）。&lt;/p&gt;

&lt;p&gt;样例如下&lt;/p&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Search by definition $\eqref{1-3}$ or $\ref{1-3}$.

&lt;span class=&quot;nt&quot;&gt;&amp;lt;br&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;br&amp;gt;&lt;/span&gt;

$$
\begin{aligned} \sin 2\theta = 2\sin \theta \cos \theta \\ = \cfrac{2 \tan \theta}{1+\tan^2 \theta} \end{aligned} \label{1-3}\tag{1-3}
$$
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;经过测试，指令内所填的引用名无论是数字、英文还是常用的字符组合都可以正常使用，如图&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.jsdelivr.net/gh/mowchann/blog-static/image/column/post/2021/20210519-180634.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;参考链接&quot;&gt;参考链接&lt;/h4&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/falgon/roki-web/issues/34&quot;&gt;Referencing formula numbers in articles · Issue #34 · falgon/roki-web (github.com)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://katex.org/docs/supported.html#macros&quot;&gt;Macros - Supported Functions · KaTeX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://katex.org/docs/supported.html#html&quot;&gt;HTML - Supported Functions · KaTeX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://katex.org/docs/options.html&quot;&gt;Options · KaTeX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/KaTeX/KaTeX/blob/master/docs/options.md&quot;&gt;KaTeX/options.md at master · KaTeX/KaTeX (github.com)&lt;/a&gt;&lt;/p&gt;

</description>
				<pubDate>Thu, 20 May 2021 01:00:00 +0800</pubDate>
				<link>https://www.mowchan.me/post/2021/katex-ref-label-support.html</link>
				<guid isPermaLink="true">https://www.mowchan.me/post/2021/katex-ref-label-support.html</guid>
				
				<category>前端</category>
				
				<category>KaTeX</category>
				
				<category>数学公式</category>
				
				<category>引用</category>
				
				<category>LaTeX</category>
				
				
				<category>Frontend</category>
				
			</item>
		
			<item>
				<title>用人话讲明白支持向量机SVM的数学原理</title>
				<description>&lt;h3 id=&quot;1-什么是svm&quot;&gt;1. 什么是SVM&lt;/h3&gt;

&lt;p&gt;SVM支持向量机，号称&lt;strong&gt;机器学习的拦路虎&lt;/strong&gt;。江湖传言，遇到了他，机器学习就会从入门到放弃。另一方面也就是说，只要搞定了SVM，后面的算法模型学起来都是小意思。&lt;/p&gt;

&lt;p&gt;先看下官方定义：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;支持向量机方法是建立在统计学习理论的VC维理论和结构风险最小原理基础上的，根据有限的样本信息在模型的复杂性和学习能力之间寻求最佳折衷，以期获得最好的泛化能力。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;VC 维，结构风险，有限样本，模型复杂性，最佳折衷，泛化能力，这一切……真是让人摸不着头脑……&lt;/p&gt;

&lt;p&gt;行了，文绉绉的理论从来看不懂，我们还是从算法看起吧。&lt;/p&gt;

&lt;p&gt;SVM一般用于&lt;strong&gt;解决二分类问题&lt;/strong&gt;（也可以解决多分类和回归问题，本文暂不涉及），数学化语言概述如下：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;样本数据&lt;/strong&gt;：$n$个样本，$p$个输入 $(x_{1},\cdots,x_{p})$ ，1个输出$y$&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第$i$个样本的输入&lt;/strong&gt;： $X_{i}=(x_{i1},x_{i2},\cdots,x_{ip})^{T}, i=1,2,\cdots n$&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;输出$y$&lt;/strong&gt;：一般用$1$和$-1$作为两类样本的标签&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;训练样本集$D$&lt;/strong&gt;：
\(D=\begin{pmatrix}  x_{11}, &amp;amp; x_{12} , &amp;amp; x_{13} , &amp;amp; \cdots , &amp;amp; x_{1p}, &amp;amp; y_{1} \\x_{21} ,&amp;amp; x_{22} , &amp;amp; x_{23} , &amp;amp; \cdots , &amp;amp; x_{2p},  &amp;amp; y_{2} \\&amp;amp; &amp;amp; \cdots \\&amp;amp; &amp;amp; \cdots \\x_{n1} ,&amp;amp; x_{n2},  &amp;amp; x_{n3} , &amp;amp; \cdots , &amp;amp; x_{np},  &amp;amp; y_{n} \end{pmatrix}\)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;训练目的&lt;/strong&gt;：以训练样本为研究对象，在样本的特征空间中找到一个超平面 $W^{T}X+b=0$
，将两类样本（$+1$和$-1$）有效分开，其中 $W=(w_{1},w_{2},\cdots,w_{p})^{T}$&lt;/p&gt;

&lt;p&gt;然而，这些个公式更是看的云里雾里。没关系，抽象的数学语言难以理解，那我们就从直观的图形和例子开始，抽丝剥茧一点点学。&lt;/p&gt;

&lt;h3 id=&quot;2-线性分类器的含义&quot;&gt;2. 线性分类器的含义&lt;/h3&gt;

&lt;p&gt;上一篇学线性回归时，是从一元线性回归讲起。一元，即一个自变量，再加上一个因变量，这种数据形式在二维坐标轴中就可以表示成$(x,y)$。$(x,y)$的数据形式可以通过画点、画线在二维平面上进行展示，方便初学者理解。&lt;/p&gt;

&lt;p&gt;学习算法时通过图的形式来入门，最合适不过。那么，我们讲SVM也从平面上的点和线讲起不就好了。&lt;/p&gt;

&lt;p&gt;我们用图看看线性分类器要解决什么样的问题。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.jsdelivr.net/gh/mowchann/blog-static/image/column/post/2021/20210519-121506.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;假设有两类要区分的样本点，一类用黄色圆点代表，另一类用红色方形代表，中间这条直线就是一条能将两类样本完全分开的分类函数。&lt;/p&gt;

&lt;p&gt;用前面的数学化语言描述一下这个图，就是：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;样本数据&lt;/strong&gt;：11个样本，2个输入 $(x_{1},x_{2})$，一个输出$y$&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第$i$个样本的输入&lt;/strong&gt;： $X_{i}=(x_{i1},x_{i2})^{T}, i=1,2,\cdots 11$&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;输出$y$&lt;/strong&gt;：用$+1$（红色方形）和$-1$（黄色圆点）作为标签&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;训练样本集$D$&lt;/strong&gt;：&lt;/p&gt;

\[D=\begin{pmatrix}  x_{11}, &amp;amp; x_{12} , &amp;amp; y_{1} \\x_{21} ,&amp;amp; x_{22} , &amp;amp; y_{2} \\&amp;amp;\cdots \\x_{n1} ,&amp;amp; x_{n2},  &amp;amp; y_{n} \end{pmatrix},n=11\]

&lt;p&gt;&lt;strong&gt;训练目的&lt;/strong&gt;：以训练样本为研究对象，找到一条直线 $w_{1}x_{1}+w_{2}x_{2}+b=0$，将两类样本有效分开。&lt;/p&gt;

&lt;p&gt;这里我们引出线性可分的定义：&lt;strong&gt;如果一个线性函数能够将样本分开，就称这些样本是线性可分的&lt;/strong&gt;。线性函数在一维空间里，就是一个小小的点；在二维可视化图像中，是一条直直的线；在三维空间中，是一个平平的面；在更高维的空间中，是无法直观用图形展示的超平面。&lt;/p&gt;

&lt;p&gt;回想一下线性回归，在一元线性回归中我们要找拟合一条直线，使得样本点$(x, y)$都落在直线附近；在二元线性回归中，要拟合一个平面，使得样本点$(x_1, x_2, y)$都落在该平面附近；在更高维的情况下，就是拟合超平面。&lt;/p&gt;

&lt;p&gt;那么，线性分类（此处仅指二分类）呢？当样本点为$(x, y)$时（注意，和回归不同，由于$y$是分类标签，$y$的数字表示是只有属性含义，是没有真正的数值意义的，因此当只有一个自变量时，不是二维问题而是一维问题），要找到一个点$wx+b=0$，即$x=-b/w$这个点，使得该点左边的是一类，右边的是另一类。&lt;/p&gt;

&lt;p&gt;当样本点为$(x_1, x_2, y)$时，要找到一条直线 $w_{1}x_{1}+w_{2}x_{2}+b=0$ ，将平面划分成两块，使得 $w_{1}x_{1}+w_{2}x_{2}+b&amp;gt;0$的区域是$y=1$类的点，$w_{1}x_{1}+w_{2}x_{2}+b&amp;lt;0$ 的区域是$y=-1$类别的点。&lt;/p&gt;

&lt;p&gt;更高维度以此类推，由于更高维度的的超平面要写成$w_{1}x_{1}+w_{2}x_{2}+\cdots +w_{p}x_{p}+b=0$ 会有点麻烦，一般会用矩阵表达式代替，即上面的 $W^{T}X+b=0$ 。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.jsdelivr.net/gh/mowchann/blog-static/image/column/post/2021/20210519-122328.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;$W^{T}X+b=0$ 这个式子中，$X$不是二维坐标系中的横轴，而是样本的向量表示。例如上面举的二维平面中的例子，假设绿色框内是的坐标是$(3,1)$，则 $X^{T}=(x_{1},x_{2})=(3,1)$ 。一般说向量都默认是列向量，因此以行向量形式来表示时，就加上转置。因此， $W^{T}X+b=0$中$W^{T}$是一组行向量，是未知参数，$X$是一组列向量，是已知的样本数据，可以将 $w_{i}$理解为$x_{i}$的系数，行向量与列向量相乘得到一个$1\times 1$的矩阵，也就是一个实数。&lt;/p&gt;

&lt;h3 id=&quot;3-怎么找线性分类器&quot;&gt;3. 怎么找线性分类器&lt;/h3&gt;

&lt;p&gt;我们还是先看只有两个自变量的情况下，怎么求解最佳的线性分割。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.jsdelivr.net/gh/mowchann/blog-static/image/column/post/2021/20210519-122400.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;如图，理想状态下，平面中的两类点是完全线性可分的。这时问题来了，这样能把两类点分割的线有很多啊，哪条是最好的呢？&lt;/p&gt;

&lt;p&gt;支持向量机中，对最好分类器的定义是：&lt;strong&gt;最大边界超平面，即距两个类别的边界观测点最远的超平面&lt;/strong&gt;。在二维情况下，就是找最宽的马路，在三维问题中，就是找最厚的木板。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.jsdelivr.net/gh/mowchann/blog-static/image/column/post/2021/20210519-122418.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;显然，上图中左边的马路比右边的宽，马路的边界由1、2、3这三个点确定，而马路中间那条虚线，就是我们要的 $W^{T}X+b=0$ 。&lt;/p&gt;

&lt;p&gt;可以看到，我们找马路时，只会考虑$+1$类中，离$-1$类近的点，还有$-1$类中，离$+1$类距离近的点，即图中的1、2、3和$a$、$b$、$c$这些点。其他距离对方远的样本点，我们做支持向量机这个模型时，是不考虑的。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;由于最大边界超平面仅取决于两类别的边界点，这些点被称为支持向量，因此这种算法被命名为支持向量机&lt;/strong&gt;。这个定义就比较好理解了吧？&lt;/p&gt;

&lt;h3 id=&quot;4-求解超平面&quot;&gt;4. 求解超平面&lt;/h3&gt;

&lt;p&gt;上篇仅介绍了SVM的基本概念，本篇着重讲解SVM中的最佳线性分类器（最大边界超平面）是如何求得的。&lt;/p&gt;

&lt;h4 id=&quot;41-几何间隔&quot;&gt;4.1 几何间隔&lt;/h4&gt;

&lt;p&gt;上一小节给出&lt;strong&gt;二维问题下最佳线性分割的标准&lt;/strong&gt;，&lt;strong&gt;就是分割线到两类边界点的距离最“宽”&lt;/strong&gt;，那么这个“宽度”怎么量化和求解呢？&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.jsdelivr.net/gh/mowchann/blog-static/image/column/post/2021/20210519-122433.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;我们知道，点 $(x_{0} ,y_{0})$ 直线$Ax+By+c=0$的距离（中学的知识点），可以表示为：&lt;/p&gt;

\[D=\dfrac{|Ax_{0}+By_{0}+c|} {\sqrt{A^{2}+B^{2}}}\]

&lt;p&gt;在我们的二维问题中，第$i$个点的坐标为 $X_{i}=(x_{i1},x_{i2})^{T}$ ，直线为 $w_{1}x_{1}+w_{2}x_{2}+b=W^{T}X+b=0$ （为了打公式方便，后面不区分向量和其转置，省略$T$标志，统一写成 $WX+b=0$ ），将上式替换， $X_{i}$ 到分割直线的距离为：&lt;/p&gt;

\[D=\dfrac{|WX_{i}+b|} {\sqrt{w_{1}^{2}+w_{2}^{2}}}=\dfrac{|WX_{i}+b|}{\Vert W \Vert}\]

&lt;p&gt;有的人也许对分母$\Vert W\Vert $感到陌生，这里多做点解释。&lt;/p&gt;

&lt;p&gt;$\Vert W \Vert $是向量$W$的“2-范数”（ $L_{2}$ 范数），一般我们说&lt;strong&gt;向量长度&lt;/strong&gt;，&lt;strong&gt;指的是向量的2-范数&lt;/strong&gt;。例如这里的 $W=(w_{1},w_{2})$ ，它的2-范数就是 $\Vert W\Vert _{2}=\sqrt{w_1^2+w_2^2} $（通常会省略下标2，一般说$ \Vert W\Vert $就是指 $ \Vert W \Vert_2 $ ，而它的$p$-范数（ $L_p$ 范数）就是 $\Vert W_p \Vert =\sqrt[p]{w_1^p+w_2^p}$ 。&lt;/p&gt;

&lt;p&gt;这里给出向量范数的一般形式。对于$n$维向量 $W=(w_{1},w_{2},\cdots ,w_{n})$ ，它的&lt;strong&gt;$p$-范数&lt;/strong&gt;为：
\(\Vert W\Vert _{p}=\sqrt[p]{w_{1}^{p}+w_{2}^{p}+...+w_{n}^{p}}\)&lt;/p&gt;

&lt;p&gt;$D=\dfrac{\vert WX_i+b\vert}{\Vert W \Vert}$这个公式的学名叫做&lt;strong&gt;几何间隔&lt;/strong&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;回到二维问题，令“马路宽度”为$2d$，即最佳分割线到两类支持向量的距离均为$d$，最佳分割线参数的求解目标就是使$d$最大。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.jsdelivr.net/gh/mowchann/blog-static/image/column/post/2021/20210519-122452.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;42-凸二次规划&quot;&gt;4.2 凸二次规划&lt;/h4&gt;

&lt;p&gt;假设$L_1$是其中一条过$+1$类支持向量且平行于$WX+b=0$的直线，$L_2$是过$-1$类支持向量且平行于$WX+b=0$的直线，这$L_1$和$L_2$就确定了这条马路的两边，$L$是马路中线。&lt;/p&gt;

&lt;p&gt;由于确定了$L$的形式是 $WX+b=0$，又因为$L_1$、$L_2$距离$L$是相等的，我们定义$L_1$为$WX+b=1$，$L_2$为$WX+b=-1$。为什么这两条平行线的方程右边是$1$和$-1$其实也可以是$2$和$-2$，或者任意非零常数$C$和$-C$，规定$1$和$-1$只是为了方便。就像$2x+3y+1=0$和$4x+6y+2=0$是等价的，方程同乘一个常数后并不会改变。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.jsdelivr.net/gh/mowchann/blog-static/image/column/post/2021/20210519-122507.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;确定了三条线的方程，我们就可以求马路的宽度$2d$。$2d$是$L_1$和$L_2$这两条平行线之间的距离：&lt;/p&gt;

\[2d=\dfrac{\vert 1-(-1)\vert}{\Vert W\Vert }=\dfrac{2}{\Vert W\Vert }\]

&lt;p&gt;在4.1小节我们讲了现在的目标是&lt;strong&gt;最大化几何间隔$d$&lt;/strong&gt;，由于 $d=\dfrac{1}{\Vert W\Vert}$ ，问题又转化成了最小化$\Vert W\Vert$。对于求$\min \Vert W\Vert$，通常会转化为求 $\min\dfrac{\Vert W\Vert^{2}}{2}$ ，为什么要用平方后除以2这个形式呢？这是为了后面求解方便（还记得上次讲线性回归讲到的凸函数求导吗？）。&lt;/p&gt;

&lt;p&gt;$\Vert W\Vert$不可能无限小，因为还有限制条件呢。&lt;strong&gt;超平面正确分类意味着点$i$到超平面的距离恒大于等于$d$&lt;/strong&gt;，即:&lt;/p&gt;

\[\frac{|WX_{i}+b|}{\Vert W\Vert}\geqslant d=\frac{1}{\Vert W\Vert}\]

&lt;p&gt;两边同乘$\Vert W\Vert$，简化为：&lt;/p&gt;

\[|WX_{i}+b|=y_{i}(WX_{i}+b) \geqslant 1\]

&lt;p&gt;$\vert WX_{i}+b \vert=y_{i}(WX_{i}+b)$ 应该不难理解吧？因为$y$只有两个值，$+1$和$-1$。&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;如果第$i$个样本属于$+1$类别， $y_{i}&amp;gt;0$，同时 $WX_{i}+b&amp;gt;0$ ，两者相乘也大于0；&lt;/li&gt;
  &lt;li&gt;若属于$-1$类， $y_{i}&amp;lt;0$，$WX_{i}+b&amp;lt;0$，此时相乘依旧是大于0的。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这意味着 $y_{i}(WX_{i}+b)$ 恒大于0，$y$起到的作用就和绝对值一样。之所以要用$y$替换绝对值，是因为$y$是已知样本数据，方便后面的公式求解。&lt;/p&gt;

&lt;p&gt;我们将这个目标规划问题用数学语言描述出来。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;目标函数&lt;/strong&gt;：
\(\min \tau(W) = \min \dfrac{1}{2} \Vert W\Vert ^2 = \min \dfrac{1}{2}W^TW\)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;约束条件&lt;/strong&gt;：&lt;/p&gt;

\[y_i(b+W^TX_i)-1 \geqslant 0, i=1,2,\cdots,n\]

&lt;p&gt;这里约束条件是$W$的多个线性函数（$n$代表样本个数），目标函数是$W$的二次函数（再次提醒，$X$、$y$不是变量，是已知样本数据），这种规划问题叫做&lt;strong&gt;凸二次规划&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;什么叫凸二次规划？之前讲线性回归最小二乘法时，提到了处处连续可导且有最小值的凸函数。从二维图形上理解“凸”，就是在一个“凸”形中，任取其中两个点连一条直线，这条线上的点仍然在这个图形内部，例如 $f(x)=x^{2}$ 上方的区域。&lt;/p&gt;

&lt;p&gt;当一个约束优化问题中，目标函数和约束函数是凸函数（线性函数也是凸函数），该问题被称为&lt;strong&gt;凸优化问题&lt;/strong&gt;。 当凸优化问题中的目标函数是一个二次函数时，就叫做凸二次规划，一般形式为：
\(\begin{aligned}
\min_x &amp;amp; \frac{1}{2}x^TQx + c^Tx
\\
\text{ s.t. } &amp;amp; W_x \leqslant b
\end{aligned}\)&lt;/p&gt;

&lt;p&gt;若上式中的$Q$为正定矩阵，则目标函数有唯一的全局最小值。我们的问题中，$Q$是一个单位矩阵。&lt;/p&gt;

&lt;h4 id=&quot;43-拉格朗日乘数法&quot;&gt;4.3 拉格朗日乘数法&lt;/h4&gt;

&lt;p&gt;这种不等式条件约束下的求多元函数极值的问题，到底怎么求解呢？&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;以下会涉及高等数学知识，推导过程较为复杂，数学基础较弱或对推导没兴趣的同学可以跳过，直接看第5小节&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;当我们求一个函数 $f(x,y)$ 的极值时，如果不带约束，分别对$x$，$y$求偏导，令两个偏导等于$0$，解方程即可。这种是求&lt;strong&gt;无条件极值&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;带约束的话则为&lt;strong&gt;条件极值&lt;/strong&gt;，如果约束为等式，有时借助换元法可以将有条件转化为无条件极值从而求解，不过换元消元也只能解决三元以内的问题。而&lt;strong&gt;拉格朗日乘数法&lt;/strong&gt;可以通过引入新的未知标量（&lt;strong&gt;拉格朗日乘数&lt;/strong&gt; $\lambda$ ），直接求多元函数条件极值，不必先把问题转化为无条件极值的问题。&lt;/p&gt;

&lt;p&gt;求函数$f(x,y)$在附加条件 $\varphi(x,y)=0$下可能的极值点，可以先做拉格朗日函数：&lt;/p&gt;

&lt;p&gt;$L(x,y) = f(x,y) + \lambda \varphi (x,y)$，其中$\lambda$为参数，则各阶偏导为$0$：
\(\begin{cases}
f_x(x,y) + \lambda \varphi_x(x,y) = 0,\\
f_y(x,y) + \lambda \varphi_y(x,y) = 0,\\
\varphi(x,y) = 0
\end{cases}\)
则该方程组解出的$x, y, \lambda$就是函数$f(x,y)$在附件条件下的所有可能极值点。&lt;/p&gt;

&lt;p&gt;讲完拉格朗日乘数法的思路，仍解决不了上面的问题，因为该问题约束条件是不等式。其实，解决办法很简单，分成两部分看就行。&lt;/p&gt;

&lt;p&gt;为了看起来简洁，我们令目标函数 $\min\dfrac{\Vert W \Vert^{2}}{2}$为 $\min f(W)$，约束条件 $y_{i} (WX_{i}+b)-1\geqslant 0$为$g_{i}(W)\geqslant 0$ 。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;当可行解$W$落在 $g_{i}(W)&amp;gt;0$ 区域内时，此时的问题就是求无条件极值问题（因为极小值已经包含在整个大区域内），直接极小化 $f(W)$就行；&lt;/li&gt;
  &lt;li&gt;当可行解$W$落在 $g_{i}(W)=0$区域内时，此时的问题就是等式约束下的求极值问题，用拉格朗日乘数法求解即可。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这两部分对应到样本上，又是什么？&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;当可行解$W$落在 $g_{i}(W)&amp;gt;0$内时，此时$i$这个样本点是“马路”之外的点；&lt;/li&gt;
  &lt;li&gt;当可行解$W$落在 $g_{i}(W)=0$内时，此时$i$这个样本点正好落在马路边上，也就是我们的支持向量！&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;我们再进一步思考下：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;当可行解$W$落在 $g_{i}(W)&amp;gt;0$内时，此时约束不起作用（即求无条件极值），也就是拉格朗日乘数 $\lambda_{i}=0$；&lt;/li&gt;
  &lt;li&gt;当可行解$W$落在边界上时， $\lambda_{i}\neq 0 ，g_{i}(W)=0$。
不论是以上哪种情况， $\lambda_{i} g_{i}(W)=0$ 均成立。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;搞懂了上面说的，接下来构造拉格朗日函数，$n$个不等式约束都要加拉格朗日函数 $\lambda_{i} \geqslant 0$ ，有拉格朗日乘数向量 $\lambda =(\lambda_{1},\cdots\lambda_{n})^{T}$ ：&lt;/p&gt;

\[L(W,b,\lambda ) = f(W)-\sum_{1}^{n} \lambda_{i} g_{i}(W)  =\frac{||W||^{2}}{2} - \sum_{1}^{n}  \lambda_{i}y_{i}(WX_{i}+b)  +\sum_{1}^{n}  \lambda_{i} \tag{1}\]

&lt;p&gt;要求极值，先对参数求偏导：&lt;/p&gt;

\[\frac{\partial L}{\partial W}=W-\sum_{1}^{n}  \lambda_{i}y_{i}X_{i}=0 \tag{2}\]

\[\frac{\partial L}{\partial b}=\sum_{1}^{n}  \lambda_{i}y_{i}=0 \tag{3}\]

&lt;p&gt;此时又要引入一个概念——对偶问题。关于对偶问题可以参见&lt;a href=&quot;clearly-lagrange-duality-introduction.html&quot;&gt;这篇文章&lt;/a&gt;，这里再不赘述。简而言之就是原先的问题是先求$L$对$\lambda$的最大值再求对$W$、$b$的最小值，变成先求$L$对$W$、$b$的最小值再求$\lambda$的最大值。&lt;/p&gt;

&lt;p&gt;将(2)式 $W=\sum_{1}^{n}  \lambda_{i}y_{i}X_{i}$ 代入(1)式，得：&lt;/p&gt;

\[\begin{aligned}
L &amp;amp;= \frac{1}{2}(\sum_{1}^{n}  \lambda_{i}y_{i}X_{i})(\sum_{1}^{n}  \lambda_{i}y_{i}X_{i}) -  \sum_{1}^{n}  \lambda_{i}y_{i} ((\sum_{1}^{n}  \lambda_{i}y_{i}X_{i})X_{i}+b)+\sum_{1}^{n}  \lambda_{i} \\

&amp;amp;= \sum_{1}^{n}  \lambda_{i} - \frac{1}{2}(\sum_{i=1}^{n} \sum_{j=1}^{n}  \lambda_{i} \lambda_{j}y_{i}y_{j}X_{i}^{T}X_{j}) 
\end{aligned}
\tag{4}\]

&lt;p&gt;此时目标函数中$W$、$b$就都被消去了，约束最优化问题就转变成： &lt;strong&gt;目标函数：&lt;/strong&gt;&lt;/p&gt;

\[\min L(\lambda ) = \min \left(\frac{1}{2}\sum_{i=1}^{n} \sum_{j=1}^{n}  \lambda_{i} \lambda_{j}y_{i}y_{j}X_{i}^{T}X_{j}-\sum_{1}^{n}  \lambda_{i} \right) \tag{5}\]

&lt;p&gt;&lt;strong&gt;约束条件：&lt;/strong&gt; 
\(\sum_{1}^{n}  \lambda_{i}y_{i}=0 , \lambda_{i} \geqslant 0 \tag{6}\)&lt;/p&gt;

\[\lambda_{i}\left( y_{i}(WX_{i}+b)-1\right) = 0, i=1,2\cdots n \tag{7}\]

&lt;p&gt;(6)式来自上面的(3)式，(7)式是由 $\lambda_{i} g_{i}(W)=0$ 而来。如果能解出上面这个问题的最优解，我们就可以根据这个 $\lambda$ 求解出我们需要的$W$和$b$。&lt;/p&gt;

&lt;h3 id=&quot;5-线性可分问题小结&quot;&gt;5. 线性可分问题小结&lt;/h3&gt;

&lt;p&gt;最大边界超平面是由支持向量决定的，支持向量是边界上的样本点：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;假设有$m$个支持向量，则 $W=\sum_{1}^{m}  \lambda_{i}y_{i}X_{i}$；&lt;/li&gt;
  &lt;li&gt;从$m$个支持向量中任选一个，可以求 $b=y_{i}-WX_{i}$；&lt;/li&gt;
  &lt;li&gt;决策函数 $h(x)=\text{sgn}(W^{T}X+b)=\text{sgn}\left[\sum_{1}^{m} (\lambda_{i}y_{i}X_{i}^{T})X+b\right]$；&lt;/li&gt;
  &lt;li&gt;对新样本 $X_\ast$的预测： $\text{sgn}(W^{T}X_\ast+b)，W^{T}X_\ast+b$为正则 $y_\ast=1$，为负则 $y_\ast=-1$，为$0$则拒绝判断。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;至此我们讲完了线性分类支持向量机的逻辑思想和求解过程，但这些只是SVM的基础知识，真正的核心其实还没有讲到。要知道，SVM的优势在于解决&lt;strong&gt;小样本&lt;/strong&gt;、&lt;strong&gt;非线性&lt;/strong&gt;和&lt;strong&gt;高维&lt;/strong&gt;的回归和二分类问题（Support vector machine, SVM, 1992,  Boser, Guyon and Vapnik)。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;小样本，是指与问题的复杂度相比，SVM要求的样本数相对较少；&lt;/li&gt;
  &lt;li&gt;非线性，是指SVM擅长应付样本数据线性不可分的情况，主要通过&lt;strong&gt;核函数和松弛变量&lt;/strong&gt;来实现，这才是SVM的精髓，而本文是入门笔记，暂不涉及；&lt;/li&gt;
  &lt;li&gt;高维，是指样本维数很高，因为SVM 产生的分类器很简洁，用到的样本信息很少，仅仅用到支持向量。由于分类器仅由支持向量决定，SVM还能够&lt;strong&gt;有效避免过拟合&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;参考链接&quot;&gt;参考链接&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://blog.csdn.net/DP323/article/details/80535863&quot;&gt;SVM 原理详解，通俗易懂_DP323的博客-CSDN博客_svm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://link.zhihu.com/?target=http%3A//www.sohu.com/a/206572358_160850&quot;&gt;从超平面到SVM（一）&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://link.zhihu.com/?target=https%3A//www.sohu.com/a/211607605_160850&quot;&gt;从超平面到SVM（二）&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://link.zhihu.com/?target=https%3A//blog.csdn.net/baishuiniyaonulia/article/details/80141115&quot;&gt;多元函数的极值及其求法&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://link.zhihu.com/?target=https%3A//www.cnblogs.com/xxrxxr/p/7536131.html&quot;&gt;关于SVM数学细节逻辑的个人理解（二）&lt;/a&gt;&lt;/p&gt;

</description>
				<pubDate>Wed, 19 May 2021 07:00:00 +0800</pubDate>
				<link>https://www.mowchan.me/post/2021/clearly-svm-introduction.html</link>
				<guid isPermaLink="true">https://www.mowchan.me/post/2021/clearly-svm-introduction.html</guid>
				
				<category>SVM</category>
				
				<category>支持向量机</category>
				
				<category>机器学习</category>
				
				
				<category>ML</category>
				
			</item>
		
			<item>
				<title>PAT A1056：Mice and Rice</title>
				<description>&lt;h3 id=&quot;题目内容&quot;&gt;题目内容&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Mice and Rice&lt;/strong&gt; is the name of a programming contest in which each programmer must write a piece of code to control the movements of a mouse in a given map. The goal of each mouse is to eat as much rice as possible in order to become a FatMouse.&lt;/p&gt;

&lt;p&gt;First the playing order is randomly decided for $N_P$ programmers. Then every $N_G$ programmers are grouped in a match. The fattest mouse in a group wins and enters the next turn. All the losers in this turn are ranked the same. Every $N_G$ winners are then grouped in the next match until a final winner is determined.&lt;/p&gt;

&lt;p&gt;For the sake of simplicity, assume that the weight of each mouse is fixed once the programmer submits his/her code. Given the weights of all the mice and the initial playing order, you are supposed to output the ranks for the programmers.&lt;/p&gt;

&lt;h4 id=&quot;input-specification&quot;&gt;Input Specification:&lt;/h4&gt;

&lt;p&gt;Each input file contains one test case. For each case, the first line contains 2 positive integers: $N_P$ and $N_G$ $(\leqslant 1000)$, the number of programmers and the maximum number of mice in a group, respectively. If there are less than $N_G$ mice at the end of the player’s list, then all the mice left will be put into the last group. The second line contains $N_P$ distinct non-negative numbers $W_i$ $(i=0,\cdots, N_{P−1})$ where each $W_i$ is the weight of the $i$-th mouse respectively. The third line gives the initial playing order which is a permutation of $0,\cdots,N_{P−1}$ (assume that the programmers are numbered from 0 to $N_{P−1}$). All the numbers in a line are separated by a space.&lt;/p&gt;

&lt;h4 id=&quot;output-specification&quot;&gt;Output Specification:&lt;/h4&gt;

&lt;p&gt;For each test case, print the final ranks in a line. The $i$-th number is the rank of the $i$-th programmer, and all the numbers must be separated by a space, with no extra space at the end of the line.&lt;/p&gt;

&lt;h4 id=&quot;sample-input&quot;&gt;Sample Input:&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-in&quot;&gt;11 3
25 18 0 46 37 3 19 22 57 56 10
6 0 8 7 10 5 9 1 4 2 3
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;sample-output&quot;&gt;Sample Output:&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-out&quot;&gt;5 5 5 2 5 5 5 3 1 3 5
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;参考代码&quot;&gt;参考代码&lt;/h3&gt;

&lt;p&gt;有图解，方便理解：https://blog.csdn.net/CV_Jason/article/details/85238006&lt;/p&gt;

&lt;p&gt;二重循环处理问题：https://blog.csdn.net/a553650885/article/details/86745604&lt;/p&gt;

&lt;p&gt;上面代码的清晰版本：https://blog.csdn.net/weixin_35093872/article/details/87857252&lt;/p&gt;

&lt;p&gt;思路比较详细：https://blog.csdn.net/qq_24452475/article/details/100612383&lt;/p&gt;

&lt;p&gt;柳婼的单循环计数推入版本：https://liuchuo.blog.csdn.net/article/details/54427590&lt;/p&gt;

</description>
				<pubDate>Mon, 15 Feb 2021 02:00:00 +0800</pubDate>
				<link>https://www.mowchan.me/post/2021/pat-a1056.html</link>
				<guid isPermaLink="true">https://www.mowchan.me/post/2021/pat-a1056.html</guid>
				
				<category>PAT</category>
				
				<category>Python</category>
				
				<category>C++</category>
				
				
				<category>PAT</category>
				
			</item>
		
			<item>
				<title>PAT（甲级）2020年秋季考试题目</title>
				<description>&lt;h3 id=&quot;7-1-prime-day-20-分&quot;&gt;7-1 Prime Day (20 分)&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://images.ptausercontent.com/e8219d7d-c640-4b82-a98d-4553a1817364.JPG&quot; alt=&quot;wbfg.JPG&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The above picture is from Sina Weibo, showing May 23rd, 2019 as a very cool “Prime Day”. That is, not only that the corresponding number of the date &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;20190523&lt;/code&gt; is a prime, but all its sub-strings ended at the last digit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3&lt;/code&gt; are prime numbers.&lt;/p&gt;

&lt;p&gt;Now your job is to tell if a given date is a Prime Day.&lt;/p&gt;

&lt;h4 id=&quot;input-specification&quot;&gt;Input Specification:&lt;/h4&gt;

&lt;p&gt;Each input file contains one test case. For each case, a date between January 1st, 0001 and December 31st, 9999 is given, in the format &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;yyyymmdd&lt;/code&gt;.&lt;/p&gt;

&lt;h4 id=&quot;output-specification&quot;&gt;Output Specification:&lt;/h4&gt;

&lt;p&gt;For each given date, output in the decreasing order of the length of the substrings, each occupies a line. In each line, print the string first, followed by a space, then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Yes&lt;/code&gt; if it is a prime number, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;No&lt;/code&gt; if not. If this date is a Prime Day, print in the last line &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;All Prime!&lt;/code&gt;.&lt;/p&gt;

&lt;h4 id=&quot;sample-input-1&quot;&gt;Sample Input 1:&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-in&quot;&gt;20190523
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;sample-output-1&quot;&gt;Sample Output 1:&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-out&quot;&gt;20190523 Yes
0190523 Yes
190523 Yes
90523 Yes
0523 Yes
523 Yes
23 Yes
3 Yes
All Prime!
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;sample-input-2&quot;&gt;Sample Input 2:&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-in&quot;&gt;20191231
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;sample-output-2&quot;&gt;Sample Output 2:&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-out&quot;&gt;20191231 Yes
0191231 Yes
191231 Yes
91231 No
1231 Yes
231 No
31 Yes
1 No
&lt;/code&gt;&lt;/pre&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;7-2-the-judger-25-分&quot;&gt;7-2 The Judger (25 分)&lt;/h3&gt;

&lt;p&gt;A game of numbers has the following rules: at the beginning, two distinct positive integers are given by the judge. Then each player in turn must give a number to the judge. The number must be the difference of two numbers that are previously given, and must not be duplicated to any of the existed numbers. The game will run for several rounds. The one who gives a duplicate number or even a wrong number will be kicked out.&lt;/p&gt;

&lt;p&gt;Your job is to write a judger program to judge the players’ numbers and to determine the final winners.&lt;/p&gt;

&lt;h4 id=&quot;input-specification-1&quot;&gt;Input Specification:&lt;/h4&gt;

&lt;p&gt;Each input file contains one test case. For each case, the first line gives two distinct positive integers to begin with. Both numbers are in $[1,10^5]$.&lt;/p&gt;

&lt;p&gt;In the second line, two numbers are given: $N (2\leqslant N\leqslant 10)$, the number of players, and $M (2\leqslant M\leqslant 10^3)$, the number of rounds.&lt;/p&gt;

&lt;p&gt;Then $N$ lines follow, each contains $M$ positive integers. The $i$-th line corresponds to the $i$-th player $(i=1,\cdots,N)$. The game is to start from the 1st player giving his/her 1st number, followed by everybody else giving their 1st numbers in the 1st round; then everyone give their 2nd numbers in the 2nd round, and so on so forth.&lt;/p&gt;

&lt;h4 id=&quot;output-specification-1&quot;&gt;Output Specification:&lt;/h4&gt;

&lt;p&gt;If the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i&lt;/code&gt;-th player is kicked out in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;k&lt;/code&gt;-th round, print in a line &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Round #k: i is out.&lt;/code&gt;. The rest of the numbers given by the one who is out of the game will be ignored. If more than one player is out in the same round, print them in increasing order of their indices. When the game is over, print in the last line &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Winner(s): W1 W2 ... Wn&lt;/code&gt;, where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;W1 ... Wn&lt;/code&gt; are the indices of the winners in increasing order. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the beginning or the end of the line. If there is no winner, print &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;No winner.&lt;/code&gt; instead.&lt;/p&gt;

&lt;h4 id=&quot;sample-input-1-1&quot;&gt;Sample Input 1:&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-in&quot;&gt;101 42
4 5
59 34 67 9 7
17 9 8 50 7
25 92 43 26 37
76 51 1 41 40
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;sample-output-1-1&quot;&gt;Sample Output 1:&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-out&quot;&gt;Round #4: 1 is out.
Round #5: 3 is out.
Winner(s): 2 4
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;sample-input-2-1&quot;&gt;Sample Input 2:&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-in&quot;&gt;42 101
4 5
59 34 67 9 7
17 9 18 50 49
25 92 58 1 39
102 32 2 6 41
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;sample-output-2-1&quot;&gt;Sample Output 2:&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-out&quot;&gt;Round #1: 4 is out.
Round #3: 2 is out.
Round #4: 1 is out.
Round #5: 3 is out.
No winner.
&lt;/code&gt;&lt;/pre&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;7-3-safari-park-25-分&quot;&gt;7-3 Safari Park (25 分)&lt;/h3&gt;

&lt;p&gt;A safari park（野生动物园）has $K$ species of animals, and is divided into $N$ regions. The managers hope to spread the animals to all the regions, but not the same animals in the two neighboring regions. Of course, they also realize that this is an NP complete problem, you are not expected to solve it. Instead, they have designed several distribution plans. Your job is to write a program to help them tell if a plan is feasible.&lt;/p&gt;

&lt;h4 id=&quot;input-specification-2&quot;&gt;Input Specification:&lt;/h4&gt;

&lt;p&gt;Each input file contains one test case. For each case, the first line gives 3 integers: $N (0&amp;lt;N\leqslant 500)$, the number of regions; $R (\geqslant 0)$, the number of neighboring relations, and $K (0&amp;lt;K\leqslant N)$, the number of species of animals. The regions and the species are both indexed from 1 to $N$.&lt;/p&gt;

&lt;p&gt;Then $R$ lines follow, each gives the indices of a pair of neighboring regions, separated by a space.&lt;/p&gt;

&lt;p&gt;Finally there is a positive $M (\leqslant 20)$ followed by $M$ lines of distribution plans. Each plan gives $N$ indices of species in a line (the $i$-th index is the animal in the $i$-th rigion), separated by spaces. It is guaranteed that any pair of neighboring regions must be different, and there is no duplicated neighboring relations.&lt;/p&gt;

&lt;h4 id=&quot;output-specification-2&quot;&gt;Output Specification:&lt;/h4&gt;

&lt;p&gt;For each plan, print in a line &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Yes&lt;/code&gt; if no animals in the two neighboring regions are the same, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;No&lt;/code&gt; otherwise. However, if the number of species given in a plan is not $K$, you must print &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Error: Too many species.&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Error: Too few species.&lt;/code&gt; according to the case.&lt;/p&gt;

&lt;h4 id=&quot;sample-input&quot;&gt;Sample Input:&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-in&quot;&gt;6 8 3
2 1
1 3
4 6
2 5
2 4
5 4
5 6
3 6
5
1 2 3 3 1 2
1 2 3 4 5 6
4 5 6 6 4 5
2 3 4 2 3 4
2 2 2 2 2 2
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;sample-output&quot;&gt;Sample Output:&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-out&quot;&gt;Yes
Error: Too many species.
Yes
No
Error: Too few species.
&lt;/code&gt;&lt;/pre&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;7-4-replacement-selection-30-分&quot;&gt;7-4 Replacement Selection (30 分)&lt;/h3&gt;

&lt;p&gt;When the input is much too large to fit into memory, we have to do &lt;strong&gt;external sorting&lt;/strong&gt; instead of internal sorting. One of the key steps in external sorting is to generate sets of sorted records (also called &lt;strong&gt;runs&lt;/strong&gt;) with limited internal memory. The simplest method is to read as many records as possible into the memory, and sort them internally, then write the resulting run back to some tape. The size of each run is the same as the capacity of the internal memory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Replacement Selection&lt;/strong&gt; sorting algorithm was described in 1965 by Donald Knuth. Notice that as soon as the first record is written to an output tape, the memory it used becomes available for another record. Assume that we are sorting in ascending order, if the next record is not smaller than the record we have just output, then it can be included in the run.&lt;/p&gt;

&lt;p&gt;For example, suppose that we have a set of input { 81, 94, 11, 96, 12, 99, 35 }, and our memory can sort 3 records only. By the simplest method we will obtain three runs: { 11, 81, 94 }, { 12, 96, 99 } and { 35 }. According to the replacement selection algorithm, we would read and sort the first 3 records { 81, 94, 11 } and output 11 as the smallest one. Then one space is available so 96 is read in and will join the first run since it is larger than 11. Now we have { 81, 94, 96 }. After 81 is out, 12 comes in but it must belong to the next run since it is smaller than 81. Hence we have { 94, 96, 12 } where 12 will stay since it belongs to the next run. When 94 is out and 99 is in, since 99 is larger than 94, it must belong to the &lt;strong&gt;first run&lt;/strong&gt;. Eventually we will obtain two runs: the first one contains { 11, 81, 94, 96, 99 } and the second one contains { 12, 35 }.&lt;/p&gt;

&lt;p&gt;Your job is to implement this replacement selection algorithm.&lt;/p&gt;

&lt;h4 id=&quot;input-specification-3&quot;&gt;Input Specification:&lt;/h4&gt;

&lt;p&gt;Each input file contains several test cases. The first line gives two positive integers $N (\leqslant 10^5)$ and $M (&amp;lt;N/2)$, which are the total number of records to be sorted, and the capacity of the internal memory. Then &lt;em&gt;N&lt;/em&gt; numbers are given in the next line, all in the range of &lt;strong&gt;int&lt;/strong&gt;. All the numbers in a line are separated by a space.&lt;/p&gt;

&lt;h4 id=&quot;output-specification-3&quot;&gt;Output Specification:&lt;/h4&gt;

&lt;p&gt;For each test case, print in each line a run (in ascending order) generated by the replacement selection algorithm. All the numbers in a line must be separated by exactly 1 space, and there must be no extra space at the beginning or the end of the line.&lt;/p&gt;

&lt;h4 id=&quot;sample-input-1&quot;&gt;Sample Input:&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-in&quot;&gt;13 3
81 94 11 96 12 99 17 35 28 58 41 75 15
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;sample-output-1&quot;&gt;Sample Output:&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-out&quot;&gt;11 81 94 96 99
12 17 28 35 41 58 75
15
&lt;/code&gt;&lt;/pre&gt;
</description>
				<pubDate>Fri, 05 Feb 2021 21:30:00 +0800</pubDate>
				<link>https://www.mowchan.me/post/2021/pat-2020-autumn.html</link>
				<guid isPermaLink="true">https://www.mowchan.me/post/2021/pat-2020-autumn.html</guid>
				
				<category>PAT</category>
				
				<category>真题</category>
				
				
				<category>PAT</category>
				
			</item>
		
			<item>
				<title>PAT A1027：Colors in Mars（进制转换）</title>
				<description>&lt;h3 id=&quot;题目内容&quot;&gt;题目内容&lt;/h3&gt;

&lt;p&gt;People in Mars represent the colors in their computers in a similar way as the Earth people. That is, a color is represented by a 6-digit number, where the first 2 digits are for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Red&lt;/code&gt;, the middle 2 digits for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Green&lt;/code&gt;, and the last 2 digits for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Blue&lt;/code&gt;. The only difference is that they use radix 13 (0-9 and A-C) instead of 16. Now given a color in three decimal numbers (each between 0 and 168), you are supposed to output their Mars RGB values.&lt;/p&gt;

&lt;h4 id=&quot;input-specification&quot;&gt;Input Specification:&lt;/h4&gt;

&lt;p&gt;Each input file contains one test case which occupies a line containing the three decimal color values.&lt;/p&gt;

&lt;h4 id=&quot;output-specification&quot;&gt;Output Specification:&lt;/h4&gt;

&lt;p&gt;For each test case you should output the Mars RGB value in the following format: first output &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#&lt;/code&gt;, then followed by a 6-digit number where all the English characters must be upper-cased. If a single color is only 1-digit long, you must print a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt; to its left.&lt;/p&gt;

&lt;h4 id=&quot;sample-input&quot;&gt;Sample Input:&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-in&quot;&gt;15 43 71
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;sample-output&quot;&gt;Sample Output:&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-out&quot;&gt;#123456
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;题目要点&quot;&gt;题目要点&lt;/h3&gt;

&lt;p&gt;本题 20 分，考察了进制数的转换和输出结果添加前导零。前导零可以用 Python 强大的字符串格式输出实现。十进制向任意进制转换用的算法是“取余倒排法”，即将待求的数除以进制，取余，商部分继续除以进制，直到商为零，将所得余数倒序排列，得到目标进制的值。&lt;/p&gt;

&lt;h3 id=&quot;ac-源代码&quot;&gt;AC 源代码&lt;/h3&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;radix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'0123456789ABC'&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;radix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;radix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'#{:&amp;gt;02}{:&amp;gt;02}{:&amp;gt;02}'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;用递归的方法简单清晰地实现了十进制向任意进制转换。&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;char&lt;/code&gt;定义了不同进制的各位数字如何表示；递归发生语句中&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;radix()&lt;/code&gt;和&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;+ char[]&lt;/code&gt;的位置可以巧妙地完成余数的倒排。&lt;/p&gt;

&lt;p&gt;R、G、B 三种颜色分别调用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;radix()&lt;/code&gt;可以用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map()&lt;/code&gt;函数直接调用，省去重复的赋值、调用步骤，也能明显减少 Python 的用时。&lt;/p&gt;

&lt;p&gt;Python 的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;format()&lt;/code&gt;方法功能强大，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{:&amp;gt;02}&lt;/code&gt;表示&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\{:\{\{fill\}align\}\{sign\}\{width\}\}&lt;/code&gt;，也就是说&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;gt;&lt;/code&gt;表示右对齐，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;表示前导零，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt;表示宽度，如果输出的字符串或数字长度为2，那么不填充前导零&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;，如果长度不足2，那么根据右对齐从左填充。&lt;/p&gt;

&lt;p&gt;另外，前导零的实现还有另一种表示方法，将&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;放在表示右对齐的&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;gt;&lt;/code&gt;前面，表示用该字符填充。&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'#{:0&amp;gt;2}{:0&amp;gt;2}{:0&amp;gt;2}'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;参考来源&quot;&gt;参考来源&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://docs.python.org/zh-cn/3/library/string.html#formatspec&quot;&gt;https://docs.python.org/zh-cn/3/library/string.html#formatspec&lt;/a&gt;&lt;/p&gt;
</description>
				<pubDate>Tue, 26 Jan 2021 15:30:00 +0800</pubDate>
				<link>https://www.mowchan.me/post/2021/pat-a1027.html</link>
				<guid isPermaLink="true">https://www.mowchan.me/post/2021/pat-a1027.html</guid>
				
				<category>PAT</category>
				
				<category>Python</category>
				
				<category>C++</category>
				
				<category>进制</category>
				
				<category>前导零</category>
				
				
				<category>PAT</category>
				
			</item>
		
			<item>
				<title>PAT A1082：Read Number in Chinese</title>
				<description>&lt;h3 id=&quot;题目内容&quot;&gt;题目内容&lt;/h3&gt;

&lt;p&gt;Given an integer with no more than 9 digits, you are supposed to read it in the traditional Chinese way. Output &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Fu&lt;/code&gt; first if it is negative. For example, -123456789 is read as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Fu yi Yi er Qian san Bai si Shi wu Wan liu Qian qi Bai ba Shi jiu&lt;/code&gt;. Note: zero (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ling&lt;/code&gt;) must be handled correctly according to the Chinese tradition. For example, 100800 is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;yi Shi Wan ling ba Bai&lt;/code&gt;.&lt;/p&gt;

&lt;h4 id=&quot;input-specification&quot;&gt;Input Specification:&lt;/h4&gt;

&lt;p&gt;Each input file contains one test case, which gives an integer with no more than 9 digits.&lt;/p&gt;

&lt;h4 id=&quot;output-specification&quot;&gt;Output Specification:&lt;/h4&gt;

&lt;p&gt;For each test case, print in a line the Chinese way of reading the number. The characters are separated by a space and there must be no extra space at the end of the line.&lt;/p&gt;

&lt;h4 id=&quot;sample-input-1&quot;&gt;Sample Input 1:&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-in&quot;&gt;-123456789
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;sample-output-1&quot;&gt;Sample Output 1:&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-out&quot;&gt;Fu yi Yi er Qian san Bai si Shi wu Wan liu Qian qi Bai ba Shi jiu
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;sample-input-2&quot;&gt;Sample Input 2:&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-in&quot;&gt;100800
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;sample-output-2&quot;&gt;Sample Output 2:&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-out&quot;&gt;yi Shi Wan ling ba Bai
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;题目要点&quot;&gt;题目要点&lt;/h3&gt;

&lt;p&gt;本题 25 分，这道题是非常复杂，因为提供的样例很少，规则也需要自己根据生活经验去分析，最后还要考虑些边界条件。对问题模拟的好坏直接影响代码编写的复杂程度，因此需要静心分析，能发现规律的利用迭代、循环，没有规律的，枚举出各种条件、情况，梳理清晰。&lt;/p&gt;

&lt;p&gt;本文用Python实现，但是基本思路和其它语言差别不大。另外，这道题也可以用正则表达式处理，但是输入的值最多是9位，而且问题简化后完全可以枚举出几种情况，所以不建议用正则表达式。&lt;/p&gt;

&lt;p&gt;首先，每一位的数字对应一个汉字，0~9一共10个数字用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;digit[]&lt;/code&gt;表示；从低位数起，每个4位都是以“（个）、十、百、千”为后缀在数字之后，用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;place[]&lt;/code&gt;表示；每个4位在读完后还要加个后缀，如“万”、“亿”，用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;suffix[]&lt;/code&gt;表示。因此，我们可以将整个数字按4位切分成若干段，每一段译出数字、“十百千”，封装成一个函数。调用一次后根据这是第&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i&lt;/code&gt;个段对应加上“万”、“亿”的后缀。最终合并起来，如果是负数再在头部加&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Fu&lt;/code&gt;即可。&lt;/p&gt;

&lt;p&gt;其次，最为棘手的是“零”的处理，什么时候读“零”，什么时候只读一个，什么时候不读，这是这道题最难的地方。好在我们将数字按4位分割成段后问题简单多了，只用考虑最多4位的情况：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;如果4位全部是0，如&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0000&lt;/code&gt;，那么完全不译，函数返回空值。比如&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;12,0000&lt;/code&gt;读作&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;十二万&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1,0000,5000&lt;/code&gt;读作&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;一亿五千&lt;/code&gt;；&lt;/li&gt;
  &lt;li&gt;如果零出现在末尾，如&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1200&lt;/code&gt;读作&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;一千二百&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1000&lt;/code&gt;读作&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;一千&lt;/code&gt;，那么末尾零的数字、在的“十百千”位也不译；&lt;/li&gt;
  &lt;li&gt;如果零出现在中间或开头，要看是否有连续的零：
    &lt;ul&gt;
      &lt;li&gt;如果只有一个零，如&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2305&lt;/code&gt;读作&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;二千零五&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0234&lt;/code&gt;读作&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;零二三四&lt;/code&gt;（因为这是从数字中取出四位，所以允许开头有零），那么译出“零”，但是不译“十百千”位；&lt;/li&gt;
      &lt;li&gt;如果有两个及以上连续个零，如&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2003&lt;/code&gt;读作&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;二千零三&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0005&lt;/code&gt;读作&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;零五&lt;/code&gt;，那么连续的零只译出一个即可，同样的，不译“十百千”位。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这样就基本将问题考虑完全，那么如何实现上述对零的处理？我这里的&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;repl()&lt;/code&gt;函数是将完全不译的零替换为一个字符，如&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*&lt;/code&gt;。&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;repl()&lt;/code&gt;函数比较取巧，首先替换完末尾零，然后考虑连续零只留一个，先将&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;000&lt;/code&gt;替换成&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;**0&lt;/code&gt;，再将&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;00&lt;/code&gt;替换成&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*0&lt;/code&gt;，注意顺序不可以颠倒。最终返回字符串。&lt;/p&gt;

&lt;p&gt;当&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;solve()&lt;/code&gt;函数中，按位遍历字符串时读到该位是&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*&lt;/code&gt;就&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;continue&lt;/code&gt;跳过这一步循环，否则就按照正常的数字译出，如果数字是零，那么只译“零”不译“十百千”。遍历结束作为当前段，返回列表，&lt;/p&gt;

&lt;p&gt;需要注意的是，输入的值可能是有前导零，如&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;002&lt;/code&gt;，所以要先处理下输入的值。还要考虑边界情况，如，输入&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;（&lt;strong&gt;测试点3&lt;/strong&gt;），会被上述算法当作末尾零不译，所以要在程序入口先判断下值是否为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;，如果是直接输出&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ling&lt;/code&gt;，如果不是，再调用上述的算法。&lt;/p&gt;

&lt;p&gt;这里提供一些额外的测试样例，以供参考&lt;/p&gt;
&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// 输入&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;880808080&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// 输出&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Fu&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ba&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Yi&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ba&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Qian&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ling&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ba&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Shi&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Wan&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ba&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Qian&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ling&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ba&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Shi&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// 输入&lt;/span&gt;
&lt;span class=&quot;mi&quot;&gt;800000000&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// 输出&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ba&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Yi&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// 输入&lt;/span&gt;
&lt;span class=&quot;mi&quot;&gt;80000008&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// 输出&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ba&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Qian&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Wan&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ling&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ba&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// 输入&lt;/span&gt;
&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// 输出&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ling&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// 输入&lt;/span&gt;
&lt;span class=&quot;mo&quot;&gt;002&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// 输出&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;er&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// 输入&lt;/span&gt;
&lt;span class=&quot;mi&quot;&gt;1010010&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// 输出&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;yi&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bai&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ling&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;yi&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Wan&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ling&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;yi&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Shi&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// 输入&lt;/span&gt;
&lt;span class=&quot;mi&quot;&gt;1000010&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// 输出&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;yi&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bai&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Wan&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ling&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;yi&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Shi&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// 输入&lt;/span&gt;
&lt;span class=&quot;mi&quot;&gt;100000000&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// 输出&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;yi&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Yi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;ac-源代码&quot;&gt;AC 源代码&lt;/h3&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;math&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ceil&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;repl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rstrip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'0'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'*'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'000'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'**0'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'00'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'*0'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;solve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;part&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;part&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'0000'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;part&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;repl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;part&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;words&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dig&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;part&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[::&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dig&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'*'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;dig&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;digit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;' '&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;place&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;digit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;words&lt;/span&gt;


&lt;span class=&quot;n&quot;&gt;digit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'ling'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'yi'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'er'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'san'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'si'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'wu'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'liu'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'qi'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'ba'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'jiu'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;place&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;''&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Shi'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Bai'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Qian'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;suffix&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;''&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Wan'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Yi'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'-'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;negative&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lstrip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'-'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;negative&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'0'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ceil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;part&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][::&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;part&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;solve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;part&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;part&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;suffix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;part&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;negative&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Fu'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;' '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[::&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;digit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;更多思考&quot;&gt;更多思考&lt;/h3&gt;

&lt;p&gt;使用正则表达式处理这道题的“零”问题更容易，而且还可以得到连续零的起讫下标，将字符串转换为列表就可以依据得到的下标直接替换。&lt;/p&gt;

&lt;h4 id=&quot;查找替换末尾零&quot;&gt;查找替换末尾零&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-regex&quot;&gt;[0]{1,}$
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;re&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;part&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'1034000'&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;part&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;re&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'[0]{1,}$'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'*'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;part&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'1034***'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;查找替换连续零&quot;&gt;查找替换连续零&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-regex&quot;&gt;(0){2,}
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;re&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;part&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'1034007009'&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;re&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;finditer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'(0){2,}'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;part&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;span&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;参考来源&quot;&gt;参考来源&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://www.liuchuo.net/archives/2204&quot;&gt;https://www.liuchuo.net/archives/2204&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/346321610&quot;&gt;https://zhuanlan.zhihu.com/p/346321610&lt;/a&gt;&lt;/p&gt;
</description>
				<pubDate>Mon, 25 Jan 2021 17:00:00 +0800</pubDate>
				<link>https://www.mowchan.me/post/2021/pat-a1082.html</link>
				<guid isPermaLink="true">https://www.mowchan.me/post/2021/pat-a1082.html</guid>
				
				<category>PAT</category>
				
				<category>Python</category>
				
				<category>C++</category>
				
				<category>枚举</category>
				
				<category>模拟</category>
				
				
				<category>PAT</category>
				
			</item>
		
			<item>
				<title>PAT A1009：Product of Polynomials</title>
				<description>&lt;h3 id=&quot;题目内容&quot;&gt;题目内容&lt;/h3&gt;

&lt;p&gt;This time, you are supposed to find $A\times B$ where $A$ and $B$ are two polynomials.&lt;/p&gt;

&lt;h4 id=&quot;input-specification&quot;&gt;Input Specification:&lt;/h4&gt;

&lt;p&gt;Each input file contains one test case. Each case occupies 2 lines, and each line contains the information of a polynomial:&lt;/p&gt;

&lt;p&gt;$K$ $N_1 a_{N_1} N_2 a_{N_2} \cdots N_K a_{N_K}$&lt;/p&gt;

&lt;p&gt;where $K$ is the number of nonzero terms in the polynomial, $N_i$ and $a_{N_i} (i=1,2,\cdots,K)$ are the exponents and coefficients, respectively. It is given that $1\leqslant K\leqslant 10$，$0\leqslant N_K &amp;lt; \cdots &amp;lt; N_2 &amp;lt; N_1 \leqslant 1000$.&lt;/p&gt;

&lt;h4 id=&quot;output-specification&quot;&gt;Output Specification:&lt;/h4&gt;

&lt;p&gt;For each test case you should output the product of $A$ and $B$ in one line, with the same format as the input. Notice that there must be &lt;strong&gt;NO&lt;/strong&gt; extra space at the end of each line. Please be accurate up to 1 decimal place.&lt;/p&gt;

&lt;h4 id=&quot;sample-input&quot;&gt;Sample Input:&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-in&quot;&gt;2 1 2.4 0 3.2
2 2 1.5 1 0.5
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;sample-output&quot;&gt;Sample Output:&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-out&quot;&gt;3 3 3.6 2 6.0 1 1.6
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;题目要点&quot;&gt;题目要点&lt;/h3&gt;

&lt;p&gt;本题 25 分，是比较简单的模拟题。在输入时，Python可以不用考虑给定的$K$，直接用数组切片隔位取指数列表、系数列表，再用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;zip()&lt;/code&gt;构造字典。&lt;/p&gt;

&lt;p&gt;重点需要考虑的是如何将多项式的指数和对应系数映射。C/C++可以用数组下标作为指数，数组浮点数值为对应系数。这里Python使用字典比较方便，而且考虑到两个多项式的指数项不一定相同，在求和时要指数项系数对应相加，Python可以使用集合的求并集&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;|&lt;/code&gt;运算符实现。&lt;/p&gt;

&lt;p&gt;注意，测试点6是非零系数项个数，也就是$K$为0的情况，这时候只输出&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;。如果有多余空格会出现“格式错误”。&lt;/p&gt;

&lt;h3 id=&quot;ac-源代码&quot;&gt;AC 源代码&lt;/h3&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;itertools&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;product&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;ins1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ins2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ins1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]),&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ins1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ins2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]),&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ins2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;poly&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;prod&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;coef&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prod&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;poly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;poly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;coef&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;poly&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sorted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;poly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reverse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;' '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'{:d} {:.1f}'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;poly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;poly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;参考来源&quot;&gt;参考来源&lt;/h3&gt;

&lt;p&gt;A1002多项式加法的解析：&lt;a href=&quot;https://column.mowchan.me/post/2021/pat-a1002.html&quot;&gt;https://column.mowchan.me/post/2021/pat-a1002.html&lt;/a&gt;&lt;/p&gt;
</description>
				<pubDate>Sun, 24 Jan 2021 09:50:00 +0800</pubDate>
				<link>https://www.mowchan.me/post/2021/pat-a1009.html</link>
				<guid isPermaLink="true">https://www.mowchan.me/post/2021/pat-a1009.html</guid>
				
				<category>PAT</category>
				
				<category>Python</category>
				
				<category>多项式</category>
				
				<category>迭代器</category>
				
				<category>组合</category>
				
				
				<category>PAT</category>
				
			</item>
		
	</channel>
</rss>
