├── .gitignore ├── LICENSE ├── README.md ├── docs ├── index.md ├── introduction │ ├── about.md │ ├── contributing.md │ ├── faq.md │ └── write_passage.md ├── javascripts │ ├── mathjax.js │ └── site.js ├── knowledge │ ├── ds │ │ └── lct │ │ │ ├── images │ │ │ ├── lct-access-1.svg │ │ │ ├── lct-access-2.svg │ │ │ ├── lct-access-3.svg │ │ │ ├── lct-access-4.svg │ │ │ ├── lct-access-5.svg │ │ │ ├── lct-access-6.svg │ │ │ └── lct-access-7.svg │ │ │ └── index.md │ └── index.md ├── problem │ ├── 1 │ │ ├── 1 │ │ │ └── index.md │ │ ├── 2 │ │ │ └── index.md │ │ ├── 3 │ │ │ └── index.md │ │ ├── 4 │ │ │ └── index.md │ │ ├── 5 │ │ │ └── index.md │ │ └── index.md │ ├── 2 │ │ ├── 1 │ │ │ └── index.md │ │ ├── 2 │ │ │ └── index.md │ │ ├── 3 │ │ │ └── index.md │ │ ├── 4 │ │ │ └── index.md │ │ ├── 5 │ │ │ └── index.md │ │ └── index.md │ ├── 3 │ │ ├── 1 │ │ │ └── index.md │ │ ├── 2 │ │ │ └── index.md │ │ ├── 3 │ │ │ └── index.md │ │ ├── 4 │ │ │ └── index.md │ │ ├── 5 │ │ │ └── index.md │ │ └── index.md │ ├── 4 │ │ ├── 1 │ │ │ └── index.md │ │ ├── 2 │ │ │ └── index.md │ │ ├── 3 │ │ │ └── index.md │ │ ├── 4 │ │ │ └── index.md │ │ ├── 5 │ │ │ └── index.md │ │ └── index.md │ ├── 5 │ │ ├── 1 │ │ │ └── index.md │ │ ├── 2 │ │ │ └── index.md │ │ ├── 3 │ │ │ └── index.md │ │ ├── 4 │ │ │ └── index.md │ │ ├── 5 │ │ │ └── index.md │ │ └── index.md │ ├── 6 │ │ ├── 1 │ │ │ └── index.md │ │ ├── 2 │ │ │ └── index.md │ │ ├── 3 │ │ │ └── index.md │ │ ├── 4 │ │ │ └── index.md │ │ ├── 5 │ │ │ └── index.md │ │ └── index.md │ ├── 7 │ │ ├── 1 │ │ │ └── index.md │ │ ├── 2 │ │ │ └── index.md │ │ ├── 3 │ │ │ └── index.md │ │ ├── 4 │ │ │ └── index.md │ │ ├── 5 │ │ │ └── index.md │ │ └── index.md │ ├── 8 │ │ ├── 1 │ │ │ └── index.md │ │ ├── 2 │ │ │ └── index.md │ │ ├── 3 │ │ │ └── index.md │ │ ├── 4 │ │ │ └── index.md │ │ ├── 5 │ │ │ └── index.md │ │ └── index.md │ ├── 9 │ │ ├── 1 │ │ │ └── index.md │ │ ├── 2 │ │ │ └── index.md │ │ ├── 3 │ │ │ └── index.md │ │ ├── 4 │ │ │ └── index.md │ │ ├── 5 │ │ │ └── index.md │ │ └── index.md │ ├── 10 │ │ ├── 1 │ │ │ └── index.md │ │ ├── 2 │ │ │ └── index.md │ │ ├── 3 │ │ │ └── index.md │ │ ├── 4 │ │ │ └── index.md │ │ ├── 5 │ │ │ └── index.md │ │ └── index.md │ ├── 11 │ │ ├── 1 │ │ │ └── index.md │ │ ├── 2 │ │ │ └── index.md │ │ ├── 3 │ │ │ └── index.md │ │ ├── 4 │ │ │ └── index.md │ │ ├── 5 │ │ │ └── index.md │ │ └── index.md │ ├── 12 │ │ ├── 1 │ │ │ └── index.md │ │ ├── 2 │ │ │ └── index.md │ │ ├── 3 │ │ │ └── index.md │ │ ├── 4 │ │ │ └── index.md │ │ ├── 5 │ │ │ └── index.md │ │ └── index.md │ ├── 13 │ │ ├── 1 │ │ │ └── index.md │ │ ├── 2 │ │ │ └── index.md │ │ ├── 3 │ │ │ └── index.md │ │ ├── 4 │ │ │ └── index.md │ │ ├── 5 │ │ │ └── index.md │ │ └── index.md │ ├── 14 │ │ ├── 1 │ │ │ └── index.md │ │ ├── 2 │ │ │ └── index.md │ │ ├── 3 │ │ │ └── index.md │ │ ├── 4 │ │ │ └── index.md │ │ ├── 5 │ │ │ └── index.md │ │ └── index.md │ ├── 15 │ │ ├── 1 │ │ │ └── index.md │ │ ├── 2 │ │ │ └── index.md │ │ ├── 3 │ │ │ └── index.md │ │ ├── 4 │ │ │ └── index.md │ │ ├── 5 │ │ │ └── index.md │ │ └── index.md │ ├── 16 │ │ ├── 1 │ │ │ └── index.md │ │ ├── 2 │ │ │ └── index.md │ │ ├── 3 │ │ │ └── index.md │ │ ├── 4 │ │ │ └── index.md │ │ ├── 5 │ │ │ └── index.md │ │ └── index.md │ ├── 17 │ │ ├── 1 │ │ │ └── index.md │ │ ├── 2 │ │ │ └── index.md │ │ ├── 3 │ │ │ └── index.md │ │ ├── 4 │ │ │ └── index.md │ │ ├── 5 │ │ │ └── index.md │ │ └── index.md │ ├── 18 │ │ ├── 1 │ │ │ └── index.md │ │ ├── 2 │ │ │ └── index.md │ │ ├── 3 │ │ │ └── index.md │ │ ├── 4 │ │ │ └── index.md │ │ ├── 5 │ │ │ └── index.md │ │ └── index.md │ ├── 19 │ │ ├── 1 │ │ │ └── index.md │ │ ├── 2 │ │ │ └── index.md │ │ ├── 3 │ │ │ └── index.md │ │ ├── 4 │ │ │ └── index.md │ │ ├── 5 │ │ │ └── index.md │ │ └── index.md │ ├── 20 │ │ ├── 1 │ │ │ └── index.md │ │ ├── 2 │ │ │ └── index.md │ │ ├── 3 │ │ │ └── index.md │ │ ├── 4 │ │ │ └── index.md │ │ ├── 5 │ │ │ └── index.md │ │ └── index.md │ ├── 21 │ │ ├── 1 │ │ │ ├── 1.md │ │ │ └── index.md │ │ ├── 2 │ │ │ └── index.md │ │ ├── 3 │ │ │ └── index.md │ │ ├── 4 │ │ │ └── index.md │ │ ├── 5 │ │ │ └── index.md │ │ └── index.md │ ├── 22 │ │ ├── 1 │ │ │ ├── 1.md │ │ │ └── index.md │ │ ├── 2 │ │ │ ├── 1.md │ │ │ └── index.md │ │ ├── 3 │ │ │ ├── 1.md │ │ │ └── index.md │ │ ├── 4 │ │ │ ├── 1.md │ │ │ └── index.md │ │ ├── 5 │ │ │ ├── 1.md │ │ │ └── index.md │ │ └── index.md │ ├── 23 │ │ ├── 1 │ │ │ ├── 1.md │ │ │ └── index.md │ │ ├── 2 │ │ │ ├── 1.md │ │ │ ├── image │ │ │ │ └── 1-conditions.png │ │ │ └── index.md │ │ ├── 3 │ │ │ ├── 1.md │ │ │ └── index.md │ │ ├── 4 │ │ │ ├── 1.md │ │ │ └── index.md │ │ ├── 5 │ │ │ ├── 1.md │ │ │ └── index.md │ │ └── index.md │ ├── 24 │ │ ├── 1 │ │ │ ├── 1.md │ │ │ └── index.md │ │ ├── 2 │ │ │ ├── 1.md │ │ │ ├── 2.md │ │ │ └── index.md │ │ ├── 3 │ │ │ ├── 1.md │ │ │ ├── image │ │ │ │ └── 1-polylongdiv.png │ │ │ └── index.md │ │ ├── 4 │ │ │ ├── 1.md │ │ │ └── index.md │ │ ├── 5 │ │ │ ├── 1.md │ │ │ └── index.md │ │ └── index.md │ └── index.md ├── tags.md └── test_pages │ ├── test.md │ └── unfinished.md ├── mkdocs.yml └── overrides ├── contest.html ├── knowledge.html ├── main.html ├── problem.html └── solution.html /.gitignore: -------------------------------------------------------------------------------- 1 | site/ 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 历年 CCF CSP 题目解析 2 | 3 | 历年 CCF CSP 题目解析,用来整理记录 CSP 考试题目的分析及题解。 4 | 5 | 该项目目前部署在[Github Pages](https://ccf-csp-project.github.io/CSP-Project-with-MkDocs/)。 如果访问 Github Pages 网络过慢,可以去[镜像站](http://123.57.252.106/)。 6 | 7 | 该项目涉及多个版本,您目前正在浏览的是 MkDocs 版本。所有版本会尽量保持同步更新。 -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # CSP Project 2 | 3 | **CCF CSP认证**(CCF 计算机软件能力认证 Certified Software Professional)是中国计算机学会(CCF)联合华为、360、滴滴等十余家知名IT企业以及清华、北航、国防科大等15所著名高校于2014年推出CCF CSP(计算机软件能力)认证标准,用于评价业界人士的计算机软件能力。 4 | 5 | **CSP Project** 旨在整理 CSP 考试题目的各种难度层次,且满足考试环境需求的思路及题解,力求满足各个水平阶层选手的需要,让所有读者都能有所收获。 6 | 7 | 该项目存在不同版本,各个版本间会尽量保持同步更新。 -------------------------------------------------------------------------------- /docs/introduction/about.md: -------------------------------------------------------------------------------- 1 | # 关于本项目 2 | 3 | ## 内容说明 4 | 5 | **CSP Project** 旨在整理 CSP 考试题目的各种难度层次,且满足考试环境需求的思路及题解。 6 | 7 | ## 结构说明 8 | 9 | 为了更好复现考试情况(不会事先知道题目使用的算法),以及思路的连贯性与递进性,项目按照**比赛场次**进行分类安排。目前暂不支持以算法标签搜索题目。 10 | 11 | 题目列表内有每场比赛的题目,而题目页面对应有**思路列表**表格。它指明了解决该题目的不同思路,包含部分分思路。 12 | 13 | 每个思路有对应的三部分链接: 14 | 15 | - 贡献者:指向了该思路条目的创建者; 16 | - 使用语言:指向了该思路对应的代码题解; 17 | - 链接:题解链接指向了该部分思路对应的位置,方便读者进行选择性阅读;文章链接指向了该思路所对应的文章,我们将连贯的思路放在了同一文档内,方便读者理解。 18 | 19 | ## 该项目的其他版本 20 | 21 | - [LaTeX 版本](https://github.com/lxlonlyn/CSP-Project) 22 | -------------------------------------------------------------------------------- /docs/introduction/contributing.md: -------------------------------------------------------------------------------- 1 | # 如何参与 2 | 3 | ## 直接在 Github 上编辑 4 | 5 | ### 增加页面 6 | 7 | 请参考[如何编写自己的思路页面](write_passage.md)。 8 | 9 | ### 修改单个页面 10 | 11 | 1. 如果您没有 Github 账号,请[注册](https://github.com/signup)一个。 12 | 2. 找到您想修改的页面; 13 | 3. 点击正文右上方(目录左侧)的**编辑此页**按钮; 14 | 4. 在编辑框内编写你想修改的内容; 15 | 5. 编写完成后滚动到页面下方,点击 ++"Propose changes"++ 按钮提交修改。点击按钮后,GitHub 会自动帮你创建一份分支,并将你的提交添加到这个分支仓库。 16 | 6. GitHub 会自动跳转到你的分支仓库的页面,此时页面上方会显示 ++"Create pull request"++ 按钮,点击后 GitHub 会跳转到一个创建 Pull Request 页面。向下滚动检查自己所作出的修改没有错误后,填写 Pull Request 信息,然后点击页面上的绿色的 ++"Create pull request"++ 按钮创建 Pull Request。 17 | 7. 不出意外的话,你的 Pull Request 就顺利提交到仓库,等待管理员审核并合并到主仓库中即可。 18 | 19 | ### 修改多个页面 20 | 21 | 考虑到 Github 的链接稳定性,我们推荐您[使用 Git 进行本地编辑](#git)。 22 | 23 | ## 使用 Git 进行本地编辑 24 | 25 | 1. 将主仓库 Fork 到自己的仓库中; 26 | 2. 将 Fork 后的仓库克隆(clone)到本地; 27 | 3. 在本地进行修改后提交(commit)这些更改; 28 | 4. 将这些更改推送(push)到你克隆的仓库; 29 | 5. 提交 Pull Request 至主仓库。 30 | 31 | 如果您无法理解上述操作,可以使用以下一系列操作。 32 | 33 | 1. 将仓库拷贝到自身账户 34 | 1. 如果您没有 Github 的账户,请[注册](https://github.com/signup)一个。 35 | 2. 根据自己的平台,下载并安装 Git,参考[链接](https://git-scm.com/download)。 36 | 3. 装好之后,配置本地用户。在命令行中输入以下代码: 37 | ``` 38 | git config -global user.name "你自己的用户名" 39 | git config -global user.email "自己的邮箱@example.com" 40 | ``` 41 | 4. 在[本仓库]的右上角有 ++"Fork"++ 选项,点击它。之后您会发现该项目已经拷贝到了您的库中。 42 | 5. 在本地建好一个文件夹,用于存放拷贝下来的文件。进入该文件夹,输入以下指令: 43 | ``` 44 | git clone https://github.com/您的github账号名称/CSP-Project-with-MkDocs.git 45 | ``` 46 | 6. 您现在应该能在该文件夹中看到整体项目了。 47 | 2. 在自身仓库中进行修改 48 | 1. 在该文件夹中进行对应的修改。**在您的仓库里的修改不会影响到本项目页面的展示,请不用担心损坏问题。** 49 | 2. 进行对应修改之后,在该文件夹中开启命令行,输入以下指令: 50 | ``` 51 | git add . 52 | git commit -m "我做出了哪些贡献" 53 | git push origin master 54 | ``` 55 | 3. 登入 Github 网页端,应该可以看见您的仓库内已经出现了对应的变化。 56 | 3. 将自身仓库提交到本仓库 57 | 1. 在您的仓库页面,点击导航栏中的 ++"Pull request"++,之后再点击右上角绿色的 ++"New pull request"++ 。 58 | 2. 确认 Pull request 的方向,应该由您的仓库指向本仓库。确认无误后,点击绿色的 ++"Create pull request"++ 。 59 | 3. 填写好对应评论,点击右下角绿色 ++"Create pull request"++ 即可。 60 | 61 | [本仓库]: https://github.com/CCF-CSP-Project/CSP-Project-with-MkDocs -------------------------------------------------------------------------------- /docs/introduction/faq.md: -------------------------------------------------------------------------------- 1 | # 常见问题解答 2 | 3 | !!! question "为什么要做这个项目?" 4 | 5 | 1. 网上题解鱼龙混杂,很难找到适合自己的; 6 | 2. 很多选手无法做到一眼看出某些题的做法(比如笔者),需要对各种方法进行分析、尝试与筛选,而很多题解往往“一步到位”,缺少中间分析;同时部分分的思路提及较少; 7 | 3. 笔者受学校老师所托,写出一本书来提升笔者所在学校的整体 CSP 认证水平。后来在 [icy-blue](https://github.com/icy-blue) 大佬的提醒下,笔者了解了 MkDocs,感觉相比用 LaTeX 编写书籍而言,它更适合于大家交流思路。 8 | 9 | 10 | !!! question "这个项目是不是等同于 CSP 的 [OI-Wiki]" 11 | 12 |   制作该项目最初的动机并没有 [OI-Wiki] 那么伟大,不过最终的目的也是大致相同的:让更多竞赛资源不充裕的同学能方便地接触到训练资源。 13 | 14 |   [OI-Wiki] 是非常好的学习网站,但正式比赛的时候,题目使用的算法是不能预料的,需要进行一定分析。本项目旨在帮助读者强化“分析”的能力,与 [OI-Wiki] 等共同促进读者水平的进步。 15 | 16 | 17 | !!! question "我对这个项目很感兴趣,该怎么参与?" 18 | 19 |   我们很感谢您对本项目的支持! 20 | 21 |   参与的方式有很多,请参考 [如何参与] 页面。 22 | 23 | 24 | !!! question "我可能比较弱,不知道该做些什么 QAQ" 25 | 26 |   我们很感谢您对本项目的支持! 27 | 28 |   因为要收集不同的思路,所以我们希望听到更多人的声音。无论您处于算法学习途中的哪一阶段,想必都有自己在这一阶段的理解与收获。如果您能够将您的思路分享给大家,我们将会万分感谢。 29 | 30 |   能参与的方式不只有提供思路与题解,其他也有很多。比如审核、修改稿件,宣传 CSP Project,提出优化界面的建议等等。 31 | 32 |   参与帮助的方式有很多,请参考 [如何参与] 页面。 33 | 34 | 35 | [OI-Wiki]: https://oi-wiki.org/ 36 | [如何参与]: contributing.md -------------------------------------------------------------------------------- /docs/introduction/write_passage.md: -------------------------------------------------------------------------------- 1 | # 如何编写自己的题解页面 2 | 3 | 1. 我们欢迎任何人提出您的思路!但是对于和已有思路重合的思路,我们会考虑合并。所以请再阅读完所有思路的大概后,确定没人做过后再添加您的思路。如果只是建议或提示,请通过修改实现。 4 | 2. 将该仓库存放到本地,可以参考[使用 Git 进行本地编辑](contributing.md#git)中的第一步。 5 | 3. 在**恰当的位置**添加您想增加的页面,请参考下文的[文档结构说明](#_2)。 6 | 4. 在进行修改完善后,提交到本仓库。可以参考[使用 Git 进行本地编辑](contributing.md#git)。 7 | 8 | ## 文档结构说明 9 | 10 | 1. 所有的页面都存放在 `docs` 文件夹下,思路及题解在 `docs/problem` 中。 11 | 2. 如果您想增加第 x 次认证第 y 题的题解,请在 `docs/problem/x/y` 下创建您的文档。如第 24 次认证第 5 题的题解文件夹在 `docs/problem/24/5`。 12 | 3. 请将您的文档命名为 `n.md`,其中 n 代表目前该题目题解目录内题解文章的个数。比如当文件夹中有 `1.md` 和 `2.md` 后,您可以将您的文档命名为 `3.md`。 13 | 4. 如果您需要增加图片,则可以在题目文件夹下的 image 文件夹(如果没有则创建)中存放图片,命名为 `n-name.xxx`,其中 n 为对应的文档名称,`name` 为图片名字,`xxx` 为后缀。如您要给 `3.md` 增加图片 `test.png`,则请在 `image` 文件夹中命名为 `3-test.png`。 14 | 5. 在编写完之后,请在题目文件夹对应的 `index.md` 中,在思路列表添加对应您的记录。 15 | 16 | ???+ example "我是一个栗子" 17 | 18 | 比如说,您要编写第 233 届比赛第 1 题的题解思路,该比赛在 2042 年 12 月举办。目前已经有两个题解文件 `1.md 2.md` 了。 19 | 20 | === "创建 docs/problem/233/1/3.md" 21 | 22 | ```{ .markdown .annotate linenums="1"} 23 | # 204212-1 我是题目名字 (1) 24 | 25 | ## 50% 数据——某个思路 (2) 26 | 27 | 这是一段演示。 28 | 29 | 时间复杂度 $\mathbf{O}(n)$。 30 | 31 | ## 100% 数据——根据某个思路的改进 32 | 33 | 这是一段演示。 34 | 35 | 时间复杂度 $\mathbf{O}(1)$。 36 | 37 | ### 实现 (3) 38 | 39 | ???+ success "代码实现" (4) 40 | 41 | === "C++" 42 | 43 | ```cpp linenums="1" 44 | #include 45 | #include 46 | using namespace std; 47 | int main() { 48 | // 代码不好懂时,推荐增加注释 49 | printf("Hello World!\n"); 50 | return 0; 51 | } 52 | ``` 53 | 54 | === "Java" 55 | 56 | ```Java linenums="1" 57 | import java.util.Scanner; 58 | 59 | public class Main { 60 | public static void main(String[] args) { 61 | System.out.println("Hello World!\n"); 62 | } 63 | } 64 | ``` 65 | 66 | === "Python 3" 67 | 68 | ```python linenums="1" 69 | print("Hello World\n") 70 | ``` 71 | ``` 72 | 73 | 1. 请在文章开头说明对应题目,表示为 `# yyyymm-p name` 的形式,其中 `yyyy` 对应比赛年份,`mm` 是月,`p` 是题目编号,`name` 是题目名称。 74 | 2. 对于每个思路,请说明得分 + 大致思路。 75 | 3. 实现请单独标出,方便后续引用。 76 | 4. 代码请按照此格式给出。 77 | 78 | === "docs/problem/233/index.md" 79 | 80 | ```markdown linenums="1" hl_lines="13 14 18" 81 | # 204212-1 我是题目名字 82 | 83 | ## 题目链接 84 | 85 | [204212-1 我是题目名字](这里是指向 CCF CSP 官网测试网站的网址) 86 | 87 | ## 思路列表 88 | 89 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 90 | | :-: | :-: | :-: | :-: | :-: | 91 | | [其他人的github名称](其他人的github账号) | 100 | 其他人的某个思路1 | [C++](1.md#对应代码位置) | [题解链接](1.md#对应解析位置)/[文章 1] | 92 | | [其他人的github名称](其他人的github账号) | 100 | 其他人的某个思路2 | [Java](2.md#对应代码位置) | [题解链接](2.md#对应解析位置)/[文章 2] | 93 | | [您的github名称](您的github账号) | 50 | 某个思路 | | [题解链接](n.md#对应题解位置)/[文章 3] | 94 | | [您的github名称](您的github账号) | 100 | 根据某个思路的改进 | [C++、Java、Python 3](3.md#对应代码位置) | [题解链接](n.md#对应题解位置)/[文章 3] | 95 | 96 | [文章 1]: 1.md 97 | [文章 2]: 2.md 98 | [文章 3]: 3.md 99 | 100 | ``` 101 | 102 | 1. 您只需要增加黄色背景的行即可,其他内容应该先前存在。 103 | 2. 对应位置即为网页标签对应位置,在生成网页后点击对应导航栏即可浏览。如果无法知晓,可以暂时忽略。 104 | -------------------------------------------------------------------------------- /docs/javascripts/mathjax.js: -------------------------------------------------------------------------------- 1 | window.MathJax = { 2 | tex: { 3 | inlineMath: [["\\(", "\\)"]], 4 | displayMath: [["\\[", "\\]"]], 5 | processEscapes: true, 6 | processEnvironments: true 7 | }, 8 | options: { 9 | ignoreHtmlClass: ".*|", 10 | processHtmlClass: "arithmatex" 11 | } 12 | }; 13 | 14 | document$.subscribe(() => { 15 | MathJax.typesetPromise() 16 | }) 17 | -------------------------------------------------------------------------------- /docs/javascripts/site.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | $('#idea_list').DataTable( 3 | { 4 | columnDefs: [ 5 | { 6 | targets: "_all", 7 | className: 'dt-body-center' 8 | }, 9 | { 10 | orderable: false, 11 | targets: [2, 3, 4, 5] 12 | } 13 | ], 14 | language: { 15 | "lengthMenu": "每页展示 _MENU_ 条题解", 16 | "zeroRecords": "没有查询到任何题解QAQ,不如自己创作一个?", 17 | "info": "目前为第 _PAGE_ 页,总共 _PAGES_ 页", 18 | "infoEmpty": "没有题解记录", 19 | "infoFiltered": "(从 _MAX_ 条题解中筛选)", 20 | "paginate": { 21 | "previous": "上一页", 22 | "next": "下一页" 23 | }, 24 | "search": "查找关键字:" 25 | } 26 | } 27 | ); 28 | }); -------------------------------------------------------------------------------- /docs/knowledge/index.md: -------------------------------------------------------------------------------- 1 | # 知识库 2 | 3 | 有一些题目涉及了比较复杂的知识点,不适合在页面内展开。知识库主要用来存放这一些知识点。 4 | 5 | 因为该计划并不是按照知识点来进行专项练习,知识库中内容很难做到非常全面。如果想要进行深入全面地学习,推荐使用[OI Wiki](https://oi-wiki.org/),或者是其他大佬的博客。 -------------------------------------------------------------------------------- /docs/problem/1/1/index.md: -------------------------------------------------------------------------------- 1 | # 201403-1 相反数 2 | 3 | ## 题目链接 4 | 5 | [201403-1 相反数](http://118.190.20.162/view.page?gpid=T10) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/1/2/index.md: -------------------------------------------------------------------------------- 1 | # 201403-2 窗口 2 | 3 | ## 题目链接 4 | 5 | [201403-2 窗口](http://118.190.20.162/view.page?gpid=T9) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/1/3/index.md: -------------------------------------------------------------------------------- 1 | # 201403-3 命令行选项 2 | 3 | ## 题目链接 4 | 5 | [201403-3 命令行选项](http://118.190.20.162/view.page?gpid=T8) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/1/4/index.md: -------------------------------------------------------------------------------- 1 | # 201403-4 无线网络 2 | 3 | ## 题目链接 4 | 5 | [201403-4 无线网络](http://118.190.20.162/view.page?gpid=T7) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/1/5/index.md: -------------------------------------------------------------------------------- 1 | # 201403-5 任务调度 2 | 3 | ## 题目链接 4 | 5 | [201403-5 任务调度](http://118.190.20.162/view.page?gpid=T6) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/1/index.md: -------------------------------------------------------------------------------- 1 | # 第 1 次(2014 年 3 月) 2 | 3 | 4 | | 题目编号 | 题目名称 | 涉及算法 | 最高得分 | 满分题解语言 | 链接 | 5 | | :-: | :-: | :-: | :-: | :-: | :-: | 6 | | 201403-1 | 相反数 | | | | [链接](1\index.md) | 7 | | 201403-2 | 窗口 | | | | [链接](2\index.md) | 8 | | 201403-3 | 命令行选项 | | | | [链接](3\index.md) | 9 | | 201403-4 | 无线网络 | | | | [链接](4\index.md) | 10 | | 201403-5 | 任务调度 | | | | [链接](5\index.md) | 11 | -------------------------------------------------------------------------------- /docs/problem/10/1/index.md: -------------------------------------------------------------------------------- 1 | # 201703-1 分蛋糕 2 | 3 | ## 题目链接 4 | 5 | [201703-1 分蛋糕](http://118.190.20.162/view.page?gpid=T57) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/10/2/index.md: -------------------------------------------------------------------------------- 1 | # 201703-2 学生排队 2 | 3 | ## 题目链接 4 | 5 | [201703-2 学生排队](http://118.190.20.162/view.page?gpid=T56) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/10/3/index.md: -------------------------------------------------------------------------------- 1 | # 201703-3 Markdown 2 | 3 | ## 题目链接 4 | 5 | [201703-3 Markdown](http://118.190.20.162/view.page?gpid=T55) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/10/4/index.md: -------------------------------------------------------------------------------- 1 | # 201703-4 地铁修建 2 | 3 | ## 题目链接 4 | 5 | [201703-4 地铁修建](http://118.190.20.162/view.page?gpid=T54) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/10/5/index.md: -------------------------------------------------------------------------------- 1 | # 201703-5 引水入城 2 | 3 | ## 题目链接 4 | 5 | [201703-5 引水入城](http://118.190.20.162/view.page?gpid=T53) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/10/index.md: -------------------------------------------------------------------------------- 1 | # 第 10 次(2017 年 3 月) 2 | 3 | 4 | | 题目编号 | 题目名称 | 涉及算法 | 最高得分 | 满分题解语言 | 链接 | 5 | | :-: | :-: | :-: | :-: | :-: | :-: | 6 | | 201703-1 | 分蛋糕 | | | | [链接](1\index.md) | 7 | | 201703-2 | 学生排队 | | | | [链接](2\index.md) | 8 | | 201703-3 | Markdown | | | | [链接](3\index.md) | 9 | | 201703-4 | 地铁修建 | | | | [链接](4\index.md) | 10 | | 201703-5 | 引水入城 | | | | [链接](5\index.md) | 11 | -------------------------------------------------------------------------------- /docs/problem/11/1/index.md: -------------------------------------------------------------------------------- 1 | # 201709-1 打酱油 2 | 3 | ## 题目链接 4 | 5 | [201709-1 打酱油](http://118.190.20.162/view.page?gpid=T63) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/11/2/index.md: -------------------------------------------------------------------------------- 1 | # 201709-2 公共钥匙盒 2 | 3 | ## 题目链接 4 | 5 | [201709-2 公共钥匙盒](http://118.190.20.162/view.page?gpid=T62) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/11/3/index.md: -------------------------------------------------------------------------------- 1 | # 201709-3 JSON查询 2 | 3 | ## 题目链接 4 | 5 | [201709-3 JSON查询](http://118.190.20.162/view.page?gpid=T61) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/11/4/index.md: -------------------------------------------------------------------------------- 1 | # 201709-4 通信网络 2 | 3 | ## 题目链接 4 | 5 | [201709-4 通信网络](http://118.190.20.162/view.page?gpid=T60) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/11/5/index.md: -------------------------------------------------------------------------------- 1 | # 201709-5 除法 2 | 3 | ## 题目链接 4 | 5 | [201709-5 除法](http://118.190.20.162/view.page?gpid=T59) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/11/index.md: -------------------------------------------------------------------------------- 1 | # 第 11 次(2017 年 9 月) 2 | 3 | 4 | | 题目编号 | 题目名称 | 涉及算法 | 最高得分 | 满分题解语言 | 链接 | 5 | | :-: | :-: | :-: | :-: | :-: | :-: | 6 | | 201709-1 | 打酱油 | | | | [链接](1\index.md) | 7 | | 201709-2 | 公共钥匙盒 | | | | [链接](2\index.md) | 8 | | 201709-3 | JSON查询 | | | | [链接](3\index.md) | 9 | | 201709-4 | 通信网络 | | | | [链接](4\index.md) | 10 | | 201709-5 | 除法 | | | | [链接](5\index.md) | 11 | -------------------------------------------------------------------------------- /docs/problem/12/1/index.md: -------------------------------------------------------------------------------- 1 | # 201712-1 最小差值 2 | 3 | ## 题目链接 4 | 5 | [201712-1 最小差值](http://118.190.20.162/view.page?gpid=T68) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/12/2/index.md: -------------------------------------------------------------------------------- 1 | # 201712-2 游戏 2 | 3 | ## 题目链接 4 | 5 | [201712-2 游戏](http://118.190.20.162/view.page?gpid=T67) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/12/3/index.md: -------------------------------------------------------------------------------- 1 | # 201712-3 Crontab 2 | 3 | ## 题目链接 4 | 5 | [201712-3 Crontab](http://118.190.20.162/view.page?gpid=T66) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/12/4/index.md: -------------------------------------------------------------------------------- 1 | # 201712-4 行车路线 2 | 3 | ## 题目链接 4 | 5 | [201712-4 行车路线](http://118.190.20.162/view.page?gpid=T65) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/12/5/index.md: -------------------------------------------------------------------------------- 1 | # 201712-5 商路 2 | 3 | ## 题目链接 4 | 5 | [201712-5 商路](http://118.190.20.162/view.page?gpid=T64) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/12/index.md: -------------------------------------------------------------------------------- 1 | # 第 12 次(2017 年 12 月) 2 | 3 | 4 | | 题目编号 | 题目名称 | 涉及算法 | 最高得分 | 满分题解语言 | 链接 | 5 | | :-: | :-: | :-: | :-: | :-: | :-: | 6 | | 201712-1 | 最小差值 | | | | [链接](1\index.md) | 7 | | 201712-2 | 游戏 | | | | [链接](2\index.md) | 8 | | 201712-3 | Crontab | | | | [链接](3\index.md) | 9 | | 201712-4 | 行车路线 | | | | [链接](4\index.md) | 10 | | 201712-5 | 商路 | | | | [链接](5\index.md) | 11 | -------------------------------------------------------------------------------- /docs/problem/13/1/index.md: -------------------------------------------------------------------------------- 1 | # 201803-1 跳一跳 2 | 3 | ## 题目链接 4 | 5 | [201803-1 跳一跳](http://118.190.20.162/view.page?gpid=T73) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/13/2/index.md: -------------------------------------------------------------------------------- 1 | # 201803-2 碰撞的小球 2 | 3 | ## 题目链接 4 | 5 | [201803-2 碰撞的小球](http://118.190.20.162/view.page?gpid=T72) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/13/3/index.md: -------------------------------------------------------------------------------- 1 | # 201803-3 URL映射 2 | 3 | ## 题目链接 4 | 5 | [201803-3 URL映射](http://118.190.20.162/view.page?gpid=T71) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/13/4/index.md: -------------------------------------------------------------------------------- 1 | # 201803-4 棋局评估 2 | 3 | ## 题目链接 4 | 5 | [201803-4 棋局评估](http://118.190.20.162/view.page?gpid=T70) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/13/5/index.md: -------------------------------------------------------------------------------- 1 | # 201803-5 二次求和 2 | 3 | ## 题目链接 4 | 5 | [201803-5 二次求和](http://118.190.20.162/view.page?gpid=T69) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/13/index.md: -------------------------------------------------------------------------------- 1 | # 第 13 次(2018 年 3 月) 2 | 3 | 4 | | 题目编号 | 题目名称 | 涉及算法 | 最高得分 | 满分题解语言 | 链接 | 5 | | :-: | :-: | :-: | :-: | :-: | :-: | 6 | | 201803-1 | 跳一跳 | | | | [链接](1\index.md) | 7 | | 201803-2 | 碰撞的小球 | | | | [链接](2\index.md) | 8 | | 201803-3 | URL映射 | | | | [链接](3\index.md) | 9 | | 201803-4 | 棋局评估 | | | | [链接](4\index.md) | 10 | | 201803-5 | 二次求和 | | | | [链接](5\index.md) | 11 | -------------------------------------------------------------------------------- /docs/problem/14/1/index.md: -------------------------------------------------------------------------------- 1 | # 201809-1 卖菜 2 | 3 | ## 题目链接 4 | 5 | [201809-1 卖菜](http://118.190.20.162/view.page?gpid=T79) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/14/2/index.md: -------------------------------------------------------------------------------- 1 | # 201809-2 买菜 2 | 3 | ## 题目链接 4 | 5 | [201809-2 买菜](http://118.190.20.162/view.page?gpid=T78) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/14/3/index.md: -------------------------------------------------------------------------------- 1 | # 201809-3 元素选择器 2 | 3 | ## 题目链接 4 | 5 | [201809-3 元素选择器](http://118.190.20.162/view.page?gpid=T77) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/14/4/index.md: -------------------------------------------------------------------------------- 1 | # 201809-4 再卖菜 2 | 3 | ## 题目链接 4 | 5 | [201809-4 再卖菜](http://118.190.20.162/view.page?gpid=T76) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/14/5/index.md: -------------------------------------------------------------------------------- 1 | # 201809-5 线性递推式 2 | 3 | ## 题目链接 4 | 5 | [201809-5 线性递推式](http://118.190.20.162/view.page?gpid=T74) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/14/index.md: -------------------------------------------------------------------------------- 1 | # 第 14 次(2018 年 9 月) 2 | 3 | 4 | | 题目编号 | 题目名称 | 涉及算法 | 最高得分 | 满分题解语言 | 链接 | 5 | | :-: | :-: | :-: | :-: | :-: | :-: | 6 | | 201809-1 | 卖菜 | | | | [链接](1\index.md) | 7 | | 201809-2 | 买菜 | | | | [链接](2\index.md) | 8 | | 201809-3 | 元素选择器 | | | | [链接](3\index.md) | 9 | | 201809-4 | 再卖菜 | | | | [链接](4\index.md) | 10 | | 201809-5 | 线性递推式 | | | | [链接](5\index.md) | 11 | -------------------------------------------------------------------------------- /docs/problem/15/1/index.md: -------------------------------------------------------------------------------- 1 | # 201812-1 小明上学 2 | 3 | ## 题目链接 4 | 5 | [201812-1 小明上学](http://118.190.20.162/view.page?gpid=T80) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/15/2/index.md: -------------------------------------------------------------------------------- 1 | # 201812-2 小明放学 2 | 3 | ## 题目链接 4 | 5 | [201812-2 小明放学](http://118.190.20.162/view.page?gpid=T81) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/15/3/index.md: -------------------------------------------------------------------------------- 1 | # 201812-3 CIDR合并 2 | 3 | ## 题目链接 4 | 5 | [201812-3 CIDR合并](http://118.190.20.162/view.page?gpid=T82) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/15/4/index.md: -------------------------------------------------------------------------------- 1 | # 201812-4 数据中心 2 | 3 | ## 题目链接 4 | 5 | [201812-4 数据中心](http://118.190.20.162/view.page?gpid=T83) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/15/5/index.md: -------------------------------------------------------------------------------- 1 | # 201812-5 管道清洁 2 | 3 | ## 题目链接 4 | 5 | [201812-5 管道清洁](http://118.190.20.162/view.page?gpid=T84) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/15/index.md: -------------------------------------------------------------------------------- 1 | # 第 15 次(2018 年 12 月) 2 | 3 | 4 | | 题目编号 | 题目名称 | 涉及算法 | 最高得分 | 满分题解语言 | 链接 | 5 | | :-: | :-: | :-: | :-: | :-: | :-: | 6 | | 201812-1 | 小明上学 | | | | [链接](1\index.md) | 7 | | 201812-2 | 小明放学 | | | | [链接](2\index.md) | 8 | | 201812-3 | CIDR合并 | | | | [链接](3\index.md) | 9 | | 201812-4 | 数据中心 | | | | [链接](4\index.md) | 10 | | 201812-5 | 管道清洁 | | | | [链接](5\index.md) | 11 | -------------------------------------------------------------------------------- /docs/problem/16/1/index.md: -------------------------------------------------------------------------------- 1 | # 201903-1 小中大 2 | 3 | ## 题目链接 4 | 5 | [201903-1 小中大](http://118.190.20.162/view.page?gpid=T89) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/16/2/index.md: -------------------------------------------------------------------------------- 1 | # 201903-2 二十四点 2 | 3 | ## 题目链接 4 | 5 | [201903-2 二十四点](http://118.190.20.162/view.page?gpid=T88) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/16/3/index.md: -------------------------------------------------------------------------------- 1 | # 201903-3 损坏的RAID5 2 | 3 | ## 题目链接 4 | 5 | [201903-3 损坏的RAID5](http://118.190.20.162/view.page?gpid=T87) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/16/4/index.md: -------------------------------------------------------------------------------- 1 | # 201903-4 消息传递接口 2 | 3 | ## 题目链接 4 | 5 | [201903-4 消息传递接口](http://118.190.20.162/view.page?gpid=T86) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/16/5/index.md: -------------------------------------------------------------------------------- 1 | # 201903-5 317号子任务 2 | 3 | ## 题目链接 4 | 5 | [201903-5 317号子任务](http://118.190.20.162/view.page?gpid=T85) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/16/index.md: -------------------------------------------------------------------------------- 1 | # 第 16 次(2019 年 3 月) 2 | 3 | 4 | | 题目编号 | 题目名称 | 涉及算法 | 最高得分 | 满分题解语言 | 链接 | 5 | | :-: | :-: | :-: | :-: | :-: | :-: | 6 | | 201903-1 | 小中大 | | | | [链接](1\index.md) | 7 | | 201903-2 | 二十四点 | | | | [链接](2\index.md) | 8 | | 201903-3 | 损坏的RAID5 | | | | [链接](3\index.md) | 9 | | 201903-4 | 消息传递接口 | | | | [链接](4\index.md) | 10 | | 201903-5 | 317号子任务 | | | | [链接](5\index.md) | 11 | -------------------------------------------------------------------------------- /docs/problem/17/1/index.md: -------------------------------------------------------------------------------- 1 | # 201909-1 小明种苹果 2 | 3 | ## 题目链接 4 | 5 | [201909-1 小明种苹果](http://118.190.20.162/view.page?gpid=T94) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/17/2/index.md: -------------------------------------------------------------------------------- 1 | # 201909-2 小明种苹果(续) 2 | 3 | ## 题目链接 4 | 5 | [201909-2 小明种苹果(续)](http://118.190.20.162/view.page?gpid=T93) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/17/3/index.md: -------------------------------------------------------------------------------- 1 | # 201909-3 字符画 2 | 3 | ## 题目链接 4 | 5 | [201909-3 字符画](http://118.190.20.162/view.page?gpid=T92) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/17/4/index.md: -------------------------------------------------------------------------------- 1 | # 201909-4 推荐系统 2 | 3 | ## 题目链接 4 | 5 | [201909-4 推荐系统](http://118.190.20.162/view.page?gpid=T91) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/17/5/index.md: -------------------------------------------------------------------------------- 1 | # 201909-5 城市规划 2 | 3 | ## 题目链接 4 | 5 | [201909-5 城市规划](http://118.190.20.162/view.page?gpid=T90) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/17/index.md: -------------------------------------------------------------------------------- 1 | # 第 17 次(2019 年 9 月) 2 | 3 | 4 | | 题目编号 | 题目名称 | 涉及算法 | 最高得分 | 满分题解语言 | 链接 | 5 | | :-: | :-: | :-: | :-: | :-: | :-: | 6 | | 201909-1 | 小明种苹果 | | | | [链接](1\index.md) | 7 | | 201909-2 | 小明种苹果(续) | | | | [链接](2\index.md) | 8 | | 201909-3 | 字符画 | | | | [链接](3\index.md) | 9 | | 201909-4 | 推荐系统 | | | | [链接](4\index.md) | 10 | | 201909-5 | 城市规划 | | | | [链接](5\index.md) | 11 | -------------------------------------------------------------------------------- /docs/problem/18/1/index.md: -------------------------------------------------------------------------------- 1 | # 201912-1 报数 2 | 3 | ## 题目链接 4 | 5 | [201912-1 报数](http://118.190.20.162/view.page?gpid=T100) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/18/2/index.md: -------------------------------------------------------------------------------- 1 | # 201912-2 回收站选址 2 | 3 | ## 题目链接 4 | 5 | [201912-2 回收站选址](http://118.190.20.162/view.page?gpid=T99) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/18/3/index.md: -------------------------------------------------------------------------------- 1 | # 201912-3 化学方程式 2 | 3 | ## 题目链接 4 | 5 | [201912-3 化学方程式](http://118.190.20.162/view.page?gpid=T98) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/18/4/index.md: -------------------------------------------------------------------------------- 1 | # 201912-4 区块链 2 | 3 | ## 题目链接 4 | 5 | [201912-4 区块链](http://118.190.20.162/view.page?gpid=T97) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/18/5/index.md: -------------------------------------------------------------------------------- 1 | # 201912-5 魔数 2 | 3 | ## 题目链接 4 | 5 | [201912-5 魔数](http://118.190.20.162/view.page?gpid=T96) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/18/index.md: -------------------------------------------------------------------------------- 1 | # 第 18 次(2019 年 12 月) 2 | 3 | 4 | | 题目编号 | 题目名称 | 涉及算法 | 最高得分 | 满分题解语言 | 链接 | 5 | | :-: | :-: | :-: | :-: | :-: | :-: | 6 | | 201912-1 | 报数 | | | | [链接](1\index.md) | 7 | | 201912-2 | 回收站选址 | | | | [链接](2\index.md) | 8 | | 201912-3 | 化学方程式 | | | | [链接](3\index.md) | 9 | | 201912-4 | 区块链 | | | | [链接](4\index.md) | 10 | | 201912-5 | 魔数 | | | | [链接](5\index.md) | 11 | -------------------------------------------------------------------------------- /docs/problem/19/1/index.md: -------------------------------------------------------------------------------- 1 | # 202006-1 线性分类器 2 | 3 | ## 题目链接 4 | 5 | [202006-1 线性分类器](http://118.190.20.162/view.page?gpid=T105) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/19/2/index.md: -------------------------------------------------------------------------------- 1 | # 202006-2 稀疏向量 2 | 3 | ## 题目链接 4 | 5 | [202006-2 稀疏向量](http://118.190.20.162/view.page?gpid=T104) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/19/3/index.md: -------------------------------------------------------------------------------- 1 | # 202006-3 Markdown渲染器 2 | 3 | ## 题目链接 4 | 5 | [202006-3 Markdown渲染器](http://118.190.20.162/view.page?gpid=T103) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/19/4/index.md: -------------------------------------------------------------------------------- 1 | # 202006-4 1246 2 | 3 | ## 题目链接 4 | 5 | [202006-4 1246](http://118.190.20.162/view.page?gpid=T102) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/19/5/index.md: -------------------------------------------------------------------------------- 1 | # 202006-5 乔乔和牛牛逛超市 2 | 3 | ## 题目链接 4 | 5 | [202006-5 乔乔和牛牛逛超市](http://118.190.20.162/view.page?gpid=T101) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/19/index.md: -------------------------------------------------------------------------------- 1 | # 第 19 次(2020 年 6 月) 2 | 3 | 4 | | 题目编号 | 题目名称 | 涉及算法 | 最高得分 | 满分题解语言 | 链接 | 5 | | :-: | :-: | :-: | :-: | :-: | :-: | 6 | | 202006-1 | 线性分类器 | | | | [链接](1\index.md) | 7 | | 202006-2 | 稀疏向量 | | | | [链接](2\index.md) | 8 | | 202006-3 | Markdown渲染器 | | | | [链接](3\index.md) | 9 | | 202006-4 | 1246 | | | | [链接](4\index.md) | 10 | | 202006-5 | 乔乔和牛牛逛超市 | | | | [链接](5\index.md) | 11 | -------------------------------------------------------------------------------- /docs/problem/2/1/index.md: -------------------------------------------------------------------------------- 1 | # 201409-1 相邻数对 2 | 3 | ## 题目链接 4 | 5 | [201409-1 相邻数对](http://118.190.20.162/view.page?gpid=T16) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/2/2/index.md: -------------------------------------------------------------------------------- 1 | # 201409-2 画图 2 | 3 | ## 题目链接 4 | 5 | [201409-2 画图](http://118.190.20.162/view.page?gpid=T15) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/2/3/index.md: -------------------------------------------------------------------------------- 1 | # 201409-3 字符串匹配 2 | 3 | ## 题目链接 4 | 5 | [201409-3 字符串匹配](http://118.190.20.162/view.page?gpid=T14) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/2/4/index.md: -------------------------------------------------------------------------------- 1 | # 201409-4 最优配餐 2 | 3 | ## 题目链接 4 | 5 | [201409-4 最优配餐](http://118.190.20.162/view.page?gpid=T13) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/2/5/index.md: -------------------------------------------------------------------------------- 1 | # 201409-5 拼图 2 | 3 | ## 题目链接 4 | 5 | [201409-5 拼图](http://118.190.20.162/view.page?gpid=T12) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/2/index.md: -------------------------------------------------------------------------------- 1 | # 第 2 次(2014 年 9 月) 2 | 3 | 4 | | 题目编号 | 题目名称 | 涉及算法 | 最高得分 | 满分题解语言 | 链接 | 5 | | :-: | :-: | :-: | :-: | :-: | :-: | 6 | | 201409-1 | 相邻数对 | | | | [链接](1\index.md) | 7 | | 201409-2 | 画图 | | | | [链接](2\index.md) | 8 | | 201409-3 | 字符串匹配 | | | | [链接](3\index.md) | 9 | | 201409-4 | 最优配餐 | | | | [链接](4\index.md) | 10 | | 201409-5 | 拼图 | | | | [链接](5\index.md) | 11 | -------------------------------------------------------------------------------- /docs/problem/20/1/index.md: -------------------------------------------------------------------------------- 1 | # 202009-1 称检测点查询 2 | 3 | ## 题目链接 4 | 5 | [202009-1 称检测点查询](http://118.190.20.162/view.page?gpid=T113) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/20/2/index.md: -------------------------------------------------------------------------------- 1 | # 202009-2 风险人群筛查 2 | 3 | ## 题目链接 4 | 5 | [202009-2 风险人群筛查](http://118.190.20.162/view.page?gpid=T112) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/20/3/index.md: -------------------------------------------------------------------------------- 1 | # 202009-3 点亮数字人生 2 | 3 | ## 题目链接 4 | 5 | [202009-3 点亮数字人生](http://118.190.20.162/view.page?gpid=T111) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/20/4/index.md: -------------------------------------------------------------------------------- 1 | # 202009-4 星际旅行 2 | 3 | ## 题目链接 4 | 5 | [202009-4 星际旅行](http://118.190.20.162/view.page?gpid=T110) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/20/5/index.md: -------------------------------------------------------------------------------- 1 | # 202009-5 密信与计数 2 | 3 | ## 题目链接 4 | 5 | [202009-5 密信与计数](http://118.190.20.162/view.page?gpid=T109) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/20/index.md: -------------------------------------------------------------------------------- 1 | # 第 20 次(2020 年 9 月) 2 | 3 | 4 | | 题目编号 | 题目名称 | 涉及算法 | 最高得分 | 满分题解语言 | 链接 | 5 | | :-: | :-: | :-: | :-: | :-: | :-: | 6 | | 202009-1 | 称检测点查询 | | | | [链接](1\index.md) | 7 | | 202009-2 | 风险人群筛查 | | | | [链接](2\index.md) | 8 | | 202009-3 | 点亮数字人生 | | | | [链接](3\index.md) | 9 | | 202009-4 | 星际旅行 | | | | [链接](4\index.md) | 10 | | 202009-5 | 密信与计数 | | | | [链接](5\index.md) | 11 | -------------------------------------------------------------------------------- /docs/problem/21/1/1.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: solution.html 3 | --- 4 | # 202012-1 期末预测之安全指数 5 | 6 | ## 100% 数据——模拟 7 | 8 | 根据题目要求,我们求出 $s=\sum\limits_{i=1}^{n}{score_i\cdot w_i}$ 后,输出 $\max\{{s, 0}\}$ 即可。 9 | 10 | 11 | ???+ success "代码实现" 12 | 13 | === "C++" 14 | ```cpp linenums="1" 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | using namespace std; 21 | int n; 22 | int w, s; 23 | int ans; 24 | int main() { 25 | scanf("%d", &n); 26 | ans = 0; 27 | for (int i = 1; i <= n; ++i) { 28 | scanf("%d%d", &w, &s); 29 | ans += w * s; 30 | } 31 | printf("%d", max(ans, 0)); 32 | return 0; 33 | } 34 | ``` 35 | === "Java" 36 | ```java linenums="1" 37 | import java.util.Scanner; 38 | public class csp2020121 { 39 | public static void main(String[] args) { 40 | Scanner input = new Scanner(System.in); 41 | int n, w, score, ans = 0; 42 | n = input.nextInt(); 43 | for (int i = 1; i <= n; ++i) { 44 | w = input.nextInt(); 45 | score = input.nextInt(); 46 | ans += w * score; 47 | } 48 | if (ans < 0) 49 | ans = 0; 50 | System.out.print(ans); 51 | input.close(); 52 | } 53 | } 54 | ``` 55 | === "Python 3" 56 | ```python linenums="1" 57 | n = int(input()) 58 | ans = 0 59 | for i in range(n): 60 | w, score = map(int, input().strip().split()) 61 | ans += w * score 62 | if ans < 0: 63 | ans = 0 64 | print(ans) 65 | ``` -------------------------------------------------------------------------------- /docs/problem/21/1/index.md: -------------------------------------------------------------------------------- 1 | # 202012-1 期末预测之安全指数 2 | 3 | ## 题目链接 4 | 5 | [202012-1 期末预测之安全指数](http://118.190.20.162/view.page?gpid=T123) 6 | 7 | ## 思路列表 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 | 28 | 29 | 30 |
题解文章得分要求大致思路题解语言链接
文章 1100无特殊限制 25 | 模拟C++、Java、Python 3题解链接
31 | -------------------------------------------------------------------------------- /docs/problem/21/2/index.md: -------------------------------------------------------------------------------- 1 | # 202012-2 期末预测之最佳阈值 2 | 3 | ## 题目链接 4 | 5 | [202012-2 期末预测之最佳阈值](http://118.190.20.162/view.page?gpid=T122) 6 | 7 | ## 思路列表 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
题解文章得分要求大致思路题解语言链接
23 | -------------------------------------------------------------------------------- /docs/problem/21/3/index.md: -------------------------------------------------------------------------------- 1 | # 202012-3 带配额的文件系统 2 | 3 | ## 题目链接 4 | 5 | [202012-3 带配额的文件系统](http://118.190.20.162/view.page?gpid=T121) 6 | 7 | ## 思路列表 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
题解文章得分要求大致思路题解语言链接
23 | -------------------------------------------------------------------------------- /docs/problem/21/4/index.md: -------------------------------------------------------------------------------- 1 | # 202012-4 食材运输 2 | 3 | ## 题目链接 4 | 5 | [202012-4 食材运输](http://118.190.20.162/view.page?gpid=T120) 6 | 7 | ## 思路列表 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
题解文章得分要求大致思路题解语言链接
23 | -------------------------------------------------------------------------------- /docs/problem/21/5/index.md: -------------------------------------------------------------------------------- 1 | # 202012-5 星际旅行 2 | 3 | ## 题目链接 4 | 5 | [202012-5 星际旅行](http://118.190.20.162/view.page?gpid=T119) 6 | 7 | ## 思路列表 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
题解文章得分要求大致思路题解语言链接
23 | -------------------------------------------------------------------------------- /docs/problem/21/index.md: -------------------------------------------------------------------------------- 1 | # 第 21 次(2020 年 12 月) 2 | 3 | 4 | | 题目编号 | 题目名称 | 涉及算法 | 最高得分 | 满分题解语言 | 链接 | 5 | | :-: | :-: | :-: | :-: | :-: | :-: | 6 | | 202012-1 | 期末预测之安全指数 | 模拟 | 100 | C++、Java、Python 3 | [链接](1\index.md) | 7 | | 202012-2 | 期末预测之最佳阈值 | | | | [链接](2\index.md) | 8 | | 202012-3 | 带配额的文件系统 | | | | [链接](3\index.md) | 9 | | 202012-4 | 食材运输 | | | | [链接](4\index.md) | 10 | | 202012-5 | 星际旅行 | | | | [链接](5\index.md) | 11 | -------------------------------------------------------------------------------- /docs/problem/22/1/1.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: solution.html 3 | --- 4 | # 202104-1 灰度直方图 5 | 6 | ## 100% 数据——模拟 7 | 8 | 题目要求输入一个二维矩阵,最终输出每个数出现了几次。 9 | 10 | 我们开一个桶记录一下即可。复杂度 $\mathrm{O}(n^2)$。 11 | 12 | 13 | ???+ success "代码实现" 14 | 15 | === "C++" 16 | ```cpp linenums="1" 17 | #include 18 | #include 19 | using namespace std; 20 | const int maxn = 510; 21 | const int maxl = 256; 22 | int n, m, L; 23 | int a[maxn][maxn]; 24 | int tot[maxl]; 25 | int main() { 26 | scanf("%d%d%d", &n, &m, &L); 27 | for (int i = 1; i <= n; ++i) { 28 | for (int j = 1; j <= m; ++j) { 29 | scanf("%d", &a[i][j]); 30 | } 31 | } 32 | for (int i = 1; i <= n; ++i) { 33 | for (int j = 1; j <= m; ++j) { 34 | ++tot[a[i][j]]; 35 | } 36 | } 37 | for (int i = 0; i < L; ++i) { 38 | printf("%d ", tot[i]); 39 | } 40 | return 0; 41 | } 42 | ``` 43 | === "Java" 44 | ```java linenums="1" 45 | import java.util.Scanner; 46 | public class Main { 47 | public static void main(String[] args) { 48 | Scanner input = new Scanner(System.in); 49 | int n = input.nextInt(), m = input.nextInt(), L = input.nextInt(); 50 | int[][] a = new int[n][m]; 51 | for (int i = 0; i < n; ++i) { 52 | for (int j = 0; j < m; ++j) { 53 | a[i][j] = input.nextInt(); 54 | } 55 | } 56 | input.close(); 57 | int[] tot = new int[L]; 58 | for (int i = 0; i < n; ++i) { 59 | for (int j = 0; j < m; ++j) { 60 | ++tot[a[i][j]]; 61 | } 62 | } 63 | for (int i = 0; i < L; ++i) { 64 | System.out.printf("%d ", tot[i]); 65 | } 66 | } 67 | } 68 | ``` 69 | === "Python 3" 70 | ```python linenums="1" 71 | n, m, L = map(int, input().strip().split()) 72 | a = [] 73 | for i in range(n): 74 | a.append(list(map(int, input().strip().split()))) 75 | tot = [0 for i in range(L)] 76 | for i in range(n): 77 | for j in range(m): 78 | tot[a[i][j]] += 1 79 | for i in range(L): 80 | print(tot[i], end=" ") 81 | ``` -------------------------------------------------------------------------------- /docs/problem/22/1/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: problem.html 3 | tags: 4 | - 模拟 5 | hide: 6 | - tags 7 | --- 8 | # 202104-1 灰度直方图 9 | 10 | ## 题目链接 11 | 12 | [202104-1 灰度直方图](http://118.190.20.162/view.page?gpid=T128) 13 | 14 | ## 思路列表 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 33 | 34 | 35 | 36 | 37 |
题解文章得分要求大致思路题解语言链接
文章 1100无特殊限制 32 | 模拟C++、Java、Python 3题解链接
38 | -------------------------------------------------------------------------------- /docs/problem/22/2/1.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: solution.html 3 | --- 4 | # 202104-2 邻域均值 5 | 6 | ## 70% 数据——直接模拟 7 | 8 | 按照题目要求,算出每个点的邻域均值,然后直接统计即可。 9 | 10 | 一共有 $\mathrm{O}(n^2)$ 个点,每个点统计复杂度 $\mathrm{O}(r^2)$,整体复杂度 $\mathrm{O}(n^2r^2)$。 11 | 12 | ## 100% 数据——由相邻邻域均值推导 13 | 14 | 为了简化说明及避免除法精度问题,我们可以将邻域均值是否小于等于 $t$ 转化为**邻域值的总和是否小于等于 $t$ 与元素合数之积**。 15 | 16 | 考虑在 70 分的做法中什么地方浪费了时间:在统计完一个点的邻域值的总和时,我们就抛弃了这个点的信息,完全重新计算其他点的邻域值的和。但对于相邻的点,其邻域有很大面积的重合,最多相差 $2r$ 个元素。 17 | 18 | 在原本的基础上,只需要处理这 $2r$ 个元素的更改即可。 19 | 20 | 考虑时间复杂度:算出第一个点的邻域值的和为 $\mathrm{O}(r^2)$,一共要进行 $n^2$ 次 $\mathrm{O}(r)$ 的修改,整体比较复杂度 $n^2$,最终复杂度 $\mathrm{O}(r^2+n^2r)$。 21 | 22 | 23 | ???+ success "代码实现" 24 | 25 | === "C++" 26 | ```cpp linenums="1" 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | using namespace std; 33 | const int maxn = 610; 34 | int n, L, r, t; 35 | int a[maxn][maxn], sum[maxn][maxn]; 36 | int ans; 37 | inline int getSum(int row1, int col1, int row2, int col2) { 38 | // 计算一块矩阵区间的和 39 | int res = 0; 40 | for (int i = row1; i <= row2; ++i) { 41 | for (int j = col1; j <= col2; ++j) { 42 | res += a[i][j]; 43 | } 44 | } 45 | return res; 46 | } 47 | inline int getSize(int x, int y) { 48 | // 计算 (x,y) 的邻域大小 49 | int row1 = max(x - r, 1), col1 = max(y - r, 1); 50 | int row2 = min(x + r, n), col2 = min(y + r, n); 51 | return (row2 - row1 + 1) * (col2 - col1 + 1); 52 | } 53 | int main() { 54 | scanf("%d%d%d%d", &n, &L, &r, &t); 55 | for (int i = 1; i <= n; ++i) { 56 | for (int j = 1; j <= n; ++j) { 57 | scanf("%d", &a[i][j]); 58 | } 59 | } 60 | 61 | // 求出 sum[1][1] 62 | sum[1][1] = getSum(1, 1, min(r + 1, n), min(r + 1, n)); 63 | // 求出 sum[1][2..n] 64 | for (int j = 2; j <= n; ++j) { 65 | sum[1][j] = sum[1][j - 1]; 66 | // 减去最左侧一部分 67 | if (j - 1 - r > 0) 68 | sum[1][j] -= getSum(1, j - 1 - r, min(r + 1, n), j - 1 - r); 69 | // 增加右侧一部分 70 | if (j + r <= n) 71 | sum[1][j] += getSum(1, j + r, min(r + 1, n), j + r); 72 | } 73 | 74 | // 计算剩下部分,sum[i][j] 由 sum[i-1][j] 转移而来 75 | for (int i = 2; i <= n; ++i) { 76 | for (int j = 1; j <= n; ++j) { 77 | sum[i][j] = sum[i - 1][j]; 78 | if (i - 1 - r > 0) 79 | sum[i][j] -= 80 | getSum(i - 1 - r, max(j - r, 1), i - 1 - r, min(j + r, n)); 81 | if (i + r <= n) 82 | sum[i][j] += getSum(i + r, max(j - r, 1), i + r, min(j + r, n)); 83 | } 84 | } 85 | 86 | // 统计答案 87 | for (int i = 1; i <= n; ++i) { 88 | for (int j = 1; j <= n; ++j) { 89 | if (sum[i][j] <= t * getSize(i, j)) 90 | ++ans; 91 | } 92 | } 93 | printf("%d", ans); 94 | return 0; 95 | } 96 | ``` 97 | 98 | ## 100% 数据——二维前缀和 99 | 100 | 对于多次询问一段区间的值,容易想到前缀和;如果多次询问二维区间的值,需要二维前缀和。 101 | 102 | 设 $S(x,y)= \sum\limits_{i=1}^{x}\sum\limits_{j=1}^{y}{a_{i,j}}$,则 $(x_1,y_1)$ 到 $(x_2,y_2)$ ($x_2\ge x_1, y_2\ge y_1$)的和可以表示为: 103 | 104 | $$S(x_2,y_2) - S(x_1 - 1, y_2) - S(x_2, y_1 - 1) + S(x_1 - 1, y_1 - 1)$$ 105 | 106 | 我们可以 $\mathrm{O}(n^2)$ 预处理出 $S(x,y)$ 数组,之后则可以 $\mathrm{O}(1)$ 查询单点邻域值的和了。总体时间复杂度 $\mathrm{O}(n^2)$。 107 | 108 | 109 | ???+ success "代码实现" 110 | 111 | === "C++" 112 | ```cpp linenums="1" 113 | #include 114 | #include 115 | #include 116 | #include 117 | #include 118 | using namespace std; 119 | const int maxn = 610; 120 | int n, L, r, t; 121 | int a[maxn][maxn], sum[maxn][maxn]; 122 | int ans; 123 | inline int getSize(int x, int y) { 124 | // 计算 (x,y) 的邻域大小 125 | int row1 = max(x - r, 1), col1 = max(y - r, 1); 126 | int row2 = min(x + r, n), col2 = min(y + r, n); 127 | return (row2 - row1 + 1) * (col2 - col1 + 1); 128 | } 129 | int main() { 130 | scanf("%d%d%d%d", &n, &L, &r, &t); 131 | for (int i = 1; i <= n; ++i) { 132 | for (int j = 1; j <= n; ++j) { 133 | scanf("%d", &a[i][j]); 134 | } 135 | } 136 | 137 | // 预处理前缀和数组 138 | for (int i = 1; i <= n; ++i) { 139 | for (int j = 1; j <= n; ++j) { 140 | sum[i][j] = 141 | sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + a[i][j]; 142 | } 143 | } 144 | 145 | // 统计答案 146 | for (int i = 1; i <= n; ++i) { 147 | for (int j = 1; j <= n; ++j) { 148 | int row1 = max(1, i - r), col1 = max(1, j - r); 149 | int row2 = min(n, i + r), col2 = min(n, j + r); 150 | int s = sum[row2][col2] - sum[row2][col1 - 1] - 151 | sum[row1 - 1][col2] + sum[row1 - 1][col1 - 1]; 152 | if (s <= t * getSize(i, j)) 153 | ++ans; 154 | } 155 | } 156 | printf("%d", ans); 157 | return 0; 158 | } 159 | ``` -------------------------------------------------------------------------------- /docs/problem/22/2/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: problem.html 3 | tags: 4 | - 模拟 5 | - 前缀和 6 | hide: 7 | - tags 8 | --- 9 | # 202104-2 邻域均值 10 | 11 | ## 题目链接 12 | 13 | [202104-2 邻域均值](http://118.190.20.162/view.page?gpid=T127) 14 | 15 | ## 思路列表 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 50 | 51 | 52 | 53 | 54 |
题解文章得分要求大致思路题解语言链接
文章 170n≤100,r≤10 33 | 直接模拟题解链接
文章 1100无特殊限制 41 | 由相邻邻域均值推导C++题解链接
文章 1100无特殊限制 49 | 二维前缀和C++题解链接
55 | -------------------------------------------------------------------------------- /docs/problem/22/3/1.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: solution.html 3 | --- 4 | # 202104-3 DHCP服务器 5 | 6 | ## 100% 数据——模拟 7 | 8 | 模拟过程即可,具体过程参考代码注释。 9 | 10 | 11 | ???+ success "代码实现" 12 | 13 | === "C++" 14 | 15 | ```cpp linenums="1" 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #define ll long long 26 | using namespace std; 27 | const int maxn = 10010; 28 | int n, T; 29 | ll Tdef, Tmax, Tmin; 30 | map NameToID; 31 | int cnt; 32 | string Name[maxn]; 33 | string sender, receiver, type; 34 | int rTime, rIP, rOverdue; 35 | bool Illegal() { 36 | // 遇到这些情况,不处理 37 | if (receiver != Name[1] && receiver != "*" && type != "REQ") 38 | // 接收主机为本机或 *,但类型不是 Request 39 | return true; 40 | if (type != "REQ" && type != "DIS") 41 | // 类型不是 Discover 或 Request 42 | return true; 43 | if (type == "DIS" && receiver == Name[1]) 44 | // 接收主机是本机,且类型为 Discover 45 | return true; 46 | if (type != "DIS" && receiver == "*") 47 | // 接收主机为 *,且类型不是 Discover 48 | return true; 49 | return false; 50 | } 51 | enum IPState { 52 | // 描述某个 IP 的状态 53 | NOT_DISTRIBUTED, // 未分配 54 | READY_FOR_DISTRIBUTION, // 待分配 55 | DISTRIBUTED, // 占用 56 | OVERDUE // 过期 57 | }; 58 | struct IP { 59 | IPState state; 60 | int owner; 61 | int overdue; 62 | IP() { 63 | state = NOT_DISTRIBUTED; 64 | owner = 0; 65 | overdue = 0; 66 | } 67 | } ip[maxn]; 68 | int NumOfIP; 69 | int IPHeld[maxn]; 70 | int distributeIP(int owner) { 71 | // 为发送主机分配地址 72 | // 发送主机有 IP,直接返回 73 | if (IPHeld[owner]) { 74 | return IPHeld[owner]; 75 | } 76 | // 否则,寻找最小状态为未分配的 IP 地址 77 | for (int i = 1; i <= n; ++i) { 78 | if (ip[i].state == READY_FOR_DISTRIBUTION && ip[i].overdue <= rTime) { 79 | // 待分配 IP 到期变为未分配 80 | ip[i].state = NOT_DISTRIBUTED; 81 | ip[i].overdue = 0; 82 | IPHeld[ip[i].owner] = 0; 83 | ip[i].owner = 0; 84 | } 85 | if (ip[i].state == NOT_DISTRIBUTED) { 86 | return i; 87 | } 88 | } 89 | // 否则,寻找最小状态为过期的 IP 地址 90 | for (int i = 1; i <= n; ++i) { 91 | if (ip[i].state == DISTRIBUTED && ip[i].overdue <= rTime) { 92 | // 已分配 IP 过期变为过期 IP 93 | ip[i].state = OVERDUE; 94 | ip[i].overdue = 0; 95 | } 96 | if (ip[i].state == OVERDUE) { 97 | return i; 98 | } 99 | } 100 | // 否则,不处理该报文 101 | return 0; 102 | } 103 | void receiveDiscover() { 104 | // 接收到 Discover 报文 105 | int s = NameToID[sender]; 106 | int curIP = distributeIP(s); 107 | if (!curIP) // 分配失败,不处理 108 | return; 109 | ip[curIP].state = READY_FOR_DISTRIBUTION; // IP 设为待分配 110 | IPHeld[ip[curIP].owner] = 0; // 原本占用的主机不在占用 111 | IPHeld[s] = curIP; // 记录发送主机持有的 IP 112 | ip[curIP].owner = s; // 标记该 IP 被发送主机持有 113 | // 设置过期时刻 114 | if (rOverdue == 0) 115 | ip[curIP].overdue = rTime + Tdef; 116 | else { 117 | if (rOverdue < rTime + Tmin) { 118 | ip[curIP].overdue = rTime + Tmin; 119 | } else if (rOverdue > rTime + Tmax) { 120 | ip[curIP].overdue = rTime + Tmax; 121 | } else { 122 | ip[curIP].overdue = rOverdue; 123 | } 124 | } 125 | // 向主机发送 Offer 报文 126 | cout << Name[1] << " " << Name[s] << " OFR " << curIP << " " 127 | << ip[curIP].overdue << "\n"; 128 | } 129 | void receiveRequest() { 130 | // 接收到 Request 报文 131 | int s = NameToID[sender]; 132 | // 不是本机 133 | if (receiver != Name[1]) { 134 | if (IPHeld[s] && ip[IPHeld[s]].state == READY_FOR_DISTRIBUTION) { 135 | ip[IPHeld[s]].state = NOT_DISTRIBUTED; 136 | ip[IPHeld[s]].overdue = 0; 137 | ip[IPHeld[s]].owner = 0; 138 | IPHeld[s] = 0; 139 | } 140 | return; 141 | } 142 | // 更新发送主机持有的 IP 的状态 143 | if (IPHeld[s] && ip[IPHeld[s]].overdue <= rTime) { 144 | if (ip[IPHeld[s]].state == READY_FOR_DISTRIBUTION) { 145 | ip[IPHeld[s]].state = NOT_DISTRIBUTED; 146 | ip[IPHeld[s]].owner = 0; 147 | ip[IPHeld[s]].overdue = 0; 148 | IPHeld[s] = 0; 149 | } else if (ip[IPHeld[s]].state == DISTRIBUTED) { 150 | ip[IPHeld[s]].state = OVERDUE; 151 | ip[IPHeld[s]].overdue = 0; 152 | } 153 | } 154 | // 检查 IP 是否在池内且占有者是发送主机 155 | if (!IPHeld[s] || IPHeld[s] != rIP) { 156 | cout << Name[1] << " " << Name[s] << " NAK " << rIP << " " << 0 << "\n"; 157 | return; 158 | } 159 | // IP 地址状态设为占用 160 | ip[rIP].state = DISTRIBUTED; 161 | // 设置过期时刻 162 | if (rOverdue == 0) 163 | ip[rIP].overdue = rTime + Tdef; 164 | else { 165 | if (rOverdue < rTime + Tmin) { 166 | ip[rIP].overdue = rTime + Tmin; 167 | } else if (rOverdue > rTime + Tmax) { 168 | ip[rIP].overdue = rTime + Tmax; 169 | } else { 170 | ip[rIP].overdue = rOverdue; 171 | } 172 | } 173 | // 向主机发送 ACK 报文 174 | cout << Name[1] << " " << Name[s] << " ACK " << rIP << " " 175 | << ip[rIP].overdue << "\n"; 176 | } 177 | int main() { 178 | // 读入数据,其中 Name[1] 是本机名称,本机编号为 1 179 | cin >> n >> Tdef >> Tmax >> Tmin >> Name[1]; 180 | NameToID[Name[1]] = ++cnt; 181 | scanf("%d", &T); 182 | while (T--) { 183 | cin >> rTime >> sender >> receiver >> type >> rIP >> rOverdue; 184 | if (!NameToID.count(sender)) { 185 | NameToID[sender] = ++cnt; 186 | Name[cnt] = sender; 187 | } 188 | if (Illegal()) 189 | continue; 190 | if (type == "REQ") 191 | receiveRequest(); 192 | else if (type == "DIS") 193 | receiveDiscover(); 194 | } 195 | return 0; 196 | } 197 | ``` -------------------------------------------------------------------------------- /docs/problem/22/3/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: problem.html 3 | tags: 4 | - 模拟 5 | hide: 6 | - tags 7 | --- 8 | # 202104-3 DHCP服务器 9 | 10 | ## 题目链接 11 | 12 | [202104-3 DHCP服务器](http://118.190.20.162/view.page?gpid=T126) 13 | 14 | ## 思路列表 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 33 | 34 | 35 | 36 | 37 |
题解文章得分要求大致思路题解语言链接
文章 1100无特殊限制 32 | 模拟C++题解链接
38 | -------------------------------------------------------------------------------- /docs/problem/22/4/1.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: solution.html 3 | --- 4 | # 202104-4 校门外的树 5 | 6 | ## 10% 数据——输出真因子个数 7 | 8 | $n = 2$ 时只有一个区间 $[a_1,a_2]$。 9 | 10 | 设 $d = a_2 - a_1$,答案即为 $d$ 的真因子个数。 11 | 12 | ## 30% 数据——搜索 13 | 14 | 按照题目要求,有两种美观区间: 15 | 16 | - 区间 $[a_l,a_r]$ 内中的树构成等差数列,且树集合中不含有其他 $a_i$; 17 | - 区间 $[a_l,a_r]$ 内存在 $a_m$,满足 $[a_l,a_m]$ 和 $[a_m,a_r]$ 都是美观区间; 18 | 19 | 为了方便描述,称第一种为**一型美观区间**,称第二种为**二型美观区间**。 20 | 21 | 容易想到的一种方法是,通过搜索去判断每一个区间的类型: 22 | 23 | - 对于一型美观区间,我们枚举每个因子,判断其是否会与障碍物重合; 24 | - 对于二型美观区间,我们枚举中间点,将左右区间结果相乘即可。 25 | 26 | 但是当处理二型美观区间的时候,可能会出现这样的问题: 27 | 28 | ???+ example "例子" 29 | 假设要在 $a_1,a_2,a_3,a_4$ 种树,求 $[a_1,a_4]$ 是美观区间的方案数。 30 | 31 | 在枚举 $[a_1,a_4]$ 的二型美观区间中间点的时候,会出现两种划分方式: 32 | 33 | 1. $[a_1,a_3]$ 是二型美观区间,$[a_3,a_4]$ 是一型美观区间。其中在 $[a_1,a_3]$ 是二型美观区间的搜索中,会出现 $[a_1,a_2]$ 和 $[a_2,a_3]$ 是一型美观区间的情况。 34 | 2. $[a_1,a_2]$ 是一型美观区间,$[a_2,a_4]$ 是二型美观区间。其中在 $[a_2,a_4]$ 是二型美观区间的搜索中,会出现 $[a_2,a_3]$ 和 $[a_3,a_4]$ 是一型美观区间的情况。 35 | 36 | 在两种划分方式中,都出现了 $[a_1,a_2]$,$[a_2,a_3]$ 和 $[a_3,a_4]$ 都是一型美观区间的情况,导致重复计数。 37 | 38 | 从另一个角度来看,二型美观区间就是由许多一型美观区间拼接而来,我们只需要考虑一型美观区间即可,所以任务转变为**选取一些一型美观区间,拼凑出整个区间**。上述方法的错误点在枚举了重复的子集,我们思考该如何枚举。 39 | 40 | 一种朴实无华的方法是,枚举所有的区间端点情况。 41 | 42 | 思考时间复杂度:设 $\max\{a\}=A$,枚举所有端点情况 $\mathrm{O}(2^n)$,每个情况需要计算 $\mathrm{O}(n)$ 段一型美观区间,计算一个区间的复杂度是 $\mathrm{O}(nd(A))$,其中 $d(x)$ 表示 $x$ 的真因子个数,在 $x=83160$ 时取到最大值 $127$。至于所有真因子的计算,我们可以预处理完成。复杂度 $\mathrm{O}(A\sqrt A)$。最终整体复杂度 $\mathrm{O}(A\sqrt A+2^nnd(x))$。 43 | 44 | ## 60% 数据——动态规划 45 | 46 | 枚举所有的端点情况不现实了。 47 | 48 | 我们不妨换个角度,再思考上个错误的做法:我们枚举了重复的子集。换句话说,对于一个特定的状态,它映射到了多种美观区间的组合。如果能做到**一个状态唯一对应一种美观区间**,那么问题就解决了。 49 | 50 | 由于美观区间都是由一些一型美观区间拼接而成的,所以可以进行这样对应: 51 | 52 | - 如果美观区间包含一个一型美观区间,则对应一个一型美观区间; 53 | - 如果美观区间包含两个一型美观区间,则对应两个一型美观区间; 54 | - 如果美观区间包含 $n(n\ge 3)$ 个一型美观区间,则第 $[1,n-1]$ 区间对应一个二型美观区间,第 $n$ 个区间对应一个一型美观区间。 55 | 56 | 注:以上只是一种对应方案,对应方案不唯一。 57 | 58 | 在确定划分方案后,考虑如何计数。不妨设 $f(i)$ 表示区间 $[a_1,a_i]$ 是美观区间的方案数,$g(i,j)$ 表示区间 $[a_i,a_j]$ 是一型美观区间的方案数,那么可以得到转移方程: 59 | 60 | $$f(i)=\sum\limits_{j=1}^{i-1}{f(j)\cdot g(j,i)}$$ 61 | 62 | 考虑时间复杂度:状态转移 $\mathrm{O}(n^2)$,计算 $g(i,j)$ 复杂度 $\mathrm{O}(nd(A))$,预处理所有因子 $\mathrm{O}(A\sqrt A)$,整体复杂度 $\mathrm{O}(A\sqrt A+n^3d(A))$。如果不预处理所有因子,而是直接计算的话,复杂度 $\mathrm{O}(n^3\sqrt A)$。 63 | 64 | ## 100% 数据——优化一型美观区间方案数的计算 65 | 66 | 思考哪一步浪费了时间:设 $i 89 | ???+ success "代码实现" 90 | 91 | === "C++" 92 | ```cpp linenums="1" 93 | #include 94 | #include 95 | #include 96 | #include 97 | #include 98 | #include 99 | #include 100 | using namespace std; 101 | #define ll long long 102 | #define il inline 103 | const int maxn = 1010; 104 | const ll mod = 1e9 + 7; 105 | int n; 106 | int a[maxn]; 107 | ll f[maxn]; 108 | set st; 109 | vector fac[100010]; 110 | int g(int l, int r) { 111 | int d = a[r] - a[l]; 112 | int res = 0; 113 | st.insert(d); // 将本身加入 114 | for (int i = 0; i < fac[d].size(); ++i) { 115 | if (!st.count(fac[d][i])) { 116 | // 如果因子没有被统计过,说明在本区间是合法的 117 | // 同时,这也导致包含该区间的更大区间是非法的 118 | st.insert(fac[d][i]); 119 | ++res; 120 | } 121 | } 122 | return res; 123 | } 124 | void init() { 125 | // 预处理,求出所有的真因子 126 | for (int i = 1; i <= 50000; ++i) { 127 | for (int j = 2; i * j <= 100000; ++j) { 128 | fac[i * j].push_back(i); 129 | } 130 | } 131 | } 132 | int main() { 133 | init(); 134 | scanf("%d", &n); 135 | for (int i = 1; i <= n; ++i) { 136 | scanf("%d", &a[i]); 137 | } 138 | f[1] = 1; 139 | for (int i = 2; i <= n; ++i) { 140 | st.clear(); 141 | for (int j = i - 1; j >= 1; --j) { // 区间从小到大 142 | f[i] = (f[i] + f[j] * g(j, i) % mod) % mod; 143 | } 144 | } 145 | printf("%lld", f[n]); 146 | return 0; 147 | } 148 | ``` -------------------------------------------------------------------------------- /docs/problem/22/4/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: problem.html 3 | tags: 4 | - 动态规划 5 | hide: 6 | - tags 7 | --- 8 | # 202104-4 校门外的树 9 | 10 | ## 题目链接 11 | 12 | [202104-4 校门外的树](http://118.190.20.162/view.page?gpid=T125) 13 | 14 | ## 思路列表 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 57 | 58 | 59 | 60 | 61 |
题解文章得分要求大致思路题解语言链接
文章 110n=2 32 | 输出真因子个数题解链接
文章 130n≤10 40 | 搜索题解链接
文章 160n≤100,ai≤1000 48 | 动态规划题解链接
文章 1100无特殊限制 56 | 优化一型美观区间方案数的计算C++题解链接
62 | -------------------------------------------------------------------------------- /docs/problem/22/5/1.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: solution.html 3 | --- 4 | # 202104-5 疫苗运输 5 | 6 | ## 10% 数据——按照路线遍历即可 7 | 8 | 因为只有一条线路,我们可以这样做: 9 | 10 | 1. 得到车到 1 站点的时间 $s$,若无法到达,则所有站点都是 inf; 11 | 2. 从 1 站点出发,计算该线路上到其他站点的时间。 12 | -------------------------------------------------------------------------------- /docs/problem/22/5/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: problem.html 3 | --- 4 | # 202104-5 疫苗运输 5 | 6 | ## 题目链接 7 | 8 | [202104-5 疫苗运输](http://118.190.20.162/view.page?gpid=T124) 9 | 10 | ## 思路列表 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
题解文章得分要求大致思路题解语言链接
26 | -------------------------------------------------------------------------------- /docs/problem/22/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: contest.html 3 | --- 4 | # 第 22 次(2021 年 4 月) 5 | 6 | 7 | | 题目编号 | 题目名称 | 涉及算法 | 最高得分 | 满分题解语言 | 链接 | 8 | | :-: | :-: | :-: | :-: | :-: | :-: | 9 | | 202104-1 | 灰度直方图 | 模拟 | 100 | C++、Java、Python 3 | [链接](1\index.md) | 10 | | 202104-2 | 邻域均值 | 模拟、前缀和 | 100 | C++ | [链接](2\index.md) | 11 | | 202104-3 | DHCP服务器 | 模拟 | 100 | C++ | [链接](3\index.md) | 12 | | 202104-4 | 校门外的树 | 动态规划 | 100 | C++ | [链接](4\index.md) | 13 | | 202104-5 | 疫苗运输 | | | | [链接](5\index.md) | 14 | -------------------------------------------------------------------------------- /docs/problem/23/1/1.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: solution.html 3 | --- 4 | # 202109-1 数组推导 5 | 6 | ## 100% 数据——模拟 7 | 8 | $B$ 数组是 $A$ 数组的前缀最大值,所以 $B$ 必定是单调不降的。 9 | 10 | 考虑 $B$ 数组中相邻元素之间的关系,推测 $A$ 数组中的元素值范围: 11 | 12 | 1. $B_1=A_1$; 13 | 2. 若 $B_i\not=B_{i-1}(i\ge 2)$,说明前缀最大值在第 $i$ 个位置发生了改变; 14 | 考虑 $A_i$:若 $A_i \le B_{i-1}$ 则 $B_i$ 不会发生变化,若 $A_i > B_{i-1}$ 且 $A_i\not=B_i$ 则 $B_i=A_i$ 矛盾,所以此时 $B_i=A_i$; 15 | 3. 若 $B_i=B_{i-1}(i\ge 2)$,说明前缀最大值在 $i$ 处没有改变,结合上面的分析我们可以得到 $A_i \in [0, B_{i-1}]$。因为 $B_{i-1}=B_i$,所以也可以写为 $A_i \in [0, B_{i}]$。 16 | 17 | 综合以上分析,只有在 $B_{i}=B_{i-1}(i\ge 2)$ 时,$A_i$ 的值是不确定的。 18 | 要求最大最小值,只要令不确定的 $A_i=0$ 或 $A_i=B_{i}$ 即可。 19 | 20 | 21 | 22 | ???+ success "代码实现" 23 | 24 | === "C++" 25 | ```cpp linenums="1" 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | using namespace std; 32 | #define ll long long 33 | #define il inline 34 | const int maxn = 110; 35 | int a[maxn], b[maxn]; 36 | int n; 37 | int sum; 38 | int main() { 39 | scanf("%d", &n); 40 | for (int i = 1; i <= n; ++i) { 41 | scanf("%d", &b[i]); 42 | } 43 | // 计算最大值:满足 a[i]=b[i] 44 | sum = 0; 45 | for (int i = 1; i <= n; ++i) 46 | sum += b[i]; 47 | printf("%lld\n", sum); 48 | // 计算最小值:在变化时 a[i]=b[i],其余为 0 49 | sum = 0; 50 | for (int i = 1; i <= n; ++i) { 51 | if (i == 1 || b[i] != b[i - 1]) 52 | sum += b[i]; 53 | } 54 | printf("%d\n", sum); 55 | return 0; 56 | } 57 | ``` 58 | === "Java" 59 | ```java linenums="1" 60 | import java.util.Scanner; 61 | public class Main { 62 | public static void main(String[] args) { 63 | Scanner input = new Scanner(System.in); 64 | int n = input.nextInt(); 65 | int maxval = 0, minval = 0; 66 | int b[] = new int[n + 1]; 67 | for (int i = 1; i <= n; ++i) { 68 | b[i] = input.nextInt(); 69 | maxval += b[i]; 70 | if (b[i] != b[i - 1]) 71 | minval += b[i]; 72 | } 73 | input.close(); 74 | System.out.println(maxval); 75 | System.out.println(minval); 76 | } 77 | } 78 | ``` 79 | === "Python 3" 80 | ```python linenums="1" 81 | n = int(input()) 82 | b = list(map(int, input().strip().split())) 83 | minval = 0 84 | maxval = 0 85 | for i in range(n): 86 | maxval += b[i] 87 | if b[i] != b[i-1]: 88 | minval += b[i] 89 | print(maxval) 90 | print(minval) 91 | ``` 92 | 93 | -------------------------------------------------------------------------------- /docs/problem/23/1/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: problem.html 3 | tags: 4 | - 模拟 5 | hide: 6 | - tags 7 | --- 8 | # 202109-1 数组推导 9 | 10 | ## 题目链接 11 | 12 | [202109-1 数组推导](http://118.190.20.162/view.page?gpid=T129) 13 | 14 | ## 思路列表 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 33 | 34 | 35 | 36 | 37 |
题解文章得分要求大致思路题解语言链接
文章 1100无特殊限制 32 | 模拟C++题解链接
38 | -------------------------------------------------------------------------------- /docs/problem/23/2/1.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: solution.html 3 | --- 4 | # 202109-2 非零段划分 5 | 6 | ## 70% 数据——模拟 7 | 8 | 题目中说明 $A_i\in[0, 10000]$。当 $p>10000$ 后,$A$ 数组则成为全 $0$ 数组, 9 | 所以我们只需考虑 $k\in[1, 10000]$ 时的非零段个数,不妨设 $m=10000$。 10 | 11 | 我们可以针对每一个 $p$,计算出 $A$ 数组的情况,进而计算非零段的个数,不断更新答案。 12 | 在维护 $A$ 数组的时候,我们可以让 $p$ 递增更新。 13 | 这样在 $p$ 更新的时候,只需要将 $A_i=p-1$ 处更新为 $0$ 即可。 14 | 15 | 时间复杂度 $\mathrm{O}(nm)$。 16 | 17 | ## 100% 数据——避免不必要更新 18 | 19 | 在上个做法中,时间主要浪费在了对 $A$ 数组的更新与重复计算非零段上。 20 | 对于每一个非零 $A_i$,随着 $p$ 逐渐增大,其最多改变一次,即变为 $0$。 21 | 而在上面的方法中,我们忽略了这个条件,每次都对所有的元素进行检查,无论其是否为 $0$。 22 | 23 | 考虑每个 $A_i$ 变为 $0$ 时对非零段个数的贡献。 24 | 为了简化后续讨论,这里给出一个推论: 25 | 26 | !!! note "相邻相等元素与单个元素等价" 27 | 对于一段值相同的区间,可以把它们看做成其中任意的一个元素。 28 | 29 | 这一点很好理解:既然值相同,那么这一段在变为 $0$ 时必然是同时改变。 30 | 31 | 通过以上推论,我们先缩小 $A$ 数组的元素个数,直到任意相邻两个元素都不同,之后考虑每个元素对整体的贡献。 32 | 只看元素本身看不出什么,一种思路是查看与之相邻的两个元素。 33 | 34 |
35 | ![相邻元素的四种情况](image/1-conditions.png){ width="300" } 36 |
图 1:相邻元素的四种情况
37 |
38 | 39 | 如图,红色点代表将要变为 $0$ 的元素,蓝色点为相邻两个元素;黑线以下为目前变为 $0$ 的元素。我们对以上四种情况进行分类讨论: 40 | 41 | 1. 当左右相邻元素均大于中间元素时:当中间元素变为 $0$ 时,原本一个非零段分成了两个非零段,对非零段个数贡献 $+1$; 42 | 2. 当左右相邻元素均小于中间元素时:当中间元素变为 $0$ 之前,左右元素均已变成 $0$,中间元素是孤立的非零段,在中间元素变为 $0$ 后,非零段个数减少,对非零段个数贡献 $-1$; 43 | 3. 其他两种情况:相当于某个非零段的边界去掉了一个元素,对非零段个数无影响。 44 | 45 | 针对边界元素而言,可以将其缺失的相邻元素视为 $0$。 46 | 47 | 同时,考虑到我们只需要求解非零段的个数,并不需要输出对应 $A$ 数组的状态,我们可以将每个元素的贡献(当然只有在对应 $p=A_{i}+1$ 时才会有贡献)累加,成为每个 $p$ 对应的贡献。 48 | 这样我们就可以先求出初始状态的非零段个数,之后随着 $p$ 增加利用之前求出的贡献进行更新,就可以比较快速地解决。 49 | 50 | 求出每个元素的贡献、并累加到对应 $p$ 的复杂度为 $\mathrm{O}(n)$,计算每一个 $p$ 的最后贡献的复杂度为 $\mathrm{O}(m)$,整体复杂度 $\mathrm{O}(n+m)$。 51 | 52 | 53 | 54 | ???+ success "代码实现" 55 | 56 | === "C++" 57 | 58 | ```cpp linenums="1" 59 | #include 60 | #include 61 | #include 62 | #include 63 | #include 64 | using namespace std; 65 | const int maxn = 500010; 66 | const int maxm = 10010; 67 | int n; 68 | int a[maxn]; 69 | int sum[maxm]; 70 | // sum[i] 表示 p = i 时的贡献 71 | // 注意当 a[i] 发生变化时,p = a[i] + 1 72 | int main() { 73 | scanf("%d", &n); 74 | for (int i = 1; i <= n; ++i) { 75 | scanf("%d", &a[i]); 76 | } 77 | // 去掉数组中相同元素段 78 | int tot = 0; 79 | a[++tot] = a[1]; 80 | for (int i = 2; i <= n; ++i) { 81 | if (a[i] == a[i - 1]) 82 | continue; 83 | a[++tot] = a[i]; 84 | } 85 | n = tot; 86 | // 对非两侧元素进行处理 87 | for (int i = 2; i < n; ++i) { 88 | if (a[i] < a[i - 1] && a[i] < a[i + 1]) { 89 | // 中间小两侧大,贡献 +1 90 | ++sum[a[i] + 1]; 91 | } 92 | if (a[i] > a[i - 1] && a[i] > a[i + 1]) { 93 | // 中间大两侧小,贡献 -1 94 | --sum[a[i] + 1]; 95 | } 96 | } 97 | // 处理两侧元素 98 | if (n > 1 && a[1] > a[2]) 99 | --sum[a[1] + 1]; 100 | if (n > 1 && a[n] > a[n - 1]) 101 | --sum[a[n] + 1]; 102 | // 计算初始情况 p = 1 时的非零段数 cur 103 | int cur = 0; 104 | for (int i = 1; i <= n; ++i) { 105 | if (a[i] == 0 && a[i - 1] != 0) 106 | ++cur; 107 | } 108 | if (a[n]) 109 | ++cur; 110 | // 计算并得到最大的非零段数 111 | int ans = cur; 112 | for (int i = 2; i <= 10001; ++i) { 113 | cur += sum[i]; 114 | if (cur > ans) { 115 | ans = cur; 116 | } 117 | } 118 | printf("%d", ans); 119 | return 0; 120 | } 121 | ``` -------------------------------------------------------------------------------- /docs/problem/23/2/image/1-conditions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CCF-CSP-Project/CSP-Project-with-MkDocs/303ed90bb1247e0e1a26b320b0c8fa40881b6723/docs/problem/23/2/image/1-conditions.png -------------------------------------------------------------------------------- /docs/problem/23/2/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: problem.html 3 | tags: 4 | - 模拟 5 | hide: 6 | - tags 7 | --- 8 | # 202109-2 非零段划分 9 | 10 | ## 题目链接 11 | 12 | [202109-2 非零段划分](http://118.190.20.162/view.page?gpid=T130) 13 | 14 | ## 思路列表 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 41 | 42 | 43 | 44 | 45 |
题解文章得分要求大致思路题解语言链接
文章 170n≤1000 32 | 模拟题解链接
文章 1100无特殊限制 40 | 避免不必要更新C++题解链接
-------------------------------------------------------------------------------- /docs/problem/23/3/1.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: solution.html 3 | --- 4 | # 202109-3 脉冲神经网络 5 | 6 | ## 70% 数据——模拟 7 | 8 | 先不考虑具体时间复杂度,思考朴素做法应该怎么做: 9 | 10 | 1. 枚举 $[0,T]$ 每个时刻,这里应为一个外层循环; 11 | 2. 对脉冲源进行处理:通过 $r$ 参数判断是否会发射脉冲; 12 | 3. 对神经元进行处理:通过 $v_k$ 判断是否会发射脉冲;如果发射脉冲,则更新 $u_k,v_k$。 13 | 14 | 判断脉冲源是否发射脉冲相对容易。但对于神经元来说,由于传播延迟的存在,我们需要知道 $I_k$, 15 | 即神经元在 $k$ 时刻接收到所有脉冲输入的强度之和。 16 | 又由于每个神经元是否发射脉冲是互相独立的,我们需要知道**每个神经元**在**每个时刻**接收到的脉冲和。 17 | 18 | 一种思路是开一个 $\mathrm{O}(NT)$ 的二维数组来记录。由于空间大小的限制,我们只能通过 $70%$ 数据。 19 | 20 | 再来考虑时间复杂度:枚举时刻是 $\mathrm{O}(T)$,枚举脉冲、神经元及发射脉冲需要 $\mathrm{O}(N+S+P)$, 21 | 整体复杂度 $\mathrm{O}(T(N+S+P))$,可以通过所有的数据。 22 | 23 | ## 100% 数据——滚动数组优化 24 | 25 | 为了得到满分,目前的任务是缩小记录每个神经元 $I_k$ 的空间复杂度。 26 | 27 | !!! note "提示" 28 | 题目给出的量的大小一般都是有用的。如果没有思路时,可以从这些貌似“没用”的量上进行突破,比如本题的 $D$。 29 | 30 | 考虑耗费空间的位置:虽然有传播延迟 $d$ 的存在,但在某个时刻 $t$, 31 | 能影响到神经元 $I_k$ 的时刻范围在 $[t, t+\max\{d\}]$ 范围内。 32 | 一方面,对于 $k>t+\max\{d\}$ 的 $I_k$ 我们没必要记录,因为不会有脉冲对其造成影响; 33 | 另一方面,对于 $k 50 | 51 | ???+ success "代码实现" 52 | 53 | === "C++" 54 | 55 | ```cpp linenums="1" 56 | #include 57 | #include 58 | #include 59 | #include 60 | #include 61 | #include 62 | using namespace std; 63 | const int maxn = 1010; 64 | const int maxD = 1010; 65 | 66 | // 如果使用原题的 next 可能会 CE,这里改成 nxt 67 | static unsigned long nxt = 1; 68 | /* RAND_MAX assumed to be 32767 */ 69 | int myrand(void) { 70 | nxt = nxt * 1103515245 + 12345; 71 | return ((unsigned)(nxt / 65536) % 32768); 72 | } 73 | 74 | int N, S, P, T; 75 | double dt; 76 | // 脉冲源只需要 r 参数即可 77 | int r[maxn]; 78 | 79 | // 神经元 80 | struct Neuron { 81 | double v, u, a, b, c, d; 82 | int activate_times; 83 | } neuron[maxn << 1]; 84 | 85 | // 突触 86 | struct Synapse { 87 | int s, t; 88 | double w; 89 | int D; 90 | } synapse[maxn << 1]; 91 | 92 | // 存图 93 | vector G[maxn << 1]; 94 | // 存储每个时刻每个节点的 Ik 值 95 | double I[maxD][maxn]; 96 | 97 | int main() { 98 | scanf("%d%d%d%d", &N, &S, &P, &T); 99 | scanf("%lf", &dt); 100 | int cur = 0, rn; 101 | double ru, rv, ra, rb, rc, rd; 102 | while (cur < N) { 103 | scanf("%d", &rn); 104 | scanf("%lf%lf%lf%lf%lf%lf", &rv, &ru, &ra, &rb, &rc, &rd); 105 | while (rn--) { 106 | neuron[cur].v = rv; 107 | neuron[cur].u = ru; 108 | neuron[cur].a = ra; 109 | neuron[cur].b = rb; 110 | neuron[cur].c = rc; 111 | neuron[cur].d = rd; 112 | neuron[cur].activate_times = 0; 113 | ++cur; 114 | } 115 | } 116 | for (int i = 0; i < P; ++i) { 117 | scanf("%d", &r[i]); 118 | } 119 | for (int i = 0; i < S; ++i) { 120 | scanf("%d%d", &synapse[i].s, &synapse[i].t); 121 | scanf("%lf", &synapse[i].w); 122 | scanf("%d", &synapse[i].D); 123 | // 连边 124 | G[synapse[i].s].push_back(i); 125 | } 126 | 127 | // 按时间递增 128 | for (int t = 0; t < T; ++t) { 129 | // 滚动数组清零 130 | for (int i = 0; i < N; ++i) { 131 | I[(t - 1 + maxD) % maxD][i] = 0; 132 | } 133 | // 脉冲源 134 | for (int i = 0; i < P; ++i) { 135 | if (r[i] > myrand()) { 136 | // 脉冲激发 137 | for (int j = 0; j < G[N + i].size(); ++j) { 138 | Synapse tmps = synapse[G[N + i][j]]; 139 | I[(t + tmps.D) % maxD][tmps.t] += tmps.w; 140 | } 141 | } 142 | } 143 | // 神经元 144 | for (int i = 0; i < N; ++i) { 145 | double u = neuron[i].u, v = neuron[i].v; 146 | neuron[i].v = 147 | v + dt * (0.04 * v * v + 5 * v + 140 - u) + I[t % maxD][i]; 148 | neuron[i].u = u + dt * neuron[i].a * (neuron[i].b * v - u); 149 | if (neuron[i].v >= 30) { 150 | // 脉冲激发 151 | neuron[i].v = neuron[i].c; 152 | neuron[i].u += neuron[i].d; 153 | ++neuron[i].activate_times; 154 | for (int j = 0; j < G[i].size(); ++j) { 155 | Synapse tmps = synapse[G[i][j]]; 156 | I[(t + tmps.D) % maxD][tmps.t] += tmps.w; 157 | } 158 | } 159 | } 160 | } 161 | 162 | // 输出结果 163 | double minv = 1e18, maxv = -1e18; 164 | int mint = 1e9, maxt = 0; 165 | for (int i = 0; i < N; ++i) { 166 | if (neuron[i].v < minv) 167 | minv = neuron[i].v; 168 | if (neuron[i].v > maxv) 169 | maxv = neuron[i].v; 170 | if (mint > neuron[i].activate_times) 171 | mint = neuron[i].activate_times; 172 | if (maxt < neuron[i].activate_times) 173 | maxt = neuron[i].activate_times; 174 | } 175 | printf("%.3lf %.3lf\n%d %d", minv, maxv, mint, maxt); 176 | return 0; 177 | } 178 | ``` -------------------------------------------------------------------------------- /docs/problem/23/3/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: problem.html 3 | tags: 4 | - 模拟 5 | - 滚动数组 6 | hide: 7 | - tags 8 | --- 9 | # 202109-3 脉冲神经网络 10 | 11 | ## 题目链接 12 | 13 | [202109-3 脉冲神经网络](http://118.190.20.162/view.page?gpid=T131) 14 | 15 | ## 思路列表 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 42 | 43 | 44 | 45 | 46 |
题解文章得分要求大致思路题解语言链接
文章 170N×T≤106 33 | 模拟题解链接
文章 1100无特殊限制 41 | 滚动数组优化C++题解链接
-------------------------------------------------------------------------------- /docs/problem/23/4/1.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: solution.html 3 | --- 4 | # 202109-4 收集卡牌 5 | 6 | ## 20% 数据——搜索 7 | 8 | 对于这种需要枚举状态的期望类问题,我们可以直接深搜解决。一般而言,搜索有两种方式: 9 | 10 | 1. 正推。考虑从一个状态出发能够推及到的状态,在递归终点时对答案进行更新,也可以选择将值回传给上个状态。 11 | 2. 逆推。考虑一个状态能从哪几个后继状态转移而来,先递归到终点,再逐渐返回更新。 12 | 13 | 对于本题而言,笔者认为**逆推**相对容易实现。 14 | 15 | ### 正推 16 | 17 | 考虑需要维护的状态量: 18 | 19 | 1. 目前抽了几次卡 $cost$,用来计算期望; 20 | 2. 转移到某个抽卡状态的概率 $p$,用来计算期望; 21 | 3. 目前持有卡的状态 $state$,用来统计获得卡片还是获得金币,以及判断游戏结束。注意这里是统计每张卡牌的情况,而不是总共有多少张牌; 22 | 4. 硬币个数 $coin$,用来判断游戏结束; 23 | 24 | 注:这步状态设计存在冗余的量:通过 $state$ 和 $coin$ 可以推算出目前抽了几次卡 $cost$。但为了方便进行讲解,这里不进行合并。 25 | 26 | 假设目前的状态是 $(cost, p, state, coin)$,考虑下一步转移的方向: 27 | 28 | 1. 通过 $state$ 可以得知**未获得**的牌的个数 $tot$,若 $coin \ge tot * k$,则说明目前可以用硬币买到所有的卡牌,对答案贡献 $p\cdot cost$; 29 | 2. 否则,我们要继续抽卡,枚举抽到牌的所有情况。假设目前抽到的卡牌为 $i$,结果分为两种情况: 30 | 1. 目前抽到的卡牌已经存在,即 $2^i\ \&\ state \not= 0$。该卡牌会转换为一个硬币,转移到的下个状态为 $(cost + 1, p \cdot p_i, state, coin + 1)$; 31 | 2. 目前抽到的卡牌不存在,即 $2^i\ \&\ state = 0$。需要更新持有卡牌的状态,转移到下个状态为 $(cost + 1, p \cdot p_i, state\ |\ 2^i, coin)$; 32 | 33 | 考虑一下时间复杂度:每一次从 $n$ 种卡牌中随机选择一张,最多抽卡次数 $k(n-1)+1$,总体复杂度 $\mathrm{O}(n^{k(n-1)+1})$,明显过不了。但从实际上考虑,可能的状态没有这么多(比如抽卡次数最多的几次,需要保证全程只能抽到同一张卡牌)。笔者的程序在 $n=k=5$ 的时候,进入不同状态的次数为 $46459906$。 34 | 35 | ### 逆推 36 | 37 | 相比正推,逆推的主要思路是:所有能转移到的后继状态的期望和 +1,相比正推,只需要维护两个量: 38 | 39 | 1. 目前持有卡的状态 $state$; 40 | 2. 目前持有的硬币数 $coin$。 41 | 42 | 设目前的状态是 $(state, coin)$,考虑下一步转移的方向: 43 | 44 | 1. 通过 $state$ 可以得知**未获得**的牌的个数 $tot$,若 $coin \ge tot * k$,则说明目前可以用硬币买到所有的卡牌,返回 0 即可(因为不用再抽了); 45 | 2. 否则,枚举抽到牌的所有情况,统计所有的期望和,最后 +1。假设抽到的卡牌为 $i$,结果分为两种情况: 46 | 1. 目前抽到的卡牌已经存在,即 $2^i\ \&\ state \not= 0$。该卡牌会转换为一个硬币,所以对应状态比目前硬币数多一,即 $(state, coin + 1)$; 47 | 2. 目前抽到的卡牌不存在,即 $2^i\ \&\ state = 0$。需要更新持有卡牌的状态,所对应的状态为 $(state\ |\ 2^i, coin)$; 48 | 49 | 50 | 51 | ???+ success "代码实现" 52 | === "C++ 正推" 53 | ```cpp linenums="1" 54 | #include 55 | #include 56 | #include 57 | #include 58 | #include 59 | using namespace std; 60 | const int maxn = 20; 61 | int n, k; 62 | double p[maxn]; 63 | inline int calc(int state) { 64 | // 返回目前已经抽到了几张卡 65 | int cur = 0; 66 | for (int i = 0; i < n; ++i) { 67 | if (state & (1 << i)) 68 | ++cur; 69 | } 70 | return cur; 71 | } 72 | // 注:存在另一种常见的写法,维护一个整体 ans,在每个递归终点更新。 73 | double dfs(int cost, double curp, int state, int coin) { 74 | /* 75 | cost: 目前是第几次抽卡 76 | curp: 到达目前状态的概率 77 | state: 目前持有卡牌状态 78 | coin: 目前持有硬币个数 79 | */ 80 | int cur = calc(state); 81 | if ((n - cur) * k <= coin) { 82 | // 当前硬币足以兑换所有未获得卡牌,结束 83 | return cost * curp; 84 | } 85 | double res = 0; 86 | for (int i = 0; i < n; ++i) { 87 | if (state & (1 << i)) { 88 | // 抽到已经获得的卡牌 89 | res += dfs(cost + 1, curp * p[i], state, coin + 1); 90 | } else { 91 | // 抽到未获得的卡牌 92 | res += dfs(cost + 1, curp * p[i], state | (1 << i), coin); 93 | } 94 | } 95 | return res; 96 | } 97 | 98 | int main() { 99 | scanf("%d%d", &n, &k); 100 | for (int i = 0; i < n; ++i) { 101 | scanf("%lf", &p[i]); 102 | } 103 | printf("%.10lf\n", dfs(0, 1, 0, 0)); 104 | return 0; 105 | } 106 | ``` 107 | === "C++ 逆推" 108 | ```cpp linenums="1" 109 | #include 110 | #include 111 | #include 112 | #include 113 | #include 114 | using namespace std; 115 | const int maxn = 20; 116 | int n, k; 117 | double p[maxn]; 118 | inline int calc(int state) { 119 | // 返回目前已经抽到了几张卡 120 | int cur = 0; 121 | for (int i = 0; i < n; ++i) { 122 | if (state & (1 << i)) 123 | ++cur; 124 | } 125 | return cur; 126 | } 127 | double dfs(int state, int coin) { 128 | /* 129 | state: 目前持有卡牌状态 130 | coin: 目前持有硬币个数 131 | */ 132 | int cur = calc(state); 133 | if ((n - cur) * k <= coin) { 134 | // 当前硬币足以兑换所有未获得卡牌,结束 135 | return 0; 136 | } 137 | double res = 0; 138 | for (int i = 0; i < n; ++i) { 139 | if (state & (1 << i)) { 140 | // 抽到已经获得的卡牌 141 | res += p[i] * dfs(state, coin + 1); 142 | } else { 143 | // 抽到未获得的卡牌 144 | res += p[i] * dfs(state | (1 << i), coin); 145 | } 146 | } 147 | return res + 1; 148 | } 149 | 150 | int main() { 151 | scanf("%d%d", &n, &k); 152 | for (int i = 0; i < n; ++i) { 153 | scanf("%lf", &p[i]); 154 | } 155 | printf("%.10lf\n", dfs(0, 0)); 156 | return 0; 157 | } 158 | ``` 159 | 160 | ## 抽到每张卡概率相同——化简状态后打表或记忆化搜索 161 | 162 | 考虑在原本的基础上修改转移方程: 163 | 164 | 由于抽到每张卡牌的概率是相同的,所以我们可以把 $n$ 张卡牌化简为 $2$ 种:**抽到已有的卡牌**和**抽到新的卡牌**,将转移方向从 $n$ 种转变为 $2$ 种。 165 | 166 | 但是这样复杂度还是不允许。笔者的程序在 $n=16,k=5$ 的时候,进入搜索 $1127462785$ 次,在时间允许范围内无法得出结果。需要对这种方法进行一定优化。 167 | 168 | ### 打表 169 | 170 | 因为抽到每张卡牌的概率都是 $\frac{1}{n}$,所以实际有效的值为 $n, k$,而 $n,k$ 组合的有效取值只有 $16\times 5 = 80$ 种。 171 | 172 | 在 $n=16,k=5$ 的时候进入搜索 $1127462785$ 次,按照一秒 $10^7$ 次运算的话大概需要不到 2min 就可以得出结果,在比赛时是有时间打完的(当然,前提是读到这道题时比赛时间剩的不是太少)。 173 | 174 | ### 记忆化搜索 175 | 176 | 考虑重复计算的部分:当目前**持有卡牌数量**和**持有金币数量**确定的时候,在**消除到这一步的概率**的影响后,对最终答案的贡献是一定的。 177 | 178 | 如果想到记忆化搜索了,基本上就能想出正解了。 179 | 180 | ## 100% 数据——记忆化搜索 181 | 182 | 使用记忆化搜索时,采用**逆推**的方法比较容易理解。 183 | 184 | ### 正推 185 | 186 | 考虑重复计算的部分:当目前**持有卡牌情况**和**持有金币数量**确定的时候,在**消除到这一步的概率**的影响后,对最终答案的贡献是一定的。 187 | 188 | ???+ example "一个例子" 189 | 190 | 设 $n=3,k=5$。假设我们目前已经抽到了卡片 $A,B$ 且持有硬币 $3$ 枚(由此可以得知我们已经抽了 5 次卡),转移到该状态的概率为 $p_{cur}$,那么我们下一步抽卡则分为两种情况: 191 | 192 | 1. 以 $p_c$ 的概率抽到卡片 $C$,则结束。对答案的贡献为 $p_{cur}\cdot (6p_c)$; 193 | 2. 以 $p_a$ 的概率抽到卡片 $A$,则状态转变为持有 4 枚硬币。接下来无论抽到哪张卡牌都会结束。对答案的贡献为 $p_{cur}\cdot (7p_a)$; 194 | 3. 以 $p_b$ 的概率抽到卡片 $B$,与上一条相似。对答案的贡献为 $p_{cur}\cdot (7p_b)$; 195 | 196 | 综合下来,该部分对答案的贡献为 $p_{cur}\cdot (6p_c+7p_a+7p_b)$。可以发现在消去 $p_{cur}$ 的影响后,该部分的值是一定的。 197 | 198 | 我们在搜索的时候记录状态,不去重复计算结果即可。 199 | 200 | 考虑时间复杂度:持有卡牌情况为 $\mathrm{O}(2^n)$,持有硬币的数量为 $\mathrm{O}(nk)$,最终复杂度为 $\mathrm{O}(2^n\cdot nk)$。 201 | 202 | ### 逆推 203 | 204 | 考虑重复计算的部分:当目前**持有卡牌情况**和**持有金币数量**确定的时候,期望步数是确定的。 205 | 206 | 我们在搜索时记录状态,减少重复计算即可。 207 | 208 | 时间复杂度 $\mathrm{O}(2^n\cdot nk)$。 209 | 210 | 211 | 212 | ???+ success "代码实现" 213 | === "C++ 正推" 214 | ```cpp linenums="1" 215 | #include 216 | #include 217 | #include 218 | #include 219 | #include 220 | using namespace std; 221 | const int maxn = 20; 222 | int n, k; 223 | double p[maxn]; 224 | double f[66000][90]; 225 | inline int calc(int state) { 226 | // 返回目前已经抽到了几张卡 227 | int cur = 0; 228 | for (int i = 0; i < n; ++i) { 229 | if (state & (1 << i)) 230 | ++cur; 231 | } 232 | return cur; 233 | } 234 | double dfs(int cost, double curp, int state, int coin) { 235 | /* 236 | cost: 目前是第几次抽卡 237 | curp: 到达目前状态的概率 238 | state: 目前持有卡牌状态 239 | coin: 目前持有硬币个数 240 | */ 241 | if (f[state][coin] != 0) { 242 | // 已经计算过的直接返回即可 243 | return f[state][coin] * curp; 244 | } 245 | int cur = calc(state); 246 | if ((n - cur) * k <= coin) { 247 | // 当前硬币足以兑换所有未获得卡牌,结束 248 | f[state][coin] = cost; 249 | return cost * curp; 250 | } 251 | double res = 0; 252 | for (int i = 0; i < n; ++i) { 253 | if (state & (1 << i)) { 254 | // 抽到已经获得的卡牌 255 | res += dfs(cost + 1, curp * p[i], state, coin + 1); 256 | } else { 257 | // 抽到未获得的卡牌 258 | res += dfs(cost + 1, curp * p[i], state | (1 << i), coin); 259 | } 260 | } 261 | // 记录消除 curp 影响后的值 262 | f[state][coin] = res / curp; 263 | return res; 264 | } 265 | 266 | int main() { 267 | scanf("%d%d", &n, &k); 268 | for (int i = 0; i < n; ++i) { 269 | scanf("%lf", &p[i]); 270 | } 271 | printf("%.10lf\n", dfs(0, 1, 0, 0)); 272 | return 0; 273 | } 274 | ``` 275 | === "C++ 逆推" 276 | ```cpp linenums="1" 277 | #include 278 | #include 279 | #include 280 | #include 281 | #include 282 | using namespace std; 283 | const int maxn = 20; 284 | int n, k; 285 | double p[maxn]; 286 | double f[66000][90]; 287 | inline int calc(int state) { 288 | // 返回目前已经抽到了几张卡 289 | int cur = 0; 290 | for (int i = 0; i < n; ++i) { 291 | if (state & (1 << i)) 292 | ++cur; 293 | } 294 | return cur; 295 | } 296 | double dfs(int state, int coin) { 297 | /* 298 | state: 目前持有卡牌状态 299 | coin: 目前持有硬币个数 300 | */ 301 | if (f[state][coin] >= 0) { 302 | // 已经计算过的直接返回即可 303 | return f[state][coin]; 304 | } 305 | int cur = calc(state); 306 | if ((n - cur) * k <= coin) { 307 | // 当前硬币足以兑换所有未获得卡牌,结束 308 | return f[state][coin] = 0; 309 | } 310 | double res = 0; 311 | for (int i = 0; i < n; ++i) { 312 | if (state & (1 << i)) { 313 | // 抽到已经获得的卡牌 314 | res += p[i] * dfs(state, coin + 1); 315 | } else { 316 | // 抽到未获得的卡牌 317 | res += p[i] * dfs(state | (1 << i), coin); 318 | } 319 | } 320 | // 记录并返回 321 | return f[state][coin] = res + 1; 322 | } 323 | 324 | int main() { 325 | memset(f, 0xfe, sizeof(f)); // 初始化 f 数组为负数 326 | scanf("%d%d", &n, &k); 327 | for (int i = 0; i < n; ++i) { 328 | scanf("%lf", &p[i]); 329 | } 330 | printf("%.10lf\n", dfs(0, 0)); 331 | return 0; 332 | } 333 | ``` -------------------------------------------------------------------------------- /docs/problem/23/4/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: problem.html 3 | tags: 4 | - 记忆化搜索 5 | hide: 6 | - tags 7 | --- 8 | # 202109-4 收集卡牌 9 | 10 | ## 题目链接 11 | 12 | [202109-4 收集卡牌](http://118.190.20.162/view.page?gpid=T132) 13 | 14 | ## 思路列表 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 49 | 50 | 51 | 52 | 53 |
题解文章得分要求大致思路题解语言链接
文章 120n,k≤5 32 | 搜索C++题解链接
文章 120pi相同 40 | 化简状态后打表或记忆化搜索题解链接
文章 1100无特殊限制 48 | 记忆化搜索C++题解链接
-------------------------------------------------------------------------------- /docs/problem/23/5/1.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: solution.html 3 | --- 4 | # 202109-5 箱根山岳险天下 5 | 6 | ## 前言——建立树模型 7 | 8 | 题目要求对一个数组进行以下几个操作,**强制在线**: 9 | 10 | - 删除数组中最后一个元素; 11 | - 在数组末尾加入一个元素,注意删掉后又加入的元素与之前元素不能视为相同的元素; 12 | - 在第 $s$ 次操作后的数组中,将 $[l,r]$ 位置的所有元素乘以 $y$,这个操作是永久性的; 13 | - 查询在第 $s$ 次操作后的数组中 $[l,r]$ 位置所有元素**目前**值的和。 14 | 15 | ??? note "如果知道主席树?" 16 | 17 | 对于历史操作,我们会想到主席树。但使用主席树时会遇到以下问题: 18 | 19 | 1. 强制在线,且操作中存在添加删除元素。主席树不太方便实现。 20 | 2. 主席树一般只针对最后的数组进行操作,每次操作只会影响到 $\mathrm{O}(\log n)$ 元素,减小空间占用。但这里的区间乘不是针对最终状态,影响范围很大,空间占用会很多。 21 | 22 | 考虑用什么样的结构去存储信息。 23 | 24 | ### 维护每个操作后的数组 25 | 26 | 一种朴素的想法是维护每次操作后的数组。 27 | 28 | 这种做法存在时间问题:对于修改操作,它影响到的范围是 $\mathrm{O}(m^2)$ 的,总体复杂度 $\mathrm{O}(m^3)$。 29 | 30 | ### 合并元素 31 | 32 | 思考浪费时间的地方: 33 | 34 | 设 $t$ 时刻 $x$ 位置的值为 $A_{x,t}$。假设目前时刻是 $t_{cur}$,如果在 $s$ 时刻修改了 $x$ 位置的值且直到 $t_{cur}$ 时刻该元素一直没有被删除,那么影响到的范围是 $A_{x,s}, A_{x,s+1},\cdots,A_{x, t_{cur}}$ 且操作都是相同的。而题目中所有的查询只针对目前而言,即只需要 $A_{x, t_{cur}}$。**我们不需要维护中间状态的具体值,只需要知道中间状态的每个元素的位置(排名)**。 35 | 36 | 由此,我们可以**只存储每个元素目前时刻的状态**,在进行修改时,只针对当前情况修改即可。 37 | 38 | ### 查找位置对应元素 39 | 40 | 由于每个元素只保留了最终状态,我们无法直接确定某时刻某位置的元素。假设要确定在 $s$ 时刻位置在 $x$ 的元素,因为一个元素的位置是不变的,我们不妨记录每个位置对应的元素编号与加入时间,那么在 $s$ 时刻位置子 $x$ 的元素对应位置在 $x$ 数组内最后一个加入时间小于等于 $s$ 的元素。 41 | 42 | 但是这样也存在问题:要找到一段区间上的所有元素的复杂度是 $\mathrm{O}(m\log m)$ 的,总体复杂度 $\mathrm{O}(m^2\log m)$,不太能接受。 43 | 44 | 转变一下思路,因为增加和删除都是在末端进行,所以在某个元素被删除之前,它前面的元素都是不变的(类似于栈顶元素先变化、栈底元素后变化)。我们不妨将数组视为一条链,那么对应操作: 45 | 46 | - 增加一个元素:在链的末端加入元素。 47 | - 删除一个元素:断开最后一个元素与链的连边,由于需要操作不能实际断开,可以通过维护最后一个元素来实现。那么经过该操作后,新的最后一个元素变为原来的倒数第二个元素。 48 | 49 | 可以看出这是一棵树(准确来说是森林,但可以维护一个位置为 $0$ 的元素指向所有位置为 $1$ 的元素,这样就处理成了一棵树),那么要查找一段区间的所有元素,我们可以找到两端,在树上确定了两端也就确定了整条路径。查找两点时间复杂度 $\mathrm{O}(\log m)$,确定路径复杂度 $\mathrm{O}(m)$,整体 $\mathrm{O}(m)$。 50 | 51 | ### 最终模型 52 | 53 | 用一棵树来维护每个元素的强度,同时记录当前数组的末端元素位置;用数组维护某位置中所有元素的加入时刻与编号,不妨称其为排名数组。 54 | 55 | - 增加元素:在当前数组末端元素的节点处增加新的子节点,并将其设为末端元素,同时更新排名数组。 56 | - 删除元素:当前数组末端元素变更为其父亲节点。 57 | - 修改元素:找到对应元素位置,进行链上修改。 58 | - 查询元素:找到对应元素位置,进行链上查询。 59 | 60 | ## 测试点 1——搜索确定路径 61 | 62 | 在建立树模型后,我们暴力进行对应的操作: 63 | 64 | - 增加元素:复杂度 $\mathrm{O}(1)$; 65 | - 删除元素:复杂度 $\mathrm{O}(1)$; 66 | - 修改元素:确定路径并修改复杂度 $\mathrm{O}(m)$; 67 | - 查询元素:确定路径并查询复杂度 $\mathrm{O}(m)$; 68 | 69 | 整体复杂度 $\mathrm{O}(m^2)$。 70 | 71 | ## 测试点 2——线段树 72 | 73 | 由于只有增加没有删除,所以最终形态是一条链。我们维护线段树即可,初始值为 $0$。 74 | 75 | - 增加元素:线段树单点修改,复杂度 $\mathrm{O}(\log m)$; 76 | - 修改元素:线段树区间修改,复杂度 $\mathrm{O}(\log m)$; 77 | - 查询元素:点段数区间查询,复杂度 $\mathrm{O}(\log m)$; 78 | 79 | 整体复杂度 $\mathrm{O}(m\log m)$; 80 | 81 | ## 不要求在线——树链剖分 82 | 83 | 关于树上的区间修改操作一般都可以用树链剖分完成,但树链剖分需要预先知道树的形状,而本题中点都是动态的,无法一开始就得知。如果是离线的话,可以预处理出树的形态,进行剖分。 84 | 85 | 整体复杂度 $\mathrm{O}(m\log m)$; 86 | 87 | ## 100% 数据——Link Cut Tree 88 | 89 | 因为有对树的动态加点,所以能看出这是一个**动态树问题**。解决动态树问题的结构之一就是 LCT。 90 | 91 | 本题算是 LCT 的板子题,整体复杂度 $\mathrm{O}(m\log m)$。 92 | 93 | 94 | ???+ success "代码实现" 95 | === "C++" 96 | ```cpp linenums="1" 97 | #include 98 | #include 99 | #include 100 | #include 101 | #include 102 | #include 103 | using namespace std; 104 | #define ll long long 105 | #define il inline 106 | const int maxn = 300010; 107 | 108 | int m, T; 109 | ll mod; 110 | 111 | // LCT 部分开始 112 | #define ls ch[x][0] 113 | #define rs ch[x][1] 114 | int ch[maxn][2], fa[maxn]; 115 | ll val[maxn], sum[maxn]; 116 | int lazy_rev[maxn]; 117 | ll lazy_mul[maxn]; 118 | #define getch(x) (ch[fa[x]][1] == x) 119 | #define isRoot(x) (ch[fa[x]][0] != x && ch[fa[x]][1] != x) 120 | void pushdownRev(int x) { 121 | // 执行翻转操作 122 | swap(ls, rs); 123 | lazy_rev[x] ^= 1; 124 | } 125 | void pushdownMul(int x, ll v) { 126 | // 执行区间乘操作 127 | val[x] = (val[x] * v) % mod; 128 | sum[x] = (sum[x] * v) % mod; 129 | lazy_mul[x] = (lazy_mul[x] * v) % mod; 130 | } 131 | void pushdown(int x) { 132 | // 下传懒惰标记 133 | if (lazy_rev[x]) { 134 | if (ls) 135 | pushdownRev(ls); 136 | if (rs) 137 | pushdownRev(rs); 138 | lazy_rev[x] ^= 1; 139 | } 140 | if (lazy_mul[x] != 1) { 141 | if (ls) 142 | pushdownMul(ls, lazy_mul[x]); 143 | if (rs) 144 | pushdownMul(rs, lazy_mul[x]); 145 | lazy_mul[x] = 1; 146 | } 147 | } 148 | void pushup(int x) { 149 | // 更新状态 (maintain) 150 | sum[x] = (sum[ls] + sum[rs] + val[x]) % mod; 151 | } 152 | int st[maxn]; 153 | void rotate(int x) { 154 | // splay 旋转操作 155 | int y = fa[x], z = fa[y], chk = getch(x), w = ch[x][chk ^ 1]; 156 | if (!isRoot(y)) 157 | ch[z][getch(y)] = x; 158 | ch[x][chk ^ 1] = y; 159 | ch[y][chk] = w; 160 | if (w) 161 | fa[w] = y; 162 | fa[y] = x, fa[x] = z; 163 | pushup(y); 164 | } 165 | void splay(int x) { 166 | // 将目前结点旋转到所在 splay 的根 167 | int top = 0, y = x; 168 | st[++top] = y; 169 | while (!isRoot(y)) { 170 | y = fa[y]; 171 | st[++top] = y; 172 | } 173 | while (top) 174 | pushdown(st[top--]); 175 | while (!isRoot(x)) { 176 | y = fa[x]; 177 | if (!isRoot(y)) 178 | rotate(getch(x) == getch(y) ? y : x); 179 | rotate(x); 180 | } 181 | pushup(x); 182 | } 183 | void access(int x) { 184 | // 开辟一条只含有原树的根到 x 的路径结点的实链 185 | for (int y = 0; x; x = fa[y = x]) { 186 | splay(x); 187 | rs = y; 188 | pushup(x); 189 | } 190 | } 191 | void makeRoot(int x) { 192 | // 让 x 称为原树的根 193 | access(x); 194 | splay(x); 195 | pushdownRev(x); 196 | } 197 | void split(int x, int y) { 198 | // 开辟一条只含有 x 到 y 路径结点的实链,y 为 splay 的根 199 | makeRoot(x); 200 | access(y); 201 | splay(y); 202 | } 203 | void link(int x, int y) { 204 | // 连接两个部分 205 | makeRoot(x); 206 | fa[x] = y; 207 | } 208 | // LCT 部分结束 209 | 210 | struct Player { 211 | /* 212 | 队员类。 213 | day: 成为正式队员的时刻 214 | fa : 前一名队员对应编号 215 | */ 216 | int day, fa; 217 | Player(int _d = 0, int _f = 0) { day = _d, fa = _f; } 218 | } player[maxn]; 219 | vector ranklist[maxn]; // 存储队员编号 220 | int cur, cur_rank, tot; 221 | void insertPlayer(int day, ll v) { 222 | // 加入新队员 223 | ++tot; 224 | // 对原树进行操作 225 | player[tot] = Player(day, cur); 226 | ++cur_rank; 227 | ranklist[cur_rank].push_back(tot); 228 | // 对辅助树进行操作 229 | val[tot] = sum[tot] = v; 230 | lazy_mul[tot] = 1; 231 | lazy_rev[tot] = 0; 232 | // 如果目前队伍有人,则加入队伍 233 | if (cur) 234 | link(tot, cur); 235 | cur = tot; 236 | } 237 | int findPlayer(int day, int rk) { 238 | // 查找在第 day 天排名 rk 的队员编号 239 | int l = 0, r = ranklist[rk].size() - 1, mid, ans = 0; 240 | while (l <= r) { 241 | mid = (l + r) >> 1; 242 | if (player[ranklist[rk][mid]].day <= day) { 243 | ans = mid; 244 | l = mid + 1; 245 | } else { 246 | r = mid - 1; 247 | } 248 | } 249 | return ranklist[rk][ans]; 250 | } 251 | 252 | int main() { 253 | scanf("%d%lld%d", &m, &mod, &T); 254 | int opt, s, l, r, x, y, A = 0; 255 | for (int day = 1; day <= m; ++day) { 256 | scanf("%d", &opt); 257 | if (opt == 1) { 258 | scanf("%d", &x); 259 | if (T == 1) 260 | x ^= A; 261 | if (x == 0) { 262 | // 删除队员 263 | cur = player[cur].fa; 264 | --cur_rank; 265 | } else { 266 | // 加入新队员 267 | insertPlayer(day, x); 268 | } 269 | } else if (opt == 2) { 270 | scanf("%d%d%d%d", &s, &l, &r, &y); 271 | if (T == 1) 272 | y ^= A; 273 | l = findPlayer(s, l); 274 | r = findPlayer(s, r); 275 | // 找到 l 到 r 的实链,标记乘以 y 276 | split(l, r); 277 | pushdownMul(r, y); 278 | } else { 279 | scanf("%d%d%d", &s, &l, &r); 280 | l = findPlayer(s, l); 281 | r = findPlayer(s, r); 282 | // 找到 l 到 r 的实链,求和即可 283 | split(l, r); 284 | A = sum[r]; 285 | printf("%d\n", A); 286 | } 287 | } 288 | return 0; 289 | } 290 | ``` -------------------------------------------------------------------------------- /docs/problem/23/5/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: problem.html 3 | tags: 4 | - 动态树 5 | hide: 6 | - tags 7 | --- 8 | # 202109-5 箱根山岳险天下 9 | 10 | ## 题目链接 11 | 12 | [202109-5 箱根山岳险天下](http://118.190.20.162/view.page?gpid=T133) 13 | 14 | ## 思路列表 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 65 | 66 | 67 | 68 | 69 |
题解文章得分要求大致思路题解语言链接
文章 1 32 | 建立树模型题解链接
文章 110m≤5000 40 | 搜索确定路径题解链接
文章 110事件 1 中 x>0 48 | 线段树题解链接
文章 140mode=0(离线) 56 | 树链剖分题解链接
文章 1100无特殊限制 64 | Link Cut TreeC++题解链接
70 | -------------------------------------------------------------------------------- /docs/problem/23/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: contest.html 3 | --- 4 | # 第 23 次(2021 年 9 月) 5 | 6 | 7 | | 题目编号 | 题目名称 | 涉及算法 | 最高得分 | 满分题解语言 | 链接 | 8 | | :-: | :-: | :-: | :-: | :-: | :-: | 9 | | 202109-1 | 数组推导 | 模拟 | 100 | C++、Java、Python 3 | [链接](1\index.md) | 10 | | 202109-2 | 非零段划分 | 模拟 | 100 | C++ | [链接](2\index.md) | 11 | | 202109-3 | 脉冲神经网络 | 模拟、滚动数组 | 100 | C++ | [链接](3\index.md) | 12 | | 202109-4 | 收集卡牌 | 记忆化搜索 | 100 | C++ | [链接](4\index.md) | 13 | | 202109-5 | 箱根山岳险天下 | LCT | 100 | C++ | [链接](5\index.md) | 14 | -------------------------------------------------------------------------------- /docs/problem/24/1/1.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: solution.html 3 | --- 4 | # 202112-1 序列查询 5 | 6 | ## 50% 数据——模拟 7 | 8 | 模拟一下这个过程,计算出每一个 $f(i)$ 后加起来即可。 9 | 10 | 考虑针对确定的 $x$,如何求解 $f(x)$。我们可以从小到大枚举 $A$ 中的数,枚举到第一个大于等于 $x$ 的数即可。注意末尾的判断。 11 | 12 | 枚举 $x$ 时间复杂度 $\mathbf{O}(N)$,计算 $f(x)$ 时间复杂度 $\mathbf{O}(n)$,整体时间复杂度 $\mathbf{O}(nN)$。 13 | 14 | ## 100% 数据——利用 f(x) 单调性 15 | 16 | 为了方便,设 $f(n+1) = \infty$。 17 | 18 | 通过模拟,可以得到一个显然的结论: 19 | 20 | !!! note "$f(x)$ 具有单调性" 21 | 22 | 对于 $x,y\in [0,N)$,若 $x \le y$,则 $f(x) \le f(y)$。 23 | 24 | 那么,我们可以从小到大枚举 $x$,同时记录目前 $f(x)$ 的值,设为 $y$,那么 $A_{y+1}$ 是第一个大于 $x$ 的数。 25 | 当需要计算 $f(x+1)$ 的时候,我们从小到大依次判断 $A_{y+1},A_{y+2},\cdots$ 是否满足条件, 26 | 直到遇到第一个大于 $f(x+1)$ 的数 $A_z$,那么 $f(x+1)=z-1$。 27 | 之后,在 $f(x+1)$ 的基础上以同样的步骤求 $f(x+2)$,直到求完所有的值。 28 | 29 | 考虑该算法的时间复杂度,枚举 $x$ 的复杂度是 $\mathbf{O}(N)$, 30 | 而 $A$ 数组中每个数对多被枚举一次,枚举所有 $x$ 的整体复杂度 $\mathbf{O}(n)$, 31 | 可以得到整体复杂度 $\mathbf{O}(N+n)$。 32 | 33 | 34 | 35 | ???+ success "代码实现" 36 | 37 | === "C++" 38 | 39 | ```cpp linenums="1" 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | using namespace std; 46 | #define ll long long 47 | #define il inline 48 | const int maxn = 210; 49 | int n, N; 50 | int a[maxn]; 51 | ll ans = 0; 52 | int main() { 53 | scanf("%d%d", &n, &N); 54 | for (int i = 1; i <= n; ++i) { 55 | scanf("%d", &a[i]); 56 | } 57 | int cur = 0; 58 | for (int i = 0; i < N; ++i) { 59 | while (cur < n && a[cur + 1] <= i) 60 | ++cur; 61 | ans += cur; 62 | } 63 | printf("%lld\n", ans); 64 | return 0; 65 | } 66 | ``` 67 | 68 | === "Java" 69 | 70 | ```java linenums="1" 71 | import java.util.Scanner; 72 | 73 | public class Main { 74 | public static void main(String[] args) { 75 | Scanner input = new Scanner(System.in); 76 | int n = input.nextInt(), N = input.nextInt(); 77 | long ans = 0; 78 | int a[] = new int[n + 1]; 79 | for (int i = 1; i <= n; ++i) { 80 | a[i] = input.nextInt(); 81 | } 82 | int cur = 0; 83 | for (int i = 0; i < N; ++i) { 84 | while (cur < n && a[cur + 1] <= i) 85 | ++cur; 86 | ans += cur; 87 | } 88 | System.out.println(ans); 89 | input.close(); 90 | } 91 | } 92 | ``` 93 | 94 | === "Python 3" 95 | 96 | ```python linenums="1" 97 | # 该代码与 C++ 和 Java 版本的思路相同,但超时,只能得到 50 分 98 | n, N = map(int, input().strip().split()) 99 | a = list(map(int, input().strip().split())) 100 | ans = 0 101 | cur = 0 102 | for i in range(N): 103 | while cur < n and a[cur] <= i: 104 | cur += 1 105 | ans += cur 106 | print(ans) 107 | ``` 108 | 109 | ## 100% 数据——阶段求和 110 | 111 | 在提示中,指出了可以将 $f(x)$ 相同的值一起计算。现在需要解决的问题是如何快速确定 $f(x)$ 值相等的区间。 112 | 113 | 通过观察和模拟可以发现,随着 $x$ 增大,$f(x)$ 只会在等于某个 $A$ 数组的值时发生变化。 114 | 更具体的说,对于某个属于 $A$ 数组的值 $A_i$ 来说,$[A_i,A_{i+1}-1]$ 间的 $f(x)$ 值是相同的, 115 | 这样的数共有 $A_{i+1}-dA_i$ 个。 116 | 117 | 也可以以另一种方式理解:对于一个值 $y$,考虑有多少 $x$ 满足 $f(x)=y$。 118 | 当 $xy$。 119 | 只有 $x\in [A_y,A_{y+1}]$ 时才能得到 $f(x)=y$。 120 | 121 | 得到范围后,我们就可以根据 $A$ 数组来进行求和计算。 122 | 123 | 考虑 $f(x)=n$ 的处理: 124 | 我们可以得知满足 $f(x)=n$ 的 $x$ 共有 $N-A_n$ 个, 125 | 根据上文推算,我们可以将 $A_{n+1}$ 设置为 $A_n+(N-A_n)=N$ 即可等效替代。 126 | 127 | 时间复杂度 $\mathbf{O}(n)$。 128 | 129 | 130 | 131 | ???+ success "代码实现" 132 | 133 | === "C++" 134 | 135 | ```cpp linenums="1" 136 | #include 137 | #include 138 | #include 139 | #include 140 | #include 141 | using namespace std; 142 | #define ll long long 143 | #define il inline 144 | const int maxn = 210; 145 | int n, N; 146 | int a[maxn]; 147 | ll ans = 0; 148 | int main() { 149 | scanf("%d%d", &n, &N); 150 | for (int i = 1; i <= n; ++i) { 151 | scanf("%d", &a[i]); 152 | } 153 | a[n + 1] = N; 154 | for (int i = 1; i <= n + 1; ++i) { 155 | // 处理区间 [A(i-1),A(i)] 的 f(x) 值的和 156 | ans += 1ll * (a[i] - a[i - 1]) * (i - 1); 157 | } 158 | printf("%lld\n", ans); 159 | return 0; 160 | } 161 | ``` 162 | 163 | === "Java" 164 | 165 | ```Java linenums="1" 166 | import java.util.Scanner; 167 | 168 | public class Main { 169 | public static void main(String[] args) { 170 | Scanner input = new Scanner(System.in); 171 | int n = input.nextInt(), N = input.nextInt(); 172 | long ans = 0; 173 | int a[] = new int[n + 2]; 174 | for (int i = 1; i <= n; ++i) { 175 | a[i] = input.nextInt(); 176 | } 177 | a[0] = 0; 178 | a[n + 1] = N; 179 | for (int i = 1; i <= n + 1; ++i) { 180 | ans += (a[i] - a[i - 1]) * (i - 1); 181 | } 182 | System.out.println(ans); 183 | input.close(); 184 | } 185 | } 186 | ``` 187 | 188 | === "Python 3" 189 | 190 | ```python linenums="1" 191 | n, N = map(int, input().strip().split()) 192 | a = list(map(int, input().strip().split())) 193 | a.insert(0, 0) 194 | a.append(N) 195 | ans = 0 196 | for i in range(1, n + 2): 197 | ans += (a[i] - a[i - 1]) * (i - 1) 198 | print(ans) 199 | ``` -------------------------------------------------------------------------------- /docs/problem/24/1/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: problem.html 3 | tags: 4 | - 模拟 5 | hide: 6 | - tags 7 | --- 8 | # 202112-1 序列查询 9 | 10 | ## 题目链接 11 | 12 | [202112-1 序列查询](http://118.190.20.162/view.page?gpid=T138) 13 | 14 | ## 思路列表 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 49 | 50 | 51 | 52 | 53 |
题解文章得分要求大致思路题解语言链接
文章 150n<N≤1000 32 | 直接模拟 题解链接
文章 1100无特殊限制 40 | 利用 f(x) 单调性C++、Java、Python 3题解链接
文章 1100无特殊限制 48 | 阶段求和C++、Java、Python 3题解链接
-------------------------------------------------------------------------------- /docs/problem/24/2/1.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: solution.html 3 | --- 4 | # 202112-2 序列查询新解 5 | 6 | ## 与上一题的比较 7 | 8 | 1. 上一题是求和,而本题要求求绝对值的和,无法转化为两者求差的形式。 9 | 2. $f(x),g(x)$ 的变化是各自独立的,当 $f(x)$ 改变时,$g(x)$ 可能不变,也可能改变;$g(x)$ 对 $f(x)$ 也是如此。 10 | 3. 对于所有数据点,$n$ 和 $N$ 都增大了许多。如果复杂度涉及到 $n$,则最多预计为 $\mathbf{O}(n\log n)$ 级别;如果涉及到 $N$,则必须是亚线性级别。 11 | 12 | ## 70% 数据——计算出每个 f(x),g(x) 的值 13 | 14 | 由于1,2条限制,我们无法直接对 $f(x),g(x)$ 分别进行处理。但我们可以求出每个 $f(x),g(x)$ 的值,再计算求和即可。 15 | 16 | $f(x)$ 的计算同第一问,任意方法皆可。单个 $g(x)$ 的值可以直接 $\mathbf{O}(1)$ 求得。 17 | 18 | ## 100% 数据——对 f(x),g(x) 都相同的区间进行求和处理 19 | 20 | 注:为了防止混淆,将题目中的 $r$ 改为 $ratio$。 21 | 22 | 假设 $f(x)$ 一共有 $x$ 种取值,$g(x)$ 一共有 $y$ 种取值。 23 | 直接来看 $f(x),g(x)$ 的组合一共有 $xy$ 种, 24 | 但注意到 $f(x),g(x)$ 都是单调不递减函数,所以真正的组合只有 $x+y$ 种。 25 | 26 | 在第一题中已经说明 $f(x)$ 的取值范围为 $[0,n]$,在 $\mathbf{O}(n)$ 级别。 27 | 考虑 $g(x)$ 的取值情况,将 $ratio$ 的公式带入可以得到 $g(x)=\lfloor \frac{x}{ratio}\rfloor=\lfloor\frac{x}{\lfloor \frac{N}{n+1}\rfloor}\rfloor$。 28 | 由于 $x$ 取值有 $N$ 种,所以 $g(x)$ 的取值是 $\mathbf{O}(\frac{N}{\frac{N}{n+1}})=\mathbf{O}(n)$ 级别的。 29 | 所以,整体复杂度为 $\mathbf{O}(n+n)=\mathbf{O}(n)$。 30 | 31 | ???+ note "提示" 32 | 有些时候,题目给出的某些量的值会比较特殊(如本题 $ratio=\lfloor\frac{N}{n+1}\rfloor$), 33 | 代表着出题人可能想要隐藏某些做法,但不得不为了让时间复杂度正确而妥协。 34 | 在没有思路的时候,可以作为突破口。 35 | 36 | 考虑范围问题:假设当前左端点为 $l$,如何找到右端点 $r$,满足 $f(l)=f(l+1)=\cdots=f(r),g(l)=g(l+1)\cdots=g(r)$ 且 $f(l)\not=f(r+1)\ or\ g(l)\not=g(r+1)$。 37 | 我们可以对 $f(x),g(x)$ 分别考虑: 38 | 39 | 1. 对于 $f(x)$ 而言,第一个满足 $f(x)=f(l)+1$ 的 $x$ 值为 $A_{f_l + 1}$。 40 | 2. 对于 $g(x)$ 而言,因为分母 $ratio$ 是固定的,所以值相同的区间长度也是固定为 $ratio$。 41 | 我们不妨将 $g(x)$ 值相同的数字为一组,则可以得到 $[0,ratio-1],[ratio,2\cdot ratio-1],\cdots,[n\cdot ratio,(n+1)\cdot ratio-1],\cdots$ 42 | 这样的分组序列,每组的 $g(x)$ 取值为 $0,1,\cdots,n,\cdots$。 43 | 可以发现,对于一个数 $l$,其所属的分组是 $\lfloor \frac{l}{ratio}\rfloor$,也即 $g(l)$; 44 | 而下一组开始的第一个数为 $ratio\cdot (g(l)+1)$,从而可以得到右端点 $r = ratio\cdot (g(l)+1) - 1$。 45 | 3. 在 $f(x),g(x)$ 计算得到的右端点中,选择较小的一个作为计算的右端点。 46 | 47 | 计算完一段后,设 $l=r+1$ 继续计算下一段,直到结束。时间复杂度 $\mathbf{O}(n)$。 48 | 49 | 50 | 51 | ???+ success "代码实现" 52 | 53 | === "C++" 54 | 55 | ```cpp linenums="1" 56 | #include 57 | #include 58 | #include 59 | #include 60 | #include 61 | using namespace std; 62 | #define ll long long 63 | const int maxn = 100010; 64 | int n, N; 65 | int a[maxn]; 66 | int rat, f, g; 67 | ll ans = 0; 68 | int main() { 69 | scanf("%d%d", &n, &N); 70 | for (int i = 1; i <= n; ++i) { 71 | scanf("%d", &a[i]); 72 | } 73 | rat = N / (n + 1); // 为了防止冲突,题目中 r 改为 rat 74 | int cur = 0; // 用来计算 f(x) 75 | bool flag = false; // 如果需要更新 f(x) 值,则 flag = true 76 | for (int l = 0, r; l < N; l = r + 1) { 77 | flag = false; 78 | // 利用 f(x) 的值确定 r 的范围 79 | if (cur < n) 80 | r = a[cur + 1] - 1; 81 | else 82 | r = N - 1; 83 | // 判断 f(x), g(x) 谁先变化,选择较小的区间 84 | if ((l / rat + 1) * rat - 1 < r) { 85 | // 如果 g(x) 先变化,则改为选择 g(x) 86 | r = (l / rat + 1) * rat - 1; 87 | } else { 88 | // 如果 f(x) 先变化,则确定选择 f(x),计算后更新 f(x) 89 | flag = true; 90 | } 91 | // [l, r] 区间内的值是相等的,可以求和 92 | ans += 1ll * (r - l + 1) * abs(l / rat - cur); 93 | // 更新 f(x) 的值 94 | if (flag) 95 | ++cur; 96 | } 97 | printf("%lld\n", ans); 98 | return 0; 99 | } 100 | ``` 101 | 102 | -------------------------------------------------------------------------------- /docs/problem/24/2/2.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: solution.html 3 | --- 4 | # 202112-2 序列查询新解 5 | 6 | ## 100% 思路——以 f(x) 为单位,讨论内部 g(x) 求和 7 | 8 | 我们需要进行区间求和来降低复杂度。 9 | 一种思路是,整体上对 $f(x)$ 进行求和,而在内部对 $g(x)$ 的情况进行分类讨论。 10 | 11 | 我们单独考虑每一个 $f(x)$ 的区间,每个区间上 $f(x)$ 的值相同。 12 | 可以观察到,对于一个区间上的下标 $i$,可能存在 $g(i)\ge f(i)$,也可能存在 $g(i) 51 | 52 | ???+ success "代码实现" 53 | 54 | === "C++" 55 | 56 | ```cpp linenums="1" 57 | #include 58 | #include 59 | #include 60 | #include 61 | #include 62 | #include 63 | #include 64 | #include 65 | using namespace std; 66 | typedef long long LL; 67 | typedef unsigned long long uLL; 68 | typedef pair pii; 69 | const int mod = 1e9 + 7; 70 | const int maxn = 1e5 + 5; 71 | LL N, n; 72 | LL arr[maxn]; // 题中 A 数组 73 | vector f; // 存储每个区间上f的值 74 | vector pos; // 存储每个区间的边界,是左闭右闭 75 | LL r, ans; // 题中的 r,ans为计算的答案 76 | // 下面的函数用于计算g(x)在区间上的和 77 | // 这一步比较细,具体可以灵活实现 78 | // 下面的思路还是比较冗杂的 79 | LL totG(LL be, LL ed) { 80 | // 右边界小于左边界,返回0 81 | if (ed < be) { 82 | return 0; 83 | } 84 | // 两边界重合,返回一个g值 85 | if (be == ed) { 86 | return be / r; 87 | } 88 | // 如果两边界g值相同,返回该值乘以区间长度 89 | if (be / r == ed / r) { 90 | return (be / r) * (ed - be + 1); 91 | } 92 | // 将区间分为三部分,分别累计 93 | LL tot = 0; 94 | // 对于左边界,其值为be/r,数目为 r - be % r 95 | tot += (r - (be % r)) * (be / r); 96 | // 对于右边界,其值为ed/r,数目为 ed % r + 1 97 | tot += (ed % r + 1) * (ed / r); 98 | // 对于不在边界上的g值,我们用等差数列求和公式 99 | if (ed / r - be / r > 1) { 100 | be = be / r + 1; 101 | ed = ed / r - 1; 102 | tot += r * ((be + ed) * (ed - be + 1) / 2); 103 | } 104 | return tot; 105 | } 106 | void solve() { 107 | // 输入 108 | scanf("%lld%lld", &n, &N); 109 | r = N / (n + 1); 110 | for (int i = 1; i <= n; i++) { 111 | scanf("%d", &arr[i]); 112 | } 113 | // 根据数组,生成f(x)的每个区间,值存入f,区间边界存入pos 114 | LL last = 0ll; // 记录上一个边界 115 | // 这里的逻辑参考第一题 116 | for (int i = 1; i <= n; i++) { 117 | if (arr[i] > arr[last]) { 118 | f.push_back(last); 119 | pos.push_back({arr[last], arr[i] - 1}); 120 | last = i; 121 | } 122 | } 123 | // 单独处理下最后一个区间,即[A[n],N-1] 124 | f.push_back(n); 125 | pos.push_back({arr[last], N - 1}); 126 | // 对于每个f区间,将g分成两个小区间 127 | int si = f.size(); 128 | for (int i = 0; i < si; i++) { 129 | LL num = f[i]; 130 | LL be = pos[i].first; 131 | LL ed = pos[i].second; 132 | LL length = ed - be + 1; 133 | // 因为be和ed在二分过程其值发生变化,所以下面再存一份 134 | LL bbe = be, eed = ed; 135 | // 下面使用二分,在g中寻找分界p 136 | LL pin = -1; 137 | while (be <= ed) { 138 | LL mid = (be + ed) / 2; 139 | LL cur = mid / r; 140 | if (cur >= num) { 141 | pin = mid; 142 | ed = mid - 1; 143 | } else { 144 | be = mid + 1; 145 | } 146 | } 147 | // 如果f的值一直大于g,p值不会被二分的过程赋值,所以还是初值 148 | if (pin == -1) { 149 | ans += num * length - totG(bbe, eed); 150 | } else { 151 | // 左边的用f-g,右边用g-f。就算g的值一直大于f,即左边的部分长度为0 152 | ans += num * (pin - bbe) - totG(bbe, pin - 1); 153 | ans += totG(pin, eed) - num * (eed - pin + 1); 154 | } 155 | } 156 | printf("%lld", ans); 157 | } 158 | int main() { 159 | int t; 160 | t = 1; 161 | while (t--) { 162 | solve(); 163 | } 164 | return 0; 165 | } 166 | ``` -------------------------------------------------------------------------------- /docs/problem/24/2/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: problem.html 3 | tags: 4 | - 模拟 5 | hide: 6 | - tags 7 | --- 8 | # 202112-2 序列查询新解 9 | 10 | ## 题目链接 11 | 12 | [202112-2 序列查询新解](http://118.190.20.162/view.page?gpid=T137) 13 | 14 | ## 思路列表 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 49 | 50 | 51 | 52 | 53 |
题解文章得分要求大致思路题解语言链接
文章 170n<N≤1000 32 | 计算出每个 f(x),g(x) 的值 题解链接
文章 1100无特殊限制 40 | 对 f(x),g(x) 都相同的区间进行求和处理C++题解链接
文章 2100无特殊限制 48 | 以 f(x) 为单位,讨论内部 g(x) 求和C++题解链接
54 | -------------------------------------------------------------------------------- /docs/problem/24/3/1.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: solution.html 3 | --- 4 | # 202112-3 登机牌号码 5 | 6 | ## 40% 数据——直接模拟 7 | 8 | 这一部分数据满足 $s=-1$,即校验码为空。 9 | 我们按照题目要求进行对应操作即可,大体分为以下几个步骤: 10 | 11 | 1. 得到数字序列,注意不同模式的切换以及最后的补全。 12 | 2. 将得到的数字转换为码字。 13 | 3. 根据有效数据区每行能容纳的码字数 $w$ 及目前码字个数,在末尾补充码字。注意不要忽略长度码字。 14 | 4. 输出结果。 15 | 16 | 17 | 18 | ???+ success "代码实现" 19 | 20 | === "C++" 21 | 22 | ```cpp linenums="1" 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | using namespace std; 30 | const int maxn = 210; 31 | const int mod = 929; 32 | int w, lev; 33 | char s[100010]; 34 | int n; 35 | vector numberList; // 数字序列 36 | vector codeWord; // 码字序列 37 | int currentMode; // 目前编码器模式。0:大写模式 1:小写模式 2:数字模式 38 | void checkmode(char c) { 39 | /* 40 | 检查将要输出的下个字符与目前模式是否匹配, 41 | 若不匹配,则输出对应更改模式步骤。 42 | */ 43 | if (c >= '0' && c <= '9') { 44 | if (currentMode != 2) { 45 | numberList.push_back(28); 46 | currentMode = 2; 47 | } 48 | } else if (c >= 'a' && c <= 'z') { 49 | if (currentMode != 1) { 50 | numberList.push_back(27); 51 | currentMode = 1; 52 | } 53 | } else if (c >= 'A' && c <= 'Z') { 54 | if (currentMode == 1) { 55 | numberList.push_back(28); 56 | numberList.push_back(28); 57 | currentMode = 0; 58 | } 59 | if (currentMode == 2) { 60 | numberList.push_back(28); 61 | currentMode = 0; 62 | } 63 | } 64 | } 65 | int main() { 66 | scanf("%d%d", &w, &lev); // lev 表示校验级别 67 | scanf("%s", s); 68 | n = strlen(s); 69 | // 步骤一:得到数字序列 70 | currentMode = 0; // 初始为大写模式 71 | for (int i = 0; i < n; ++i) { 72 | checkmode(s[i]); 73 | if (s[i] >= '0' && s[i] <= '9') { 74 | numberList.push_back(s[i] - '0'); 75 | } else if (s[i] >= 'a' && s[i] <= 'z') { 76 | numberList.push_back(s[i] - 'a'); 77 | } else if (s[i] >= 'A' && s[i] <= 'Z') { 78 | numberList.push_back(s[i] - 'A'); 79 | } 80 | } 81 | if (numberList.size() % 2) 82 | numberList.push_back(29); 83 | // 步骤二:转换为码字 84 | for (int i = 0; i < numberList.size(); i += 2) { 85 | codeWord.push_back(30 * numberList[i] + numberList[i + 1]); 86 | } 87 | // 步骤三:补充码字 88 | while ((1 + codeWord.size()) % w != 0) { 89 | codeWord.push_back(900); 90 | } 91 | // 步骤四:输出结果 92 | codeWord.insert(codeWord.begin(), codeWord.size() + 1); 93 | for (int i = 0; i < codeWord.size(); ++i) { 94 | printf("%d\n", codeWord[i]); 95 | } 96 | return 0; 97 | } 98 | ``` 99 | 100 | ## 100% 数据——模拟+多项式除法 101 | 102 | 这部分数据要求我们对校验码进行处理,所以步骤变为: 103 | 104 | 1. 得到数字序列,注意不同模式的切换以及最后的补全。 105 | 2. 将得到的数字转换为码字。 106 | 3. 根据有效数据区每行能容纳的码字数 $w$、目前码字个数以及{\heiti{校验码的位数}},在末尾补充码字。注意不要忽略长度码字。 107 | 4. 输出数据码部分结果。 108 | 5. 计算得出校验码,并输出。 109 | 110 | 校验码的位数能比较方便得出,关键在于校验码的计算。考虑关键公式: 111 | 112 | \begin{equation*} 113 | x^kd(x)\equiv q(x)g(x)-r(x) 114 | \end{equation*} 115 | 116 | 其中 $d(x)$ 是 $n-1$ 次多项式(已知),$g(x)$ 是 $k$ 次多项式(已知), 117 | 未知项有 $q(x),r(x)$,其中 $r(x)$ 为所求。 118 | 119 | 考虑消去 $q(x)$ 的影响:可以在两端同时对 $g(x)$ 取余,则 $q(x)g(x)$ 项会被直接消去,可以化所求式为: 120 | 121 | \begin{equation*} 122 | x^kd(x)\equiv -r(x) \mod q(x) 123 | \end{equation*} 124 | 125 | 所以目前问题转化为求解 $x^kd(x) \mod q(x)$。 126 | 127 | ???+ note "多项式带余除法" 128 | 若 $f(x)$ 和 $g(x)$ 是两个多项式,且 $g(x)$ 不等于 $0$, 129 | 则存在唯一的多项式 $q(x)$ 和 $r(x)$,满足: 130 | 131 | \begin{equation*} 132 | f(x)=q(x)g(x)+r(x) 133 | \end{equation*} 134 | 135 | 其中 $r(x)$ 的次数小于 $g(x)$ 的次数。此时 $q(x)$ 称为 $g(x)$ 除 $f(x)$ 的商式,$r(x)$ 称为余式。 136 | 137 | ???+ note "多项式长除法" 138 | 求解多项式带余除法的一种方法,步骤如下: 139 | 1. 把被除式、除式按某个字母作降幂排列,并把所缺的项用零补齐; 140 | 2. 用被除式的第一项除以除式第一项,得到商式的第一项; 141 | 3. 用商式的第一项去乘除式,把积写在被除式下面(同类项对齐),消去相等项,把不相等的项结合起来; 142 | 4. 把减得的差当作新的被除式,再按照上面的方法继续演算,直到余式为零或余式的次数低于除式的次数时为止。 143 | 144 | 下面展示的是一个多项式长除法的例子: 145 | 146 | ![例子(其实就是样例)](image/1-polylongdiv.png) 147 | 148 | 得到求解多项式带余除法的步骤后,考虑求解 $r(x)$ 的步骤: 149 | 150 | 1. 计算 $g(x)=(x-3)(x-3^2)\cdots(x-3^k)$; 151 | 2. 计算 $x^kd(x)$; 152 | 3. 计算 $x^kd(x) \mod g(x)$,得到 $-r(x)$; 153 | 4. 对得到的每一项取反即可得到 $r(x)$。 154 | 155 | 计算 $g(x)$:考虑到每一次多项式乘以的因子都是 $(x-a)$ 的格式, 156 | 所以可以把 $A(x-a)$ 的多项式相乘转化为 $xA-aA$ 的格式。 157 | $xA$ 可以通过整体移项实现;在移项后,原本在 $x^i$ 的系数成为 $x^{i+1}$ 的系数, 158 | 所以可以在一个数组上,从低位到高位依次计算,得到结果。 159 | 160 | 计算 $x^kd(x)$:这部分比较简单,将低 $k$ 位的系数赋 $0$,再将已计算出的数据位放入对应位置即可。 161 | 162 | 计算 $x^kd(x) \mod g(x)$:利用上文提到的多项式长除法即可。本题 $g(x)$ 的最高位系数恒为 $1$,简化了计算。 163 | 164 | 165 | 166 | ???+ success "代码实现" 167 | 168 | === "C++" 169 | 170 | ``` { .cpp .annotate linenums="1" hl_lines="44-88 111-118 120 128-131"} 171 | #include 172 | #include 173 | #include 174 | #include 175 | #include 176 | #include 177 | using namespace std; 178 | const int maxn = 210; 179 | const int mod = 929; 180 | int w, lev; 181 | char s[100010]; 182 | int n; 183 | vector numberList; 184 | vector codeWord; 185 | int verifyCodeLen; // 校验码长度 186 | int currentMode; 187 | void checkmode(char c) { 188 | /* 189 | 检查将要输出的下个字符与目前模式是否匹配, 190 | 若不匹配,则输出对应更改模式步骤。 191 | */ 192 | if (c >= '0' && c <= '9') { 193 | if (currentMode != 2) { 194 | numberList.push_back(28); 195 | currentMode = 2; 196 | } 197 | } else if (c >= 'a' && c <= 'z') { 198 | if (currentMode != 1) { 199 | numberList.push_back(27); 200 | currentMode = 1; 201 | } 202 | } else if (c >= 'A' && c <= 'Z') { 203 | if (currentMode == 1) { 204 | numberList.push_back(28); 205 | numberList.push_back(28); 206 | currentMode = 0; 207 | } 208 | if (currentMode == 2) { 209 | numberList.push_back(28); 210 | currentMode = 0; 211 | } 212 | } 213 | } 214 | vector get_gx(int k) { // (1) 215 | // 根据 k 计算 g(x) 216 | vector res; 217 | res.push_back(mod - 3); 218 | res.push_back(1); 219 | int a0 = 3; 220 | for (int i = 2; i <= k; ++i) { 221 | a0 = (a0 * 3) % mod; 222 | res.insert(res.begin(), 0); // 在最低位插入 1,即整体次数 +1 223 | for (int j = 0; j < i; ++j) { 224 | res[j] = (res[j] - (a0 * res[j + 1]) % mod + mod) % mod; 225 | } 226 | } 227 | return res; 228 | } 229 | 230 | void get_verify_code() { 231 | // 计算校验码并输出 232 | vector tmp; 233 | vector g = get_gx(verifyCodeLen); 234 | // 初始化 x^kd(x) 235 | for (int i = 1; i <= verifyCodeLen; ++i) { 236 | tmp.push_back(0); 237 | } 238 | for (int i = codeWord.size() - 1; i >= 0; --i) { 239 | tmp.push_back(codeWord[i]); 240 | } 241 | // 多项式长除法计算结果 242 | for (int i = tmp.size() - 1; i >= verifyCodeLen; --i) { 243 | int val = tmp[i]; 244 | for (int j = 0; j < g.size(); ++j) { 245 | tmp[i - j] = 246 | (tmp[i - j] - (val * g[g.size() - 1 - j]) % mod + mod) % mod; 247 | } 248 | } 249 | // 将 -r(x) 转化为 r(x) 250 | for (int i = 0; i < verifyCodeLen; ++i) { 251 | // 注意:不能直接 mod - tmp[i],因为 tmp[i] 可能为 0 252 | tmp[i] = (mod - tmp[i]) % mod; 253 | } 254 | // 输出结果 255 | for (int i = verifyCodeLen - 1; i >= 0; --i) { 256 | printf("%d\n", tmp[i]); 257 | } 258 | } 259 | int main() { 260 | scanf("%d%d", &w, &lev); 261 | scanf("%s", s); 262 | n = strlen(s); 263 | // 步骤一:得到数字序列 264 | currentMode = 0; 265 | for (int i = 0; i < n; ++i) { 266 | checkmode(s[i]); 267 | if (s[i] >= '0' && s[i] <= '9') { 268 | numberList.push_back(s[i] - '0'); 269 | } else if (s[i] >= 'a' && s[i] <= 'z') { 270 | numberList.push_back(s[i] - 'a'); 271 | } else if (s[i] >= 'A' && s[i] <= 'Z') { 272 | numberList.push_back(s[i] - 'A'); 273 | } 274 | } 275 | if (numberList.size() % 2) 276 | numberList.push_back(29); 277 | // 步骤二:转换为码字 278 | for (int i = 0; i < numberList.size(); i += 2) { 279 | codeWord.push_back(30 * numberList[i] + numberList[i + 1]); 280 | } 281 | if (lev == -1) 282 | verifyCodeLen = 0; 283 | else { 284 | verifyCodeLen = 1; 285 | for (int i = 0; i <= lev; ++i) { 286 | verifyCodeLen *= 2; 287 | } 288 | } 289 | // 步骤三:补充码字 290 | while ((1 + verifyCodeLen + codeWord.size()) % w != 0) { 291 | codeWord.push_back(900); 292 | } 293 | codeWord.insert(codeWord.begin(), codeWord.size() + 1); 294 | // 步骤四:输出数据码结果 295 | for (int i = 0; i < codeWord.size(); ++i) { 296 | printf("%d\n", codeWord[i]); 297 | } 298 | // 步骤五:如果有校验码,则计算并输出 299 | if (verifyCodeLen != 0) { 300 | get_verify_code(); 301 | } 302 | return 0; 303 | } 304 | ``` 305 | 306 | 1. 背景为黄色的代码是相比部分分代码做出的改变,其它部分与部分分完全相同。 -------------------------------------------------------------------------------- /docs/problem/24/3/image/1-polylongdiv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CCF-CSP-Project/CSP-Project-with-MkDocs/303ed90bb1247e0e1a26b320b0c8fa40881b6723/docs/problem/24/3/image/1-polylongdiv.png -------------------------------------------------------------------------------- /docs/problem/24/3/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: problem.html 3 | tags: 4 | - 模拟 5 | hide: 6 | - tags 7 | --- 8 | # 202112-3 登机牌号码 9 | 10 | ## 题目链接 11 | 12 | [202112-3 登机牌号码](http://118.190.20.162/view.page?gpid=T136) 13 | 14 | ## 思路列表 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 41 | 42 | 43 | 44 | 45 |
题解文章得分要求大致思路题解语言链接
文章 140s=-1 32 | 直接模拟C++题解链接
文章 1100无特殊限制 40 | 模拟+多项式除法C++题解链接
-------------------------------------------------------------------------------- /docs/problem/24/4/1.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: solution.html 3 | --- 4 | # 202112-4 磁盘文件操作 5 | 6 | ## 25% 数据——直接模拟 7 | 8 | 我们按照题目要求进行对应操作即可,注意每一个要求执行的条件: 9 | 10 | - 写入操作:从左往右依次执行,直到第一个不被自己占用的位置。**除了第一个点就被其他程序占用以外,必然会写入。**遇到自己占用,则**覆盖**。 11 | - 删除操作:同时整体进行,要求所有位置都被目前程序占用。**要么全删,要么不做任何更改。** 12 | - 恢复操作:同时整体进行,要求所有位置都不被占用,且上次占用程序为目前程序。**要么全恢复,要么不做任何更改。**遇到自己占用,则**不做任何更改**。 13 | - 读入操作:读取占用程序和数值,若未被占用,则输出 0 0。 14 | 15 | ## 100% 数据——离散化+线段树 16 | 17 | 通过这道题的操作要求等,我们可以大致推测出这道题可能需要使用线段树。 18 | 19 | ???+ note "提示" 20 | 21 | 如果没什么思路,可以拿各种数据结构往上套。 22 | 例如本题,因为涉及区间修改、单点查询,对于树状数组来说负担太重,我们可以尝试其他数据结构。 23 | 如果使用平衡树,则一般是要求出第 k 大数,或者是序列翻转类问题,对于本题来说不太契合。 24 | 其他数据结构不再一一列举。综合考虑下,线段树是比较符合要求的。 25 | 26 | ### 考虑线段树的做法 27 | 28 | 先不考虑线段树的内存空间问题,我们分析一下如何用线段树解决这道题目。 29 | 30 | 考虑我们需要维护的量,目前已知的有磁盘位置的值、目前占用程序 id、上次占用程序 id。 31 | 32 | 在这里,我们假设一个位置未被占用和被 id 为 0 的程序占用是等价的。 33 | 34 | - 写入操作:可以划分为**找到写入右边界**和**直接写入**两个操作。 35 | 36 | 直接写入操作就是直接的线段树区间修改, 37 | 而划分操作需要知道该区间**被占用**的位置是否属于将要写入的 id。 38 | 我们不妨将这个量设为 id1。 39 | 40 | - 删除操作:可以划分为**判断是否可删**和**直接删除**两个操作。 41 | 42 | 直接删除操作就是直接的线段树区间修改, 43 | 而判断是否可删需要知道该区间**所有**的位置是否属于将要写入的 id。 44 | 我们不妨将这个量设为 id2,注意 id1 与 id2 的区别——是否允许包含未被占用的程序。 45 | 46 | - 恢复操作:可以划分为**判断是否可恢复**和**直接恢复**两个操作。 47 | 48 | 该操作与删除操作类似,不过需要注意的是判断时需要判断目前占用的 id 和上次被占用的 id。 49 | 50 | - 读取操作:可以划分为**查询占用程序 id**和**查询值**两个操作。 51 | 52 | 该操作是相对比较质朴的单点查询,当然也可以处理为区间。 53 | 54 | 55 | 通过以上分析,我们得到了需要维护的量:值、有关目前占用程序 id 的两个量、上次被占用的程序 id。我们考虑每个量针对父子之间的维护。 56 | 57 | - 值 val:每个节点代表取值的多少,若左右子节点不同则设为一个不存在的值。因为我们是单点查询,所以不用担心查询到不存在的值的问题。 58 | - 被占用位置程序 id1: 59 | - 若左右子节点都未被占用,则该节点标记为未占用; 60 | - 若左右子节点中存在不唯一节点,则该节点标记为不唯一。 61 | - 若左右子节点中一个节点未占用,则该节点标记为另一个非空节点的标记; 62 | - 若左右子节点都非空且相等,则该节点标记为任意一个节点; 63 | - 若左右子节点都非空且不等,则该节点标记为不唯一; 64 | - 被占用位置程序 id2:为了方便进行讨论,将未被程序占用节点视为被 id 为 0 的程序占用。 65 | - 若左右子节点中存在不唯一节点,则该节点标记为不唯一。 66 | - 若左右子节点相等,则该节点标记为任意一个节点; 67 | - 若左右子节点不等,则该节点标记为不唯一; 68 | - 上一次被占用程序 lid:与 id2 相同。 69 | - 若左右子节点中存在不唯一节点,则该节点标记为不唯一。 70 | - 若左右子节点相等,则该节点标记为任意一个节点; 71 | - 若左右子节点不等,则该节点标记为不唯一; 72 | 73 | ### 解决空间问题 74 | 75 | 理解线段树的解法之后,就会出现另一个问题:空间达到了 1e9 级别,肯定会 MLE。 76 | 77 | 我们可以从另一个角度考虑:一共有 $2\times 10^5$ 次询问,每次最多操作涉及一个区间,可以用两个端点表示。 78 | 考虑到临界处的影响,一次操作最多会涉及 4 个点 79 | (比如原来的区间是 $[1, 10]$,我们更改了区间 $[3,5]$,那么得到的区间为 $[1,2],[3,5],[6,10]$,多出了 $2,3,5,6$ 四个点)。 80 | 那么总体来看,涉及到的点最多有 $2\times 10^5\times 4 = 8\times 10^5$ 个。 81 | 82 | 我们可以维持这些点的相对大小关系,而将其投影到一个值域较小的区域,就可以减少空间占用了。这种方法称为离散化。 83 | 84 | ???+ note "离散化" 85 | 86 | 把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。通俗的说,离散化是在不改变数据相对大小的条件下,对数据进行相应的缩小。 87 | 离散化本质上可以看成是一种哈希,其保证数据在哈希以后仍然保持原来的全/偏序关系。 88 | 89 | 离散化的一般性步骤: 90 | 91 | - 统计所有出现过的数字,在知道确切上界的时候可以用数组,不清楚情况下可以用 vector; 92 | - 对所有的数据排序 (sort)、去重 (unique); 93 | - 对于每个数,其离散化后的对应值即为其在排序去重后数组中的位置,可以通过二分 (lower\_bound) 确定。 94 | 95 | 这道题允许我们提前将所有可能出现的数记录下来(当然不是所有的题目都允许这样),所以这道题就解决了。 96 | 线段树节点的个数与询问个数成比例,时间复杂度 $\mathrm{O}(k\log k)$。 97 | 98 | 99 | 100 | ???+ success "代码实现" 101 | 102 | === "C++" 103 | 104 | ```cpp linenums="1" 105 | #include 106 | #include 107 | #include 108 | #include 109 | #include 110 | #include 111 | #include 112 | using namespace std; 113 | const int maxn = 200010; 114 | const int INF = 1e9 + 10; 115 | int n, m, k; 116 | #define ls o << 1 117 | #define rs ls | 1 118 | struct treenode { 119 | // 当前节点的值,若不唯一则为 INF;lazy 为 INF 表示无延迟更新 120 | int val, lazy_val; 121 | // 当前占用 id,若存在除 0 以外两种 id 则为 -1;lazy 为 -1 表示无延迟更新 122 | int id1, lazy_id1; 123 | // 当前占用 id,若存在两种 id 则为 -1;lazy 为 -1 表示无延迟更新 124 | int id2, lazy_id2; 125 | // 上次占用 id,若存在两种 id 则为 -1;lazy 为 -1表示无延迟更新 126 | int lid, lazy_lid; 127 | } tree[maxn << 5]; 128 | 129 | void pushup(int o) { 130 | // 线段树上传操作,合并左右子树结果 131 | // val 的合并 132 | tree[o].val = (tree[ls].val == tree[rs].val) ? tree[ls].val : INF; 133 | // id1 的合并 134 | if (tree[ls].id1 == -1 || tree[rs].id1 == -1) { 135 | tree[o].id1 = -1; 136 | } else if (tree[ls].id1 == tree[rs].id1) { 137 | tree[o].id1 = tree[ls].id1; 138 | } else if (tree[ls].id1 == 0) { 139 | tree[o].id1 = tree[rs].id1; 140 | } else if (tree[rs].id1 == 0) { 141 | tree[o].id1 = tree[ls].id1; 142 | } else { 143 | tree[o].id1 = -1; 144 | } 145 | // id2 的合并 146 | if (tree[ls].id2 == -1 || tree[rs].id2 == -1) { 147 | tree[o].id2 = -1; 148 | } else if (tree[ls].id2 == tree[rs].id2) { 149 | tree[o].id2 = tree[ls].id2; 150 | } else { 151 | tree[o].id2 = -1; 152 | } 153 | // lid 的合并 154 | if (tree[ls].lid == -1 || tree[rs].lid == -1) { 155 | tree[o].lid = -1; 156 | } else if (tree[ls].lid == tree[rs].lid) { 157 | tree[o].lid = tree[ls].lid; 158 | } else { 159 | tree[o].lid = -1; 160 | } 161 | } 162 | 163 | void pushdown(int o) { 164 | // 线段树标记下传操作 165 | if (tree[o].lazy_val != INF) { 166 | tree[ls].val = tree[rs].val = tree[o].lazy_val; 167 | tree[ls].lazy_val = tree[rs].lazy_val = tree[o].lazy_val; 168 | tree[o].lazy_val = INF; 169 | } 170 | if (tree[o].lazy_id1 != -1) { 171 | tree[ls].id1 = tree[rs].id1 = tree[o].lazy_id1; 172 | tree[ls].lazy_id1 = tree[rs].lazy_id1 = tree[o].lazy_id1; 173 | tree[o].lazy_id1 = -1; 174 | } 175 | if (tree[o].lazy_id2 != -1) { 176 | tree[ls].id2 = tree[rs].id2 = tree[o].lazy_id2; 177 | tree[ls].lazy_id2 = tree[rs].lazy_id2 = tree[o].lazy_id2; 178 | tree[o].lazy_id2 = -1; 179 | } 180 | if (tree[o].lazy_lid != -1) { 181 | tree[ls].lid = tree[rs].lid = tree[o].lazy_lid; 182 | tree[ls].lazy_lid = tree[rs].lazy_lid = tree[o].lazy_lid; 183 | tree[o].lazy_lid = -1; 184 | } 185 | } 186 | 187 | void build(int o, int l, int r) { 188 | // 线段树初始化建树 189 | if (l == r) { 190 | tree[o].val = 0; 191 | tree[o].lazy_val = INF; 192 | tree[o].id1 = tree[o].id2 = tree[o].lid = 0; 193 | tree[o].lazy_id1 = tree[o].lazy_id2 = tree[o].lazy_lid = -1; 194 | return; 195 | } 196 | int mid = (l + r) >> 1; 197 | build(ls, l, mid); 198 | build(rs, mid + 1, r); 199 | tree[o].lazy_val = INF; 200 | pushup(o); 201 | } 202 | 203 | #define ALLOK -2 204 | int find_right(int o, int l, int r, int ql, int qid) { 205 | // 操作一中,固定左端点,寻找右端点可能的最大值 206 | // 这里没有考虑和右端点的比较,直接寻找了最大的可能值 207 | pushdown(o); 208 | if (r < ql || tree[o].id1 == qid || tree[o].id1 == 0) { 209 | // 全部符合条件 210 | return ALLOK; 211 | } else if (tree[o].id2 != -1) { 212 | // 不符合条件,返回该区域左边第一个 213 | return l - 1; 214 | } else { 215 | // 需要寻找确切位置 216 | // 先查找左区间,如果左区间全满足则再寻找右区间 217 | int mid = (l + r) >> 1; 218 | int leftPart = (ql <= mid) ? find_right(ls, l, mid, ql, qid) : ALLOK; 219 | return (leftPart == ALLOK) ? find_right(rs, mid + 1, r, ql, qid) 220 | : leftPart; 221 | } 222 | } 223 | #undef ALLOK 224 | 225 | void modify_val(int o, int l, int r, int ql, int qr, int val, int id, 226 | bool ignoreLid = false) { 227 | // 若 val = INF 代表不需要对 val 进行处理 228 | // 若 ignoreLid = true 则不对 lid 进行更改 229 | if (l >= ql && r <= qr) { 230 | if (val != INF) 231 | tree[o].val = tree[o].lazy_val = val; 232 | tree[o].id1 = tree[o].lazy_id1 = id; 233 | tree[o].id2 = tree[o].lazy_id2 = id; 234 | if (!ignoreLid) 235 | tree[o].lid = tree[o].lazy_lid = id; 236 | return; 237 | } 238 | pushdown(o); 239 | int mid = (l + r) >> 1; 240 | if (ql <= mid) { 241 | modify_val(ls, l, mid, ql, qr, val, id, ignoreLid); 242 | } 243 | if (qr > mid) { 244 | modify_val(rs, mid + 1, r, ql, qr, val, id, ignoreLid); 245 | } 246 | pushup(o); 247 | } 248 | 249 | bool is_same_id(int o, int l, int r, int ql, int qr, int id, 250 | bool isRecover = false) { 251 | // 判断该区域 id 和 lid 是否满足条件 252 | if (l >= ql && r <= qr) { 253 | if (isRecover) { 254 | // 检查 id = 0 且 lid = id 255 | return (tree[o].id2 == 0 && tree[o].lid == id); 256 | } else { 257 | // 检查 id = id 258 | return (tree[o].id2 == id); 259 | } 260 | } 261 | pushdown(o); 262 | int mid = (l + r) >> 1; 263 | bool isSame = true; 264 | if (ql <= mid) { 265 | isSame = isSame && is_same_id(ls, l, mid, ql, qr, id, isRecover); 266 | } 267 | if (qr > mid && isSame) { 268 | isSame = isSame && is_same_id(rs, mid + 1, r, ql, qr, id, isRecover); 269 | } 270 | return isSame; 271 | } 272 | 273 | int query_val(int o, int l, int r, int p) { 274 | // 线段树单点求值:val 275 | if (p >= l && p <= r && tree[o].val != INF) { 276 | return tree[o].val; 277 | } 278 | pushdown(o); 279 | int mid = (l + r) >> 1; 280 | if (p <= mid) 281 | return query_val(ls, l, mid, p); 282 | else 283 | return query_val(rs, mid + 1, r, p); 284 | } 285 | 286 | int query_id(int o, int l, int r, int p) { 287 | // 线段树单点求值:id2 288 | if (p >= l && p <= r && tree[o].id2 != -1) { 289 | return tree[o].id2; 290 | } 291 | pushdown(o); 292 | int mid = (l + r) >> 1; 293 | if (p <= mid) 294 | return query_id(ls, l, mid, p); 295 | else 296 | return query_id(rs, mid + 1, r, p); 297 | } 298 | 299 | #undef ls 300 | #undef rs 301 | 302 | struct instruction { 303 | int opt, id, l, r, x; 304 | } inst[maxn]; 305 | // numList 存储所有可能出现的数,totnum 表示个数 306 | int numList[maxn << 2], totnum; 307 | void discretization() { 308 | // 离散化操作 309 | sort(numList + 1, numList + 1 + totnum); 310 | totnum = unique(numList + 1, numList + 1 + totnum) - numList - 1; 311 | m = totnum; 312 | for (int i = 1; i <= k; ++i) { 313 | if (inst[i].opt == 0 || inst[i].opt == 1 || inst[i].opt == 2) { 314 | inst[i].l = 315 | lower_bound(numList + 1, numList + 1 + totnum, inst[i].l) - 316 | numList; 317 | inst[i].r = 318 | lower_bound(numList + 1, numList + 1 + totnum, inst[i].r) - 319 | numList; 320 | } else { 321 | inst[i].x = 322 | lower_bound(numList + 1, numList + 1 + totnum, inst[i].x) - 323 | numList; 324 | } 325 | } 326 | } 327 | 328 | int main() { 329 | scanf("%d%d%d", &n, &m, &k); 330 | numList[++totnum] = 1; 331 | numList[++totnum] = m; 332 | for (int i = 1; i <= k; ++i) { 333 | scanf("%d", &inst[i].opt); 334 | if (inst[i].opt == 0) { 335 | scanf("%d%d%d%d", &inst[i].id, &inst[i].l, &inst[i].r, &inst[i].x); 336 | numList[++totnum] = inst[i].l; 337 | numList[++totnum] = inst[i].r; 338 | // 注意边界问题,为了方便这里把交界处两点分开了,下同 339 | if (inst[i].l != 1) 340 | numList[++totnum] = inst[i].l - 1; 341 | if (inst[i].r != m) 342 | numList[++totnum] = inst[i].r + 1; 343 | } else if (inst[i].opt == 1) { 344 | scanf("%d%d%d", &inst[i].id, &inst[i].l, &inst[i].r); 345 | numList[++totnum] = inst[i].l; 346 | numList[++totnum] = inst[i].r; 347 | if (inst[i].l != 1) 348 | numList[++totnum] = inst[i].l - 1; 349 | if (inst[i].r != m) 350 | numList[++totnum] = inst[i].r + 1; 351 | } else if (inst[i].opt == 2) { 352 | scanf("%d%d%d", &inst[i].id, &inst[i].l, &inst[i].r); 353 | numList[++totnum] = inst[i].l; 354 | numList[++totnum] = inst[i].r; 355 | if (inst[i].l != 1) 356 | numList[++totnum] = inst[i].l - 1; 357 | if (inst[i].r != m) 358 | numList[++totnum] = inst[i].r + 1; 359 | } else { 360 | scanf("%d", &inst[i].x); 361 | // 对于查询的数,不需要进行离散化,查找第一个比它大的数即可 362 | } 363 | } 364 | 365 | // 离散化处理 366 | discretization(); 367 | 368 | // 线段树初始化建树 369 | build(1, 1, m); 370 | 371 | // 进行操作 372 | for (int i = 1; i <= k; ++i) { 373 | if (inst[i].opt == 0) { 374 | // 写入操作:先求得范围,再进行填充 375 | int r = find_right(1, 1, m, inst[i].l, inst[i].id); 376 | if (r == -2) 377 | // r = -2 代表全部满足 378 | r = inst[i].r; 379 | else 380 | r = min(r, inst[i].r); 381 | if (inst[i].l <= r) { 382 | printf("%d\n", numList[r]); // 注意返回离散化前的值 383 | modify_val(1, 1, m, inst[i].l, r, inst[i].x, inst[i].id); 384 | } else { 385 | printf("-1\n"); 386 | } 387 | } else if (inst[i].opt == 1) { 388 | // 删除操作:先判断是否可行,之后执行 389 | if (is_same_id(1, 1, m, inst[i].l, inst[i].r, inst[i].id)) { 390 | printf("OK\n"); 391 | modify_val(1, 1, m, inst[i].l, inst[i].r, INF, 0, true); 392 | } else { 393 | printf("FAIL\n"); 394 | } 395 | } else if (inst[i].opt == 2) { 396 | // 恢复操作:先判断是否可行,之后执行 397 | if (is_same_id(1, 1, m, inst[i].l, inst[i].r, inst[i].id, true)) { 398 | printf("OK\n"); 399 | modify_val(1, 1, m, inst[i].l, inst[i].r, INF, inst[i].id, 400 | true); 401 | } else { 402 | printf("FAIL\n"); 403 | } 404 | } else if (inst[i].opt == 3) { 405 | // 读取操作:分别读取 id 和 val 406 | int id = query_id(1, 1, m, inst[i].x); 407 | int val = query_val(1, 1, m, inst[i].x); 408 | if (id == 0) { 409 | printf("0 0\n"); 410 | } else { 411 | printf("%d %d\n", id, val); 412 | } 413 | } 414 | } 415 | return 0; 416 | } 417 | ``` 418 | 419 | ## 100% 数据——动态开点线段树 420 | 421 | 在上一题的做法中,我们需要先读入所有的数据并进行离散化处理,之后再执行主要的算法过程。 422 | 但不是所有的题目都可以在执行主要的算法过程前得到所有的输入数据。 423 | 424 | ???+ note "离线算法" 425 | 426 | 要求在执行算法前输入数据已知的算法称为离线算法。 427 | 一般而言,如果没有对输入输出做特殊处理,则可以用离线算法解决该问题。 428 | 429 | ???+ note "在线算法" 430 | 不需要输入数据已知就可以执行的算法称为在线算法。 431 | 一般而言,如果对输入输出做特殊处理(如本次的询问需要与上次执行的答案进行异或才能得到真正的询问),则只能用离线算法解决该问题。 432 | 433 | 对于一道能用离线和在线算法解决的题目,如果出题人对数据进行了加密处理,导致只能使用在线算法,则我们称这道题是**强制在线**的。 434 | 435 | 离散化需要事先知道所有可能出现的数,所以是**离线算法**。如果要强制在线,就需要另一种思路。 436 | 437 | 同样,从询问涉及的点有限出发,我们考虑最多能涉及线段树上点的个数。 438 | 线段树的高度为 $\mathrm{O}(\log m)$,假设每个涉及查询的点都到达了线段树的叶子结点, 439 | 且不考虑根到任意两个结点之间重复的节点,则总共涉及的线段树节点数的个数为 $\mathrm{O}(k\log m)$。 440 | 所以我们只需要为用到的节点开辟空间即可。 441 | 442 | 针对一般的线段树,我们是预先建好了整棵线段树(build 函数), 443 | 每个线段树节点的左右子节点编号与其本身编号都是对应的(通常一个子节点是父结点的二倍,而另一个子节点则相差 1)。 444 | 而对于这种只为需要用到节点开辟空间的线段树,其左右子树只有在需要的时候才会被创建, 445 | 所以编号间没有特定关系,需要记录。 446 | 447 | 考虑什么时候需要开辟新结点:在初始化的时候需要开创一个根节点; 448 | 在进行修改及查询的时候,如果区间不是所要的区间,则需要开创新的节点。 449 | 有一个技巧是,在修改和查询的时候往往要下传标记(pushdown),可以在此之前检查是否需要开创节点。 450 | 451 | 452 | 453 | ???+ success "代码实现" 454 | 455 | === "C++" 456 | 457 | ```cpp linenums="1" 458 | #include 459 | #include 460 | #include 461 | #include 462 | #include 463 | #include 464 | #include 465 | using namespace std; 466 | const int maxn = 200010; 467 | const int INF = 1e9 + 10; 468 | int n, m, k; 469 | struct treenode { 470 | // 左右子节点编号 471 | int lc, rc; 472 | // 当前节点的值,若不唯一则为 INF;lazy 为 INF 表示无延迟更新 473 | int val, lazy_val; 474 | // 当前占用 id,若存在除 0 以外两种 id 则为 -1;lazy 为 -1 表示无延迟更新 475 | int id1, lazy_id1; 476 | // 当前占用 id,若存在两种 id 则为 -1;lazy 为 -1 表示无延迟更新 477 | int id2, lazy_id2; 478 | // 上次占用 id,若存在两种 id 则为 -1;lazy 为 -1表示无延迟更新 479 | int lid, lazy_lid; 480 | } tree[maxn << 5]; 481 | int cnt; // 线段树节点个数 482 | #define ls tree[o].lc 483 | #define rs tree[o].rc 484 | int insert_node() { 485 | // 向线段树中插入一个节点 486 | ++cnt; 487 | tree[cnt].lc = tree[cnt].rc = 0; 488 | tree[cnt].val = 0; 489 | tree[cnt].id1 = tree[cnt].id2 = 0; 490 | tree[cnt].lid = 0; 491 | tree[cnt].lazy_val = INF; 492 | tree[cnt].lazy_id1 = tree[cnt].lazy_id2 = -1; 493 | tree[cnt].lid = -1; 494 | return cnt; 495 | } 496 | 497 | void pushup(int o) { 498 | // 线段树上传操作,合并左右子树结果 499 | // val 的合并 500 | tree[o].val = (tree[ls].val == tree[rs].val) ? tree[ls].val : INF; 501 | // id1 的合并 502 | if (tree[ls].id1 == -1 || tree[rs].id1 == -1) { 503 | tree[o].id1 = -1; 504 | } else if (tree[ls].id1 == tree[rs].id1) { 505 | tree[o].id1 = tree[ls].id1; 506 | } else if (tree[ls].id1 == 0) { 507 | tree[o].id1 = tree[rs].id1; 508 | } else if (tree[rs].id1 == 0) { 509 | tree[o].id1 = tree[ls].id1; 510 | } else { 511 | tree[o].id1 = -1; 512 | } 513 | // id2 的合并 514 | if (tree[ls].id2 == -1 || tree[rs].id2 == -1) { 515 | tree[o].id2 = -1; 516 | } else if (tree[ls].id2 == tree[rs].id2) { 517 | tree[o].id2 = tree[ls].id2; 518 | } else { 519 | tree[o].id2 = -1; 520 | } 521 | // lid 的合并 522 | if (tree[ls].lid == -1 || tree[rs].lid == -1) { 523 | tree[o].lid = -1; 524 | } else if (tree[ls].lid == tree[rs].lid) { 525 | tree[o].lid = tree[ls].lid; 526 | } else { 527 | tree[o].lid = -1; 528 | } 529 | } 530 | 531 | void pushdown(int o) { 532 | // 线段树标记下传操作 533 | // 如果对应点未被创建,则进行创建 534 | if (!ls) 535 | ls = insert_node(); 536 | if (!rs) 537 | rs = insert_node(); 538 | if (tree[o].lazy_val != INF) { 539 | tree[ls].val = tree[rs].val = tree[o].lazy_val; 540 | tree[ls].lazy_val = tree[rs].lazy_val = tree[o].lazy_val; 541 | tree[o].lazy_val = INF; 542 | } 543 | if (tree[o].lazy_id1 != -1) { 544 | tree[ls].id1 = tree[rs].id1 = tree[o].lazy_id1; 545 | tree[ls].lazy_id1 = tree[rs].lazy_id1 = tree[o].lazy_id1; 546 | tree[o].lazy_id1 = -1; 547 | } 548 | if (tree[o].lazy_id2 != -1) { 549 | tree[ls].id2 = tree[rs].id2 = tree[o].lazy_id2; 550 | tree[ls].lazy_id2 = tree[rs].lazy_id2 = tree[o].lazy_id2; 551 | tree[o].lazy_id2 = -1; 552 | } 553 | if (tree[o].lazy_lid != -1) { 554 | tree[ls].lid = tree[rs].lid = tree[o].lazy_lid; 555 | tree[ls].lazy_lid = tree[rs].lazy_lid = tree[o].lazy_lid; 556 | tree[o].lazy_lid = -1; 557 | } 558 | } 559 | 560 | #define ALLOK -2 561 | int find_right(int o, int l, int r, int ql, int qid) { 562 | // 操作一中,固定左端点,寻找右端点可能的最大值 563 | // 这里没有考虑和右端点的比较,直接寻找了最大的可能值 564 | pushdown(o); 565 | if (r < ql || tree[o].id1 == qid || tree[o].id1 == 0) { 566 | // 全部符合条件 567 | return ALLOK; 568 | } else if (tree[o].id2 != -1) { 569 | // 不符合条件,返回该区域左边第一个 570 | return l - 1; 571 | } else { 572 | // 需要寻找确切位置 573 | // 先查找左区间,如果左区间全满足则再寻找右区间 574 | int mid = (l + r) >> 1; 575 | int leftPart = (ql <= mid) ? find_right(ls, l, mid, ql, qid) : ALLOK; 576 | return (leftPart == ALLOK) ? find_right(rs, mid + 1, r, ql, qid) 577 | : leftPart; 578 | } 579 | } 580 | #undef ALLOK 581 | 582 | void modify_val(int o, int l, int r, int ql, int qr, int val, int id, 583 | bool ignoreLid = false) { 584 | // 若 val = INF 代表不需要对 val 进行处理 585 | // 若 ignoreLid = true 则不对 lid 进行更改 586 | if (l >= ql && r <= qr) { 587 | if (val != INF) 588 | tree[o].val = tree[o].lazy_val = val; 589 | tree[o].id1 = tree[o].lazy_id1 = id; 590 | tree[o].id2 = tree[o].lazy_id2 = id; 591 | if (!ignoreLid) 592 | tree[o].lid = tree[o].lazy_lid = id; 593 | return; 594 | } 595 | pushdown(o); 596 | int mid = (l + r) >> 1; 597 | if (ql <= mid) { 598 | modify_val(ls, l, mid, ql, qr, val, id, ignoreLid); 599 | } 600 | if (qr > mid) { 601 | modify_val(rs, mid + 1, r, ql, qr, val, id, ignoreLid); 602 | } 603 | pushup(o); 604 | } 605 | 606 | bool is_same_id(int o, int l, int r, int ql, int qr, int id, 607 | bool isRecover = false) { 608 | // 判断该区域 id 和 lid 是否满足条件 609 | if (l >= ql && r <= qr) { 610 | if (isRecover) { 611 | // 检查 id = 0 且 lid = id 612 | return (tree[o].id2 == 0 && tree[o].lid == id); 613 | } else { 614 | // 检查 id = id 615 | return (tree[o].id2 == id); 616 | } 617 | } 618 | pushdown(o); 619 | int mid = (l + r) >> 1; 620 | bool isSame = true; 621 | if (ql <= mid) { 622 | isSame = isSame && is_same_id(ls, l, mid, ql, qr, id, isRecover); 623 | } 624 | if (qr > mid && isSame) { 625 | isSame = isSame && is_same_id(rs, mid + 1, r, ql, qr, id, isRecover); 626 | } 627 | return isSame; 628 | } 629 | 630 | int query_val(int o, int l, int r, int p) { 631 | // 线段树单点求值:val 632 | if (p >= l && p <= r && tree[o].val != INF) { 633 | return tree[o].val; 634 | } 635 | pushdown(o); 636 | int mid = (l + r) >> 1; 637 | if (p <= mid) 638 | return query_val(ls, l, mid, p); 639 | else 640 | return query_val(rs, mid + 1, r, p); 641 | } 642 | 643 | int query_id(int o, int l, int r, int p) { 644 | // 线段树单点求值:id2 645 | if (p >= l && p <= r && tree[o].id2 != -1) { 646 | return tree[o].id2; 647 | } 648 | pushdown(o); 649 | int mid = (l + r) >> 1; 650 | if (p <= mid) 651 | return query_id(ls, l, mid, p); 652 | else 653 | return query_id(rs, mid + 1, r, p); 654 | } 655 | 656 | #undef ls 657 | #undef rs 658 | 659 | int main() { 660 | scanf("%d%d%d", &n, &m, &k); 661 | // 创建根节点 662 | insert_node(); 663 | // 进行操作 664 | int r_opt, r_id, r_l, r_r, r_x, r_p; 665 | while (k--) { 666 | scanf("%d", &r_opt); 667 | if (r_opt == 0) { 668 | // 写入 669 | scanf("%d%d%d%d", &r_id, &r_l, &r_r, &r_x); 670 | int r = find_right(1, 1, m, r_l, r_id); 671 | if (r == -2) 672 | r = r_r; 673 | else 674 | r = min(r, r_r); 675 | if (r_l <= r) { 676 | printf("%d\n", r); 677 | modify_val(1, 1, m, r_l, r, r_x, r_id); 678 | } else { 679 | printf("-1\n"); 680 | } 681 | } else if (r_opt == 1) { 682 | // 删除 683 | scanf("%d%d%d", &r_id, &r_l, &r_r); 684 | if (is_same_id(1, 1, m, r_l, r_r, r_id)) { 685 | printf("OK\n"); 686 | modify_val(1, 1, m, r_l, r_r, INF, 0, true); 687 | } else { 688 | printf("FAIL\n"); 689 | } 690 | } else if (r_opt == 2) { 691 | // 恢复 692 | scanf("%d%d%d", &r_id, &r_l, &r_r); 693 | if (is_same_id(1, 1, m, r_l, r_r, r_id, true)) { 694 | printf("OK\n"); 695 | modify_val(1, 1, m, r_l, r_r, INF, r_id, true); 696 | } else { 697 | printf("FAIL\n"); 698 | } 699 | } else { 700 | // 查询 701 | scanf("%d", &r_p); 702 | int id = query_id(1, 1, m, r_p); 703 | int val = query_val(1, 1, m, r_p); 704 | if (id == 0) { 705 | printf("0 0\n"); 706 | } else { 707 | printf("%d %d\n", id, val); 708 | } 709 | } 710 | } 711 | return 0; 712 | } 713 | ``` 714 | -------------------------------------------------------------------------------- /docs/problem/24/4/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: problem.html 3 | tags: 4 | - 线段树 5 | hide: 6 | - tags 7 | --- 8 | # 202112-4 磁盘文件操作 9 | 10 | ## 题目链接 11 | 12 | [202112-4 磁盘文件操作](http://118.190.20.162/view.page?gpid=T135) 13 | 14 | ## 思路列表 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 49 | 50 | 51 | 52 | 53 |
题解文章得分要求大致思路题解语言链接
文章 125n,k≤2000,m≤10000 32 | 直接模拟 题解链接
文章 1100无特殊限制 40 | 离散化+线段树C++题解链接
文章 1100无特殊限制 48 | 动态开点线段树C++题解链接
-------------------------------------------------------------------------------- /docs/problem/24/5/1.md: -------------------------------------------------------------------------------- 1 | # 202112-5 极差路径 2 | 3 | -------------------------------------------------------------------------------- /docs/problem/24/5/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: problem.html 3 | --- 4 | # 202112-5 极差路径 5 | 6 | ## 题目链接 7 | 8 | [202112-5 极差路径](http://118.190.20.162/view.page?gpid=T134) 9 | 10 | ## 思路列表 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
题解文章得分要求大致思路题解语言链接
-------------------------------------------------------------------------------- /docs/problem/24/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: contest.html 3 | --- 4 | # 第 24 次(2021 年 12 月) 5 | 6 | 7 | | 题目编号 | 题目名称 | 涉及算法 | 最高得分 | 满分题解语言 | 链接 | 8 | | :-: | :-: | :-: | :-: | :-: | :-: | 9 | | 202112-1 | 序列查询 | 模拟 | 100 | C++、Java、Python 3 | [链接](1\index.md) | 10 | | 202112-2 | 序列查询新解 | 模拟、数学 | 100 | C++ | [链接](2\index.md) | 11 | | 202112-3 | 登机牌号码 | 模拟 | 100 | C++ | [链接](3\index.md) | 12 | | 202112-4 | 磁盘文件操作 | 线段树 | 100 | C++ | [链接](4\index.md) | 13 | | 202112-5 | 极差路径 | | | | [链接](5\index.md) | 14 | 15 | -------------------------------------------------------------------------------- /docs/problem/3/1/index.md: -------------------------------------------------------------------------------- 1 | # 201412-1 门禁系统 2 | 3 | ## 题目链接 4 | 5 | [201412-1 门禁系统](http://118.190.20.162/view.page?gpid=T21) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/3/2/index.md: -------------------------------------------------------------------------------- 1 | # 201412-2 Z字形扫描 2 | 3 | ## 题目链接 4 | 5 | [201412-2 Z字形扫描](http://118.190.20.162/view.page?gpid=T20) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/3/3/index.md: -------------------------------------------------------------------------------- 1 | # 201412-3 集合竞价 2 | 3 | ## 题目链接 4 | 5 | [201412-3 集合竞价](http://118.190.20.162/view.page?gpid=T19) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/3/4/index.md: -------------------------------------------------------------------------------- 1 | # 201412-4 最优灌溉 2 | 3 | ## 题目链接 4 | 5 | [201412-4 最优灌溉](http://118.190.20.162/view.page?gpid=T18) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/3/5/index.md: -------------------------------------------------------------------------------- 1 | # 201412-5 货物调度 2 | 3 | ## 题目链接 4 | 5 | [201412-5 货物调度](http://118.190.20.162/view.page?gpid=T17) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/3/index.md: -------------------------------------------------------------------------------- 1 | # 第 3 次(2014 年 12 月) 2 | 3 | 4 | | 题目编号 | 题目名称 | 涉及算法 | 最高得分 | 满分题解语言 | 链接 | 5 | | :-: | :-: | :-: | :-: | :-: | :-: | 6 | | 201412-1 | 门禁系统 | | | | [链接](1\index.md) | 7 | | 201412-2 | Z字形扫描 | | | | [链接](2\index.md) | 8 | | 201412-3 | 集合竞价 | | | | [链接](3\index.md) | 9 | | 201412-4 | 最优灌溉 | | | | [链接](4\index.md) | 10 | | 201412-5 | 货物调度 | | | | [链接](5\index.md) | 11 | -------------------------------------------------------------------------------- /docs/problem/4/1/index.md: -------------------------------------------------------------------------------- 1 | # 201503-1 图像旋转 2 | 3 | ## 题目链接 4 | 5 | [201503-1 图像旋转](http://118.190.20.162/view.page?gpid=T27) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/4/2/index.md: -------------------------------------------------------------------------------- 1 | # 201503-2 数字排序 2 | 3 | ## 题目链接 4 | 5 | [201503-2 数字排序](http://118.190.20.162/view.page?gpid=T26) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/4/3/index.md: -------------------------------------------------------------------------------- 1 | # 201503-3 节日 2 | 3 | ## 题目链接 4 | 5 | [201503-3 节日](http://118.190.20.162/view.page?gpid=T25) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/4/4/index.md: -------------------------------------------------------------------------------- 1 | # 201503-4 网络延时 2 | 3 | ## 题目链接 4 | 5 | [201503-4 网络延时](http://118.190.20.162/view.page?gpid=T24) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/4/5/index.md: -------------------------------------------------------------------------------- 1 | # 201503-5 最小花费 2 | 3 | ## 题目链接 4 | 5 | [201503-5 最小花费](http://118.190.20.162/view.page?gpid=T23) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/4/index.md: -------------------------------------------------------------------------------- 1 | # 第 4 次(2015 年 3 月) 2 | 3 | 4 | | 题目编号 | 题目名称 | 涉及算法 | 最高得分 | 满分题解语言 | 链接 | 5 | | :-: | :-: | :-: | :-: | :-: | :-: | 6 | | 201503-1 | 图像旋转 | | | | [链接](1\index.md) | 7 | | 201503-2 | 数字排序 | | | | [链接](2\index.md) | 8 | | 201503-3 | 节日 | | | | [链接](3\index.md) | 9 | | 201503-4 | 网络延时 | | | | [链接](4\index.md) | 10 | | 201503-5 | 最小花费 | | | | [链接](5\index.md) | 11 | -------------------------------------------------------------------------------- /docs/problem/5/1/index.md: -------------------------------------------------------------------------------- 1 | # 201509-1 数列分段 2 | 3 | ## 题目链接 4 | 5 | [201509-1 数列分段](http://118.190.20.162/view.page?gpid=T32) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/5/2/index.md: -------------------------------------------------------------------------------- 1 | # 201509-2 日期计算 2 | 3 | ## 题目链接 4 | 5 | [201509-2 日期计算](http://118.190.20.162/view.page?gpid=T31) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/5/3/index.md: -------------------------------------------------------------------------------- 1 | # 201509-3 模板生成系统 2 | 3 | ## 题目链接 4 | 5 | [201509-3 模板生成系统](http://118.190.20.162/view.page?gpid=T30) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/5/4/index.md: -------------------------------------------------------------------------------- 1 | # 201509-4 高速公路 2 | 3 | ## 题目链接 4 | 5 | [201509-4 高速公路](http://118.190.20.162/view.page?gpid=T29) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/5/5/index.md: -------------------------------------------------------------------------------- 1 | # 201509-5 最佳文章 2 | 3 | ## 题目链接 4 | 5 | [201509-5 最佳文章](http://118.190.20.162/view.page?gpid=T28) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/5/index.md: -------------------------------------------------------------------------------- 1 | # 第 5 次(2015 年 9 月) 2 | 3 | 4 | | 题目编号 | 题目名称 | 涉及算法 | 最高得分 | 满分题解语言 | 链接 | 5 | | :-: | :-: | :-: | :-: | :-: | :-: | 6 | | 201509-1 | 数列分段 | | | | [链接](1\index.md) | 7 | | 201509-2 | 日期计算 | | | | [链接](2\index.md) | 8 | | 201509-3 | 模板生成系统 | | | | [链接](3\index.md) | 9 | | 201509-4 | 高速公路 | | | | [链接](4\index.md) | 10 | | 201509-5 | 最佳文章 | | | | [链接](5\index.md) | 11 | -------------------------------------------------------------------------------- /docs/problem/6/1/index.md: -------------------------------------------------------------------------------- 1 | # 201512-1 数位之和 2 | 3 | ## 题目链接 4 | 5 | [201512-1 数位之和](http://118.190.20.162/view.page?gpid=T37) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/6/2/index.md: -------------------------------------------------------------------------------- 1 | # 201512-2 消除类游戏 2 | 3 | ## 题目链接 4 | 5 | [201512-2 消除类游戏](http://118.190.20.162/view.page?gpid=T36) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/6/3/index.md: -------------------------------------------------------------------------------- 1 | # 201512-3 画图 2 | 3 | ## 题目链接 4 | 5 | [201512-3 画图](http://118.190.20.162/view.page?gpid=T35) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/6/4/index.md: -------------------------------------------------------------------------------- 1 | # 201512-4 送货 2 | 3 | ## 题目链接 4 | 5 | [201512-4 送货](http://118.190.20.162/view.page?gpid=T34) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/6/5/index.md: -------------------------------------------------------------------------------- 1 | # 201512-5 矩阵 2 | 3 | ## 题目链接 4 | 5 | [201512-5 矩阵](http://118.190.20.162/view.page?gpid=T33) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/6/index.md: -------------------------------------------------------------------------------- 1 | # 第 6 次(2015 年 12 月) 2 | 3 | 4 | | 题目编号 | 题目名称 | 涉及算法 | 最高得分 | 满分题解语言 | 链接 | 5 | | :-: | :-: | :-: | :-: | :-: | :-: | 6 | | 201512-1 | 数位之和 | | | | [链接](1\index.md) | 7 | | 201512-2 | 消除类游戏 | | | | [链接](2\index.md) | 8 | | 201512-3 | 画图 | | | | [链接](3\index.md) | 9 | | 201512-4 | 送货 | | | | [链接](4\index.md) | 10 | | 201512-5 | 矩阵 | | | | [链接](5\index.md) | 11 | -------------------------------------------------------------------------------- /docs/problem/7/1/index.md: -------------------------------------------------------------------------------- 1 | # 201604-1 折点计数 2 | 3 | ## 题目链接 4 | 5 | [201604-1 折点计数](http://118.190.20.162/view.page?gpid=T42) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/7/2/index.md: -------------------------------------------------------------------------------- 1 | # 201604-2 俄罗斯方块 2 | 3 | ## 题目链接 4 | 5 | [201604-2 俄罗斯方块](http://118.190.20.162/view.page?gpid=T41) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/7/3/index.md: -------------------------------------------------------------------------------- 1 | # 201604-3 路径解析 2 | 3 | ## 题目链接 4 | 5 | [201604-3 路径解析](http://118.190.20.162/view.page?gpid=T40) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/7/4/index.md: -------------------------------------------------------------------------------- 1 | # 201604-4 游戏 2 | 3 | ## 题目链接 4 | 5 | [201604-4 游戏](http://118.190.20.162/view.page?gpid=T39) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/7/5/index.md: -------------------------------------------------------------------------------- 1 | # 201604-5 网络连接 2 | 3 | ## 题目链接 4 | 5 | [201604-5 网络连接](http://118.190.20.162/view.page?gpid=T38) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/7/index.md: -------------------------------------------------------------------------------- 1 | # 第 7 次(2016 年 4 月) 2 | 3 | 4 | | 题目编号 | 题目名称 | 涉及算法 | 最高得分 | 满分题解语言 | 链接 | 5 | | :-: | :-: | :-: | :-: | :-: | :-: | 6 | | 201604-1 | 折点计数 | | | | [链接](1\index.md) | 7 | | 201604-2 | 俄罗斯方块 | | | | [链接](2\index.md) | 8 | | 201604-3 | 路径解析 | | | | [链接](3\index.md) | 9 | | 201604-4 | 游戏 | | | | [链接](4\index.md) | 10 | | 201604-5 | 网络连接 | | | | [链接](5\index.md) | 11 | -------------------------------------------------------------------------------- /docs/problem/8/1/index.md: -------------------------------------------------------------------------------- 1 | # 201609-1 最大波动 2 | 3 | ## 题目链接 4 | 5 | [201609-1 最大波动](http://118.190.20.162/view.page?gpid=T47) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/8/2/index.md: -------------------------------------------------------------------------------- 1 | # 201609-2 火车购票 2 | 3 | ## 题目链接 4 | 5 | [201609-2 火车购票](http://118.190.20.162/view.page?gpid=T46) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/8/3/index.md: -------------------------------------------------------------------------------- 1 | # 201609-3 炉石传说 2 | 3 | ## 题目链接 4 | 5 | [201609-3 炉石传说](http://118.190.20.162/view.page?gpid=T45) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/8/4/index.md: -------------------------------------------------------------------------------- 1 | # 201609-4 交通规划 2 | 3 | ## 题目链接 4 | 5 | [201609-4 交通规划](http://118.190.20.162/view.page?gpid=T44) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/8/5/index.md: -------------------------------------------------------------------------------- 1 | # 201609-5 祭坛 2 | 3 | ## 题目链接 4 | 5 | [201609-5 祭坛](http://118.190.20.162/view.page?gpid=T43) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/8/index.md: -------------------------------------------------------------------------------- 1 | # 第 8 次(2016 年 9 月) 2 | 3 | 4 | | 题目编号 | 题目名称 | 涉及算法 | 最高得分 | 满分题解语言 | 链接 | 5 | | :-: | :-: | :-: | :-: | :-: | :-: | 6 | | 201609-1 | 最大波动 | | | | [链接](1\index.md) | 7 | | 201609-2 | 火车购票 | | | | [链接](2\index.md) | 8 | | 201609-3 | 炉石传说 | | | | [链接](3\index.md) | 9 | | 201609-4 | 交通规划 | | | | [链接](4\index.md) | 10 | | 201609-5 | 祭坛 | | | | [链接](5\index.md) | 11 | -------------------------------------------------------------------------------- /docs/problem/9/1/index.md: -------------------------------------------------------------------------------- 1 | # 201612-1 中间数 2 | 3 | ## 题目链接 4 | 5 | [201612-1 中间数](http://118.190.20.162/view.page?gpid=T52) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/9/2/index.md: -------------------------------------------------------------------------------- 1 | # 201612-2 工资计算 2 | 3 | ## 题目链接 4 | 5 | [201612-2 工资计算](http://118.190.20.162/view.page?gpid=T51) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/9/3/index.md: -------------------------------------------------------------------------------- 1 | # 201612-3 权限查询 2 | 3 | ## 题目链接 4 | 5 | [201612-3 权限查询](http://118.190.20.162/view.page?gpid=T50) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/9/4/index.md: -------------------------------------------------------------------------------- 1 | # 201612-4 压缩编码 2 | 3 | ## 题目链接 4 | 5 | [201612-4 压缩编码](http://118.190.20.162/view.page?gpid=T49) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/9/5/index.md: -------------------------------------------------------------------------------- 1 | # 201612-5 卡牌游戏 2 | 3 | ## 题目链接 4 | 5 | [201612-5 卡牌游戏](http://118.190.20.162/view.page?gpid=T48) 6 | 7 | ## 思路列表 8 | 9 | | 贡献者 | 期望得分 | 大概思路 | 使用语言 | 链接 | 10 | | :-: | :-: | :-: | :-: | :-: | 11 | | | | | | | 12 | -------------------------------------------------------------------------------- /docs/problem/9/index.md: -------------------------------------------------------------------------------- 1 | # 第 9 次(2016 年 12 月) 2 | 3 | 4 | | 题目编号 | 题目名称 | 涉及算法 | 最高得分 | 满分题解语言 | 链接 | 5 | | :-: | :-: | :-: | :-: | :-: | :-: | 6 | | 201612-1 | 中间数 | | | | [链接](1\index.md) | 7 | | 201612-2 | 工资计算 | | | | [链接](2\index.md) | 8 | | 201612-3 | 权限查询 | | | | [链接](3\index.md) | 9 | | 201612-4 | 压缩编码 | | | | [链接](4\index.md) | 10 | | 201612-5 | 卡牌游戏 | | | | [链接](5\index.md) | 11 | -------------------------------------------------------------------------------- /docs/problem/index.md: -------------------------------------------------------------------------------- 1 | # 题目列表 2 | 3 | 您可以先选择对应场次,再选择对应的题目。 4 | 5 | === "逆序(已更新及更新中)" 6 | 7 | - [第 24 次] 8 | - [第 23 次] 9 | - [第 22 次] 10 | 11 | === "逆序(所有)" 12 | 13 | - [第 24 次] 14 | - [第 23 次] 15 | - [第 22 次] 16 | - [第 21 次] 17 | - [第 20 次] 18 | - [第 19 次] 19 | - [第 18 次] 20 | - [第 17 次] 21 | - [第 16 次] 22 | - [第 15 次] 23 | - [第 14 次] 24 | - [第 13 次] 25 | - [第 12 次] 26 | - [第 11 次] 27 | - [第 10 次] 28 | - [第 9 次] 29 | - [第 8 次] 30 | - [第 7 次] 31 | - [第 6 次] 32 | - [第 5 次] 33 | - [第 4 次] 34 | - [第 3 次] 35 | - [第 2 次] 36 | - [第 1 次] 37 | 38 | === "正序(所有)" 39 | 40 | - [第 1 次] 41 | - [第 2 次] 42 | - [第 3 次] 43 | - [第 4 次] 44 | - [第 5 次] 45 | - [第 6 次] 46 | - [第 7 次] 47 | - [第 8 次] 48 | - [第 9 次] 49 | - [第 10 次] 50 | - [第 11 次] 51 | - [第 12 次] 52 | - [第 13 次] 53 | - [第 14 次] 54 | - [第 15 次] 55 | - [第 16 次] 56 | - [第 17 次] 57 | - [第 18 次] 58 | - [第 19 次] 59 | - [第 20 次] 60 | - [第 21 次] 61 | - [第 22 次] 62 | - [第 23 次] 63 | - [第 24 次] 64 | 65 | 66 | [第 1 次]: 1/index.md 67 | [第 2 次]: 2/index.md 68 | [第 3 次]: 3/index.md 69 | [第 4 次]: 4/index.md 70 | [第 5 次]: 5/index.md 71 | [第 6 次]: 6/index.md 72 | [第 7 次]: 7/index.md 73 | [第 8 次]: 8/index.md 74 | [第 9 次]: 9/index.md 75 | [第 10 次]: 10/index.md 76 | [第 11 次]: 11/index.md 77 | [第 12 次]: 12/index.md 78 | [第 13 次]: 13/index.md 79 | [第 14 次]: 14/index.md 80 | [第 15 次]: 15/index.md 81 | [第 16 次]: 16/index.md 82 | [第 17 次]: 17/index.md 83 | [第 18 次]: 18/index.md 84 | [第 19 次]: 19/index.md 85 | [第 20 次]: 20/index.md 86 | [第 21 次]: 21/index.md 87 | [第 22 次]: 22/index.md 88 | [第 23 次]: 23/index.md 89 | [第 24 次]: 24/index.md -------------------------------------------------------------------------------- /docs/tags.md: -------------------------------------------------------------------------------- 1 | # 标签浏览 2 | 3 | [TAGS] -------------------------------------------------------------------------------- /docs/test_pages/test.md: -------------------------------------------------------------------------------- 1 | # 测试页面 2 | 3 | 这是一个测试页面。 -------------------------------------------------------------------------------- /docs/test_pages/unfinished.md: -------------------------------------------------------------------------------- 1 | # 当前页面没有内容 2 | 3 | 很抱歉,您目前浏览的页面没有任何内容。由于人手不足等限制,我们目前没有完成此页面的编辑。 4 | 5 | 我们将会在之后更新。 -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: CSP Project 2 | site_url: https://ccf-csp-project.github.io/CSP-Project-with-MkDocs/ 3 | repo_url: https://github.com/ccf-csp-project/CSP-Project-with-MkDocs 4 | repo_name: CSP Project with MkDocs 5 | theme: 6 | name: material 7 | language: zh 8 | custom_dir: overrides 9 | features: 10 | - navigation.indexes 11 | - navigation.tabs 12 | - navigation.tracking 13 | 14 | nav: 15 | - 简介: 16 | - index.md 17 | - 关于本项目: introduction/about.md 18 | - 如何参与: introduction/contributing.md 19 | - 如何编写自己的题解页面: introduction/write_passage.md 20 | - 常见问题解答: introduction/faq.md 21 | - 题目列表: 22 | - problem/index.md 23 | - 第 24 次: 24 | - problem/24/index.md 25 | - 202112-1 序列查询: 26 | - problem/24/1/index.md 27 | - 文章 1: problem/24/1/1.md 28 | - 202112-2 序列查询新解: 29 | - problem/24/2/index.md 30 | - 文章 1: problem/24/2/1.md 31 | - 文章 2: problem/24/2/2.md 32 | - 202112-3 登机牌号码: 33 | - problem/24/3/index.md 34 | - 文章 1: problem/24/3/1.md 35 | - 202112-4 磁盘文件操作: 36 | - problem/24/4/index.md 37 | - 文章 1: problem/24/4/1.md 38 | - 第 23 次: 39 | - problem/23/index.md 40 | - 202109-1 数组推导: 41 | - problem/23/1/index.md 42 | - 文章 1: problem/23/1/1.md 43 | - 202109-2 非零段划分: 44 | - problem/23/2/index.md 45 | - 文章 1: problem/23/2/1.md 46 | - 202109-3 脉冲神经网络: 47 | - problem/23/3/index.md 48 | - 文章 1: problem/23/3/1.md 49 | - 202109-4 收集卡牌: 50 | - problem/23/4/index.md 51 | - 文章 1: problem/23/4/1.md 52 | - 202109-5 箱根山岳险天下: 53 | - problem/23/5/index.md 54 | - 文章 1: problem/23/5/1.md 55 | - 第 22 次: 56 | - problem/22/index.md 57 | - 202104-1 灰度直方图: 58 | - problem/22/1/index.md 59 | - 文章 1: problem/22/1/1.md 60 | - 202104-2 邻域均值: 61 | - problem/22/2/index.md 62 | - 文章 1: problem/22/2/1.md 63 | - 202104-3 DHCP服务器: 64 | - problem/22/3/index.md 65 | - 文章 1: problem/22/3/1.md 66 | - 202104-4 校门外的树: 67 | - problem/22/4/index.md 68 | - 文章 1: problem/22/4/1.md 69 | - 第 21 次: 70 | - problem/21/index.md 71 | - 202012-1 期末预测之安全指数: 72 | - problem/21/1/index.md 73 | - 文章 1: problem/21/1/1.md 74 | - 知识库: 75 | - knowledge/index.md 76 | - 标签搜索: tags.md 77 | - 数据结构: 78 | - Link Cut Tree: 79 | - knowledge/ds/lct/index.md 80 | 81 | markdown_extensions: 82 | - pymdownx.arithmatex: 83 | generic: true 84 | - pymdownx.highlight: 85 | anchor_linenums: true 86 | - pymdownx.inlinehilite 87 | - pymdownx.snippets 88 | - pymdownx.superfences 89 | - admonition 90 | - pymdownx.details 91 | - pymdownx.superfences 92 | - attr_list 93 | - pymdownx.tabbed: 94 | alternate_style: true 95 | - tables 96 | - def_list 97 | - pymdownx.keys 98 | - pymdownx.critic 99 | - pymdownx.caret 100 | - pymdownx.mark 101 | - pymdownx.tilde 102 | - md_in_html 103 | extra_javascript: 104 | - https://code.jquery.com/jquery-3.6.0.slim.min.js 105 | - javascripts/mathjax.js 106 | - https://polyfill.io/v3/polyfill.min.js?features=es6 107 | - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js 108 | - https://cdn.datatables.net/1.11.4/js/jquery.dataTables.js 109 | - javascripts/site.js 110 | extra_css: 111 | - https://cdn.datatables.net/1.11.4/css/jquery.dataTables.css 112 | 113 | plugins: 114 | - tags: 115 | tags_file: tags.md 116 | - search: 117 | separator: '[\s\-\.]' -------------------------------------------------------------------------------- /overrides/contest.html: -------------------------------------------------------------------------------- 1 | {% extends "main.html" %} -------------------------------------------------------------------------------- /overrides/knowledge.html: -------------------------------------------------------------------------------- 1 | {% extends "main.html" %} 2 | 3 | {% block content %} 4 | {{ super() }} 5 | 6 | 7 |

{{ lang.t("meta.comments") }}

8 | 13 | 14 | 15 | 41 | {% endblock %} -------------------------------------------------------------------------------- /overrides/main.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} -------------------------------------------------------------------------------- /overrides/problem.html: -------------------------------------------------------------------------------- 1 | {% extends "main.html" %} 2 | 3 | {% block content %} 4 | {{ super() }} 5 | 6 | 7 |

{{ lang.t("meta.comments") }}

8 | 13 | 14 | 15 | 41 | {% endblock %} -------------------------------------------------------------------------------- /overrides/solution.html: -------------------------------------------------------------------------------- 1 | {% extends "main.html" %} 2 | 3 | {% block content %} 4 | {{ super() }} 5 | 6 | 7 |

{{ lang.t("meta.comments") }}

8 | 13 | 14 | 15 | 41 | {% endblock %} --------------------------------------------------------------------------------