From a09a4d6d4755b1712ff97b5955be73bae066390b Mon Sep 17 00:00:00 2001 From: Josh-Cena Date: Thu, 22 Apr 2021 17:47:23 +0800 Subject: [PATCH 1/8] Add i18n - Default language is Chinese (zh-Hans) - Provide translation to a few texts - TODO: translate the docs --- docusaurus.config.js | 36 ++- i18n/en/code.json | 218 ++++++++++++++++++ .../current.json | 18 ++ i18n/en/docusaurus-theme-classic/footer.json | 30 +++ i18n/en/docusaurus-theme-classic/navbar.json | 22 ++ package.json | 2 + src/components/AlumniTimeline.tsx | 7 +- src/pages/alumni.tsx | 26 ++- src/pages/index.js | 56 +++-- 9 files changed, 377 insertions(+), 38 deletions(-) create mode 100644 i18n/en/code.json create mode 100644 i18n/en/docusaurus-plugin-content-docs/current.json create mode 100644 i18n/en/docusaurus-theme-classic/footer.json create mode 100644 i18n/en/docusaurus-theme-classic/navbar.json diff --git a/docusaurus.config.js b/docusaurus.config.js index 09a4ddec..b840e059 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -17,18 +17,34 @@ module.exports = { favicon: 'img/favicon/favicon.ico', organizationName: 'Computerization', // Usually your GitHub org/user name. projectName: 'computerization.github.io', // Usually your repo name. + i18n: { + defaultLocale: 'zh-Hans', + locales: ['zh-Hans', 'en'], + localeConfigs: { + 'zh-Hans': { + label: '中文', + }, + en: { + label: 'English', + }, + }, + }, themeConfig: { navbar: { - title: 'Computerization', + title: '信息化社', logo: { alt: 'Computerization Logo', src: 'img/logo.svg', srcDark: 'img/logo.svg', }, items: [ - { to: 'alumni', label: 'Alumni', position: 'left' }, - { to: 'docs/about-us', label: 'Docs', position: 'left' }, - { to: 'blog', label: 'Blog', position: 'left' }, + { to: 'alumni', label: '成员', position: 'left' }, + { to: 'docs/about-us', label: '文档', position: 'left' }, + { to: 'blog', label: '博客', position: 'left' }, + { + type: 'localeDropdown', + position: 'right', + }, { href: 'https://github.com/Computerization', label: 'GitHub', @@ -40,16 +56,16 @@ module.exports = { style: 'dark', links: [ { - title: 'Docs', + title: '文档', items: [ { - label: 'Docs', + label: '文档', to: 'docs/about-us', }, ], }, { - title: 'Community', + title: '社区', items: [ { label: 'GitHub', @@ -58,10 +74,10 @@ module.exports = { ], }, { - title: 'Social', + title: '社交', items: [ { - label: 'Blog', + label: '博客', to: 'blog', }, ], @@ -71,7 +87,7 @@ module.exports = { alt: 'Computerization Logo', src: 'img/logo.svg', }, - copyright: `Copyright © ${new Date().getFullYear()} Computerization. Built with Docusaurus.`, + copyright: `信息化社 © ${new Date().getFullYear()} 版权所有. 使用 Docusaurus 搭建.`, }, }, stylesheets: [ diff --git a/i18n/en/code.json b/i18n/en/code.json new file mode 100644 index 00000000..15e5b2ec --- /dev/null +++ b/i18n/en/code.json @@ -0,0 +1,218 @@ +{ + "theme.NotFound.title": { + "message": "Page Not Found", + "description": "The title of the 404 page" + }, + "theme.NotFound.p1": { + "message": "We could not find what you were looking for.", + "description": "The first paragraph of the 404 page" + }, + "theme.NotFound.p2": { + "message": "Please contact the owner of the site that linked you to the original URL and let them know their link is broken.", + "description": "The 2nd paragraph of the 404 page" + }, + "theme.AnnouncementBar.closeButtonAriaLabel": { + "message": "Close", + "description": "The ARIA label for close button of announcement bar" + }, + "theme.blog.paginator.navAriaLabel": { + "message": "Blog list page navigation", + "description": "The ARIA label for the blog pagination" + }, + "theme.blog.paginator.newerEntries": { + "message": "Newer Entries", + "description": "The label used to navigate to the newer blog posts page (previous page)" + }, + "theme.blog.paginator.olderEntries": { + "message": "Older Entries", + "description": "The label used to navigate to the older blog posts page (next page)" + }, + "theme.blog.post.readingTime.plurals": { + "message": "One min read|{readingTime} min read", + "description": "Pluralized label for \"{readingTime} min read\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)" + }, + "theme.tags.tagsListLabel": { + "message": "Tags:", + "description": "The label alongside a tag list" + }, + "theme.blog.post.readMore": { + "message": "Read More", + "description": "The label used in blog post item excerpts to link to full blog posts" + }, + "theme.blog.post.paginator.navAriaLabel": { + "message": "Blog post page navigation", + "description": "The ARIA label for the blog posts pagination" + }, + "theme.blog.post.paginator.newerPost": { + "message": "Newer Post", + "description": "The blog post button label to navigate to the newer/previous post" + }, + "theme.blog.post.paginator.olderPost": { + "message": "Older Post", + "description": "The blog post button label to navigate to the older/next post" + }, + "theme.tags.tagsPageTitle": { + "message": "Tags", + "description": "The title of the tag list page" + }, + "theme.blog.post.plurals": { + "message": "One post|{count} posts", + "description": "Pluralized label for \"{count} posts\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)" + }, + "theme.blog.tagTitle": { + "message": "{nPosts} tagged with \"{tagName}\"", + "description": "The title of the page for a blog tag" + }, + "theme.tags.tagsPageLink": { + "message": "View All Tags", + "description": "The label of the link targeting the tag list page" + }, + "theme.CodeBlock.copyButtonAriaLabel": { + "message": "Copy code to clipboard", + "description": "The ARIA label for copy code blocks button" + }, + "theme.CodeBlock.copied": { + "message": "Copied", + "description": "The copied button label on code blocks" + }, + "theme.CodeBlock.copy": { + "message": "Copy", + "description": "The copy button label on code blocks" + }, + "theme.docs.sidebar.expandButtonTitle": { + "message": "Expand sidebar", + "description": "The ARIA label and title attribute for expand button of doc sidebar" + }, + "theme.docs.sidebar.expandButtonAriaLabel": { + "message": "Expand sidebar", + "description": "The ARIA label and title attribute for expand button of doc sidebar" + }, + "theme.docs.paginator.navAriaLabel": { + "message": "Docs pages navigation", + "description": "The ARIA label for the docs pagination" + }, + "theme.docs.paginator.previous": { + "message": "Previous", + "description": "The label used to navigate to the previous doc" + }, + "theme.docs.paginator.next": { + "message": "Next", + "description": "The label used to navigate to the next doc" + }, + "theme.docs.sidebar.responsiveCloseButtonLabel": { + "message": "Close menu", + "description": "The ARIA label for close button of mobile doc sidebar" + }, + "theme.docs.sidebar.responsiveOpenButtonLabel": { + "message": "Open menu", + "description": "The ARIA label for open button of mobile doc sidebar" + }, + "theme.docs.sidebar.collapseButtonTitle": { + "message": "Collapse sidebar", + "description": "The title attribute for collapse button of doc sidebar" + }, + "theme.docs.sidebar.collapseButtonAriaLabel": { + "message": "Collapse sidebar", + "description": "The title attribute for collapse button of doc sidebar" + }, + "theme.docs.versions.unreleasedVersionLabel": { + "message": "This is unreleased documentation for {siteTitle} {versionLabel} version.", + "description": "The label used to tell the user that he's browsing an unreleased doc version" + }, + "theme.docs.versions.unmaintainedVersionLabel": { + "message": "This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained.", + "description": "The label used to tell the user that he's browsing an unmaintained doc version" + }, + "theme.docs.versions.latestVersionSuggestionLabel": { + "message": "For up-to-date documentation, see the {latestVersionLink} ({versionLabel}).", + "description": "The label userd to tell the user that he's browsing an unmaintained doc version" + }, + "theme.docs.versions.latestVersionLinkLabel": { + "message": "latest version", + "description": "The label used for the latest version suggestion link label" + }, + "theme.common.editThisPage": { + "message": "Edit this page", + "description": "The link label to edit the current page" + }, + "theme.common.headingLinkTitle": { + "message": "Direct link to heading", + "description": "Title for link to heading" + }, + "theme.lastUpdated.atDate": { + "message": " on {date}", + "description": "The words used to describe on which date a page has been last updated" + }, + "theme.lastUpdated.byUser": { + "message": " by {user}", + "description": "The words used to describe by who the page has been last updated" + }, + "theme.lastUpdated.lastUpdatedAtBy": { + "message": "Last updated{atDate}{byUser}", + "description": "The sentence used to display when a page has been last updated, and by who" + }, + "theme.common.skipToMainContent": { + "message": "Skip to main content", + "description": "The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation" + }, + "frontpage.button": { + "message": "Read more", + "description": "The button that navigates to the docs" + }, + "frontpage.sec1": { + "message": "Our activities", + "description": "The first section title" + }, + "frontpage.sec1.item1.title": { + "message": "Web development", + "description": "Title to the first item in the activities section" + }, + "frontpage.sec1.item1": { + "message": "At Computerization, learn front-end frameworks including {link1} and {link2}, develop collaboratively on GitHub, and utilize the skills accrued to create your own personal page. Engage in the club's platform building and demonstrate your unique creativity!", + "description": "The first item in the activities section" + }, + "frontpage.sec1.item2.title": { + "message": "Algorithm contests", + "description": "Title to the second item in the activities section" + }, + "frontpage.sec1.item2": { + "message": "At Computerization, share your coding experience with other contest masters, and probe deeper into data structures and algorithms. Prepare for NOIP China, and join LeetCode or Luogu contests. Improve yourself through trials and tribulations!", + "description": "The second item in the activities section" + }, + "frontpage.sec1.item3.title": { + "message": "Explore artificial intelligence", + "description": "Title to the third item in the activities section" + }, + "frontpage.sec1.item3": { + "message": "At Computeriztaion, learn the cutting-edge technology, discover the secrets behind artificial intelligence and machine learning, design a neural network yourself, and train it to realize any kind of your craziest dreams!", + "description": "The third item in the activities section" + }, + "frontpage.sec1.imgsrc": { + "message": "Image source: ", + "description": "The declaration of image source" + }, + "frontpage.sec1.imgsrc.link": { + "message": "Docusaurus official documentation", + "description": "The link name of image source" + }, + "frontpage.sec2.title": { + "message": "What's new", + "description": "The second section title" + }, + "frontpage.sec2.item1": { + "message": "Our homepage is officially here!", + "description": "The first item in the What's new section" + }, + "alumni.title": { + "message": "Our Alumni", + "description": "The title of the alumni page" + }, + "alumni.description": { + "message": "If you are an alumnus or an alumna of the Computerization club and would like us to update your listing or link to your homepage, please open an issue or pull request at the {link} repository, or drop us a WeChat message.", + "description": "The description of the alumni page" + }, + "alumni.classOf": { + "message": "Class of {classOf}", + "description": "The section label for each class" + } +} diff --git a/i18n/en/docusaurus-plugin-content-docs/current.json b/i18n/en/docusaurus-plugin-content-docs/current.json new file mode 100644 index 00000000..e6e9e52b --- /dev/null +++ b/i18n/en/docusaurus-plugin-content-docs/current.json @@ -0,0 +1,18 @@ +{ + "version.label": { + "message": "Next", + "description": "The label for version current" + }, + "sidebar.docs.category.关于我们": { + "message": "About us", + "description": "The label for category 关于我们 in sidebar docs" + }, + "sidebar.docs.category.我们的活动": { + "message": "Our activities", + "description": "The label for category 我们的活动 in sidebar docs" + }, + "sidebar.docs.category.Enspire": { + "message": "Enspire", + "description": "The label for category Enspire in sidebar docs" + } +} diff --git a/i18n/en/docusaurus-theme-classic/footer.json b/i18n/en/docusaurus-theme-classic/footer.json new file mode 100644 index 00000000..34b5ece8 --- /dev/null +++ b/i18n/en/docusaurus-theme-classic/footer.json @@ -0,0 +1,30 @@ +{ + "link.title.文档": { + "message": "Docs", + "description": "The title of the footer links column with title=Docs in the footer" + }, + "link.title.社区": { + "message": "Community", + "description": "The title of the footer links column with title=Community in the footer" + }, + "link.title.社交": { + "message": "Social", + "description": "The title of the footer links column with title=Social in the footer" + }, + "link.item.label.文档": { + "message": "Docs", + "description": "The label of footer link with label=Docs linking to docs/about-us" + }, + "link.item.label.GitHub": { + "message": "GitHub", + "description": "The label of footer link with label=GitHub linking to https://github.com/Computerization" + }, + "link.item.label.博客": { + "message": "Blog", + "description": "The label of footer link with label=Blog linking to blog" + }, + "copyright": { + "message": "Copyright © 2021 Computerization. Built with Docusaurus.", + "description": "The footer copyright" + } +} diff --git a/i18n/en/docusaurus-theme-classic/navbar.json b/i18n/en/docusaurus-theme-classic/navbar.json new file mode 100644 index 00000000..2e928dfc --- /dev/null +++ b/i18n/en/docusaurus-theme-classic/navbar.json @@ -0,0 +1,22 @@ +{ + "title": { + "message": "Computerization", + "description": "The title in the navbar" + }, + "item.label.成员": { + "message": "Alumni", + "description": "Navbar item with label 成员" + }, + "item.label.文档": { + "message": "Docs", + "description": "Navbar item with label 文档" + }, + "item.label.博客": { + "message": "Blog", + "description": "Navbar item with label 博客" + }, + "item.label.GitHub": { + "message": "GitHub", + "description": "Navbar item with label GitHub" + } +} diff --git a/package.json b/package.json index 33015cd1..5ba39655 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,8 @@ "build": "docusaurus build", "swizzle": "docusaurus swizzle", "deploy": "docusaurus deploy", + "write-translations": "docusaurus write-translations", + "write-heading-ids": "docusaurus write-heading-ids", "format": "prettier --write '**/*.{js,jsx,ts,tsx,html,css}'", "format:check": "prettier --check '**/*.{js,jsx,ts,tsx,html,css}'", "lint": "eslint . --ext=js,jsx,ts,tsx", diff --git a/src/components/AlumniTimeline.tsx b/src/components/AlumniTimeline.tsx index f784943c..4c9f2888 100644 --- a/src/components/AlumniTimeline.tsx +++ b/src/components/AlumniTimeline.tsx @@ -1,4 +1,5 @@ import React, { ReactElement } from 'react'; +import Translate from '@docusaurus/Translate'; import styles from './AlumniTimeline.module.css'; import MemberList from './Members'; @@ -18,7 +19,11 @@ const AlumniTimeline = ({ alumni }: AlumniProps): ReactElement => (
-

Class of {classOf}

+

+ + {'{classOf} 届'} + +

diff --git a/src/pages/alumni.tsx b/src/pages/alumni.tsx index 646d50b3..a3271ab3 100644 --- a/src/pages/alumni.tsx +++ b/src/pages/alumni.tsx @@ -7,6 +7,7 @@ import React, { ReactElement } from 'react'; import Layout from '@theme/Layout'; +import Translate from '@docusaurus/Translate'; import AlumniTimeline from '../components/AlumniTimeline'; import styles from './alumni.module.css'; @@ -21,15 +22,24 @@ export default function Alumni(): ReactElement {
-

Our Alumni

+

+ 我们的过往成员 +

- If you are an alumnus or an alumna of the Computerization club and - would like us to update your listing or link to your homepage, - please open an issue or pull request at the{' '} - - Computerization/docusaurus - {' '} - repository, or drop us a WeChat message. + + Computerization/docusaurus + + ), + }} + > + { + '如果你是信息化社的过往成员,并且希望我们更新你的个人信息或链接,请在 {link} 仓库中提交 issue 或 pull request。你也可以微信联系我们。' + } +

diff --git a/src/pages/index.js b/src/pages/index.js index 7e3bfa7b..caa0af4a 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -9,41 +9,47 @@ import React from 'react'; import classnames from 'classnames'; import Layout from '@theme/Layout'; import Link from '@docusaurus/Link'; +import Translate from '@docusaurus/Translate'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import useBaseUrl from '@docusaurus/useBaseUrl'; import styles from './styles.module.css'; const features = [ { - title: <>Web 开发, + title: Web 开发, imageUrl: 'img/undraw_version_control.svg', description: ( - <> - 在C社,学习 Vue,{' '} - Docusaurus 等多个前端框架,使用 - GitHub 进行多人合作项目开发,并用所学的技巧创建自己的个人页面, - 参与社团平台搭建,充分展现你的创意与才智! - + Vue, + link2: Docusaurus, + }} + > + { + '在C社,学习 {link1}, {link2}等多个前端框架,使用 GitHub 进行多人合作项目开发,并用所学的技巧创建自己的个人页面,参与社团平台搭建,充分展现你的创意与才智!' + } + ), }, { - title: <>算法竞赛, + title: 算法竞赛, imageUrl: 'img/undraw_docusaurus_tree.svg', description: ( - <> + 在C社,与大佬交流竞赛经验与技巧,深入了解各类数据结构与算法,备赛NOIP, 组队参加力扣周赛、洛谷月赛等算法竞赛,在磨练中提升自己的功力! - + ), }, { - title: <>人工智能探索, + title: 人工智能探索, imageUrl: 'img/undraw_docusaurus_react.svg', description: ( - <> + 在C社,感受时代科技的前沿,探究人工智能与机器学习的奥秘, 亲手设计一个自己的神经网络,并训练它做一切你能想象得到的疯狂的事! - + ), }, ]; @@ -69,7 +75,7 @@ function Home() { id={styles.getStarted} to={useBaseUrl('docs/about-us')} > - 了解更多 + 了解更多
@@ -80,7 +86,9 @@ function Home() {
-

我们的活动

+

+ 我们的活动 +

@@ -109,8 +117,12 @@ function Home() {
- 图片来源: - Docusaurus 官方文档 + 图片来源: + + + Docusaurus 官方文档 + +
@@ -121,11 +133,17 @@ function Home() {
-

最新动态

+

+ 最新动态 +

-
我们的主页正式上线了!
+
+ + 我们的主页正式上线了! + +
From d18d0ee3cfc162e23dd32725d8f1cde0b75907af Mon Sep 17 00:00:00 2001 From: Josh-Cena Date: Thu, 22 Apr 2021 20:00:22 +0800 Subject: [PATCH 2/8] Add ESLint override rule --- .eslintrc.js | 1 + 1 file changed, 1 insertion(+) diff --git a/.eslintrc.js b/.eslintrc.js index 770f1365..68870c3b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -57,6 +57,7 @@ module.exports = { files: ['*.js', '*.jsx'], rules: { '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', // may need to add more rules }, }, From d12f77ef30abfbd3ae01935c47f9685cfa1ba5a3 Mon Sep 17 00:00:00 2001 From: Josh-Cena Date: Thu, 22 Apr 2021 20:42:14 +0800 Subject: [PATCH 3/8] Improve wording --- docs/about-us.md | 4 ++-- docusaurus.config.js | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/about-us.md b/docs/about-us.md index 82e1b103..deb154be 100644 --- a/docs/about-us.md +++ b/docs/about-us.md @@ -8,8 +8,8 @@ license: Creative Commons Attribution 4.0 International License ### 我们的名字 -**C 社 << Computerization << 信息化社** -我们的全称是 Computerization,信息化社; +**C 社 << Computerization << 世外信息化社** +我们的全称是 Computerization,世外信息化社; 不过我们更喜欢被称之为 C 社,一是因为简洁明快,二也是因为与 C 语言同名(笑) ### 我们对 CS 的看法 diff --git a/docusaurus.config.js b/docusaurus.config.js index b840e059..31cc64f7 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -22,7 +22,7 @@ module.exports = { locales: ['zh-Hans', 'en'], localeConfigs: { 'zh-Hans': { - label: '中文', + label: '中文(简体)', }, en: { label: 'English', @@ -31,14 +31,14 @@ module.exports = { }, themeConfig: { navbar: { - title: '信息化社', + title: '世外信息化社', logo: { alt: 'Computerization Logo', src: 'img/logo.svg', srcDark: 'img/logo.svg', }, items: [ - { to: 'alumni', label: '成员', position: 'left' }, + { to: 'alumni', label: '往届成员', position: 'left' }, { to: 'docs/about-us', label: '文档', position: 'left' }, { to: 'blog', label: '博客', position: 'left' }, { @@ -87,7 +87,7 @@ module.exports = { alt: 'Computerization Logo', src: 'img/logo.svg', }, - copyright: `信息化社 © ${new Date().getFullYear()} 版权所有. 使用 Docusaurus 搭建.`, + copyright: `世外信息化社 © ${new Date().getFullYear()} 版权所有. 使用 Docusaurus 搭建.`, }, }, stylesheets: [ From 92c9f3932caac60ad3dda0798fb282a577c21e18 Mon Sep 17 00:00:00 2001 From: Josh-Cena Date: Thu, 22 Apr 2021 20:46:47 +0800 Subject: [PATCH 4/8] Fix incorrectly named translate item --- i18n/en/docusaurus-theme-classic/navbar.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/i18n/en/docusaurus-theme-classic/navbar.json b/i18n/en/docusaurus-theme-classic/navbar.json index 2e928dfc..c1542c55 100644 --- a/i18n/en/docusaurus-theme-classic/navbar.json +++ b/i18n/en/docusaurus-theme-classic/navbar.json @@ -3,9 +3,9 @@ "message": "Computerization", "description": "The title in the navbar" }, - "item.label.成员": { + "item.label.往届成员": { "message": "Alumni", - "description": "Navbar item with label 成员" + "description": "Navbar item with label 往届成员" }, "item.label.文档": { "message": "Docs", From 6d1a9ec1c976c5204d935973392444c5b6d58afd Mon Sep 17 00:00:00 2001 From: Josh-Cena Date: Sat, 24 Apr 2021 11:49:22 +0800 Subject: [PATCH 5/8] Add non-translated md files --- .../2020-09-02-welcome.md | 20 ++ .../2020-09-23-git-usage.md | 225 ++++++++++++++++++ .../2020-10-10-algorithm1.mdx | 141 +++++++++++ .../2020-11-04-algorithm3.mdx | 112 +++++++++ .../2020-12-02-algorithm5.mdx | 170 +++++++++++++ .../current/about-us.md | 53 +++++ .../current/activities.md | 19 ++ .../current/enspire/what-is-enspire.md | 42 ++++ .../current/matlab-and-modeling.md | 40 ++++ .../current/syllabus.md | 113 +++++++++ .../current/what-is-sam.md | 39 +++ 11 files changed, 974 insertions(+) create mode 100644 i18n/en/docusaurus-plugin-content-blog/2020-09-02-welcome.md create mode 100644 i18n/en/docusaurus-plugin-content-blog/2020-09-23-git-usage.md create mode 100644 i18n/en/docusaurus-plugin-content-blog/2020-10-10-algorithm1.mdx create mode 100644 i18n/en/docusaurus-plugin-content-blog/2020-11-04-algorithm3.mdx create mode 100644 i18n/en/docusaurus-plugin-content-blog/2020-12-02-algorithm5.mdx create mode 100644 i18n/en/docusaurus-plugin-content-docs/current/about-us.md create mode 100644 i18n/en/docusaurus-plugin-content-docs/current/activities.md create mode 100644 i18n/en/docusaurus-plugin-content-docs/current/enspire/what-is-enspire.md create mode 100644 i18n/en/docusaurus-plugin-content-docs/current/matlab-and-modeling.md create mode 100644 i18n/en/docusaurus-plugin-content-docs/current/syllabus.md create mode 100644 i18n/en/docusaurus-plugin-content-docs/current/what-is-sam.md diff --git a/i18n/en/docusaurus-plugin-content-blog/2020-09-02-welcome.md b/i18n/en/docusaurus-plugin-content-blog/2020-09-02-welcome.md new file mode 100644 index 00000000..51b6b005 --- /dev/null +++ b/i18n/en/docusaurus-plugin-content-blog/2020-09-02-welcome.md @@ -0,0 +1,20 @@ +--- +title: Welcome +author: Josh Cena +authorTitle: Leader of Computerization +authorURL: https://github.com/Josh-Cena +authorImageURL: https://avatars2.githubusercontent.com/u/55398995?s=400&u=88dc0dcb0691877524dd8739db9fde7ed4fa9721&v=4 +tags: [welcome] +--- + +**Computerization**欢迎所有 2020 届新成员! + +在这里,你可以: + +- 参与新平台 [Enspire](https://github.com/Computerization/Enspire) 的开发; +- 研究人工智能 (e.g. 神经网络、机器学习); +- 参与 Leetcode 周赛等各类算法竞赛; +- 学习前后端技术与网页设计,零距离体验 Web 项目开发; +- …… + +我们希望各位新成员能在这一年内愉快学习,获得自我提升,并结识志趣相投的伙伴。 diff --git a/i18n/en/docusaurus-plugin-content-blog/2020-09-23-git-usage.md b/i18n/en/docusaurus-plugin-content-blog/2020-09-23-git-usage.md new file mode 100644 index 00000000..33e55bbb --- /dev/null +++ b/i18n/en/docusaurus-plugin-content-blog/2020-09-23-git-usage.md @@ -0,0 +1,225 @@ +--- +title: Git 使用指南:理解 Git 工作原理 +author: Josh Cena +authorTitle: Leader of Computerization +authorURL: https://github.com/Josh-Cena +authorImageURL: https://avatars2.githubusercontent.com/u/55398995?s=400&u=88dc0dcb0691877524dd8739db9fde7ed4fa9721&v=4 +tags: [git, guide] +--- + +import useBaseUrl from '@docusaurus/useBaseUrl'; // Add to the top of the file below the front matter. + +> 这篇文章是从[C 社的新成员练手 repo](https://github.com/Computerization/New-member-practice-commit) 的 README.md 的第一节转移过来的,添加了一些内容,并做了相应的翻译。(原文用英文的原因,应该是 sy 大佬和我都更习惯用英语写技术相关的内容吧……) + +添加文件时,你既可以用带图形用户界面(GUI)的 GitHub Desktop,也可以用命令行。你可以从 GUI 入手,但你会有一天意识到命令行功能的强大,开始用它的。另外,Visual Studio Code 的用户们也可以试试其自带的源代码管理工具。 + +我们觉得有必要给你解释你每一步究竟在做什么,而不是让你机械地重复我们写好的教程。这对你尤其有帮助,因为教程通常都把事情想得很完美,但现实则充满了各种意外和变数。阅读时,我们并不要求你事先懂得任何 Git 操作。 + + + +你可以把 Git 理解成一个版本控制系统。它能记录每个文件的创建、更改、和删除,而仓库管理者可以在各个版本(commit[^commit])间自由切换,就好像游戏中的若干存档一样。 + +[^commit]: 中文大致意思是“提交”——这也是我不喜欢用中文写作的原因,中英混杂总是难以避免。 + +## 基础操作:clone, branch, commit, push, pull request + +假设现在 GitHub 上有这样一个叫 `Hello` 的仓库,是由小丽创建的,装着可能是历史上*最*著名的一段代码。它的目录长这个样子: + +```bash +. +├── Hello.cpp +│ +├── Contributors.txt +│ +└── README.md +``` + +```cpp +// Hello.cpp +#include +using namespace std; +int main() { + cout << "Hello world!" << endl; +} +``` + +```bash +// Contributors.txt +XiaoLi +``` + +```markdown +// README.md + +# Hello world + +A piece of C++ code that prints `Hello world!` +``` + +你可以把每个 commit 看作是整个仓库的一个快照,一个拷贝。实际上它要比一份完整的拷贝轻量得多,但原理上它保存了那一时刻仓库的全部信息。比如上面的版本就可以看作 `C0` commit。(每个 commit 都有一个独有的哈希值,但长到人类无法阅读。因此用 `C0` 来指代就好了。)我们也管这个 commit 叫 `master` 分支。_一个分支即一系列有线性发展关系的 commit,而 `master` 分支则作为主分支。实际上,一个分支就是一个指向某个 commit 的指针。_ 该项目目前的树状结构如下: + +Git tree 1 + +语言学家小明发现了这个仓库。他对此很感兴趣,但他对小丽还在用古早的 `Hello world!` 非常不满,因此决定做点贡献。为此,他需要先把这个文件夹(也就是仓库)下载下来。这基本就是 **_克隆仓库 (clone the repo)_** 做的事情。 + +小明在自己的机器上有了一份完整的拷贝后,就可以像本地项目一样作编辑了。他对三个文件都作了更新: + +```cpp +// Hello.cpp +#include +using namespace std; +int main() { + cout << "Bonjour le monde!" << endl; +} +``` + +```bash +// Contributors.txt +XiaoLi +XiaoMing +``` + +```markdown +// README.md + +# Hello world + +A piece of C++ code that prints `Bonjour le monde!` +``` + +现在他的直觉告诉他,他需要把这些代码发回 GitHub。要做到这一点,他可以直接提交一个 commit。但这里有个严峻的问题:_小丽对小明的行为完全没有控制。_ 事实上,大多数公开仓库(包括 C 社的)都限制了其他人直接向 `master` 提交 commit,因为没有哪个环节可以做安全验证。一旦成功 commit,小丽就会惊讶地发现她 GitHub 上的代码变成了法语。并且无论如何,这也是非常恶劣的行为:**在任何合作项目中,都永远不要直接向 master 分支提交 commit。**~~(除非你还有一周就要辞职了)~~ 向 `master` 提交 commit 还有一个问题,我们马上就会看到。 + +因此为了解决这一问题,小明 **_新建了一个分支 (create a branch)_** ,并把它命名为 `XiaoMing/change-output-language`。我们可以认为,小明是在一个和 `master` 相同但独立的文件夹里工作,而他做出的任何改动都不会影响 `master`。这不仅能明确他的目的,确定他分支作者的地位,还能避免冲突和混乱。 + +现在这些变更都会被记录在 `XiaoMing/change-output-language` 中。但当他准备 commit 时,他记起了另一条准则:**一个 commit 只应该实现一个功能。** 重新审视自己的改动,他觉得改变语言和在 `Contributors.txt` 里添加自己的名字应该是独立的改动。(这里的区别微乎其微,但在实际的项目中还是非常容易判断的。)因此他 **_上传了两个 commit (make a commit)_** ,分别命名为 `Change output to French` 和 `Add XiaoMing's name to Contributors.txt`,而它们的哈希值分别为 `C1` 和 `C2`。注意,他不一定是按顺序做出这些改动的,但 Git 把 `C2` 当作 `C1` 的继承者,因为它是后来的 commit。现在,`XiaoMing/change-output-language` 这一分支就指向了 `C2` commit。该仓库现在的 Git 树如下: + +Git tree 2 + +此时他的改动还只是本地的——没人能在 GitHub 网页上看到它们。因此他接下来 **_发布了分支并将其推送至源 (publish branch and push to origin)_** 。这会把 `XiaoMing/change-output-language` 这一分支及其包含的所有 commit 上传到 GitHub 远程终端。 + +当他发布了分支之后,其后在该分支上做出的任何 commit 都会自动被同步到 GitHub 上。 + +紧接着,他 **_发布了拉取请求 (create pull request)_** ,请求代码拥有者(也就是小丽)合并这一分支。_分支被合并后,所有的改变都会在 `master` 中体现出来。_ + +只有一个分支时,事情非常简单,因为此时分支上所有的 commit 都是 `master` 的继承者,在合并分支时,Git 只需要把所有东西都加到 `master`,也就是 `C0` 上,就可以了。因此,它会移动 `master` 指针: + +Git tree 3 + +而事实上,以上就是所有 Git 新用户需要明白的操作。但作为未来的 GitHub 代码管理者,你应当思考得更深入一点。 + +## 解决冲突 + +为了让事情更有趣一点,我们又同时请来了守旧派小红。她对小丽忘记在 cpp 文件结尾加 `return 0;` 非常不满,因此决定修正这一问题。同样地,她复制了仓库,在 `master` 上新建了一个叫 `XiaoHong/improve-code-style` 的分支,而由于此时小明还没有提交分支,`master` 仍然指向 `C0`。文件改动如下(`C3`): + +```cpp +// Hello.cpp +#include +using namespace std; +int main() { + cout << "Hello world!" << endl; + return 0; +} +``` + +```bash +// Contributors.txt +XiaoLi +XiaoHong +``` + +```markdown +// README.md + +# Hello world + +A piece of C++ code that prints `Hello world!` +``` + +她发布了分支并提交了合并请求。此时,Git 树如下: + +Git tree 4 + +小丽午休结束之后,回到 GitHub 页面上,发现多了两个合并请求。她开心地合并了小明的请求: + +Git tree 5 + +但却发现不能直接合并小红的。GitHub 警告说,该分支和 `master` 间有冲突,因为有同时作出的修改,Git 不知道要留下哪一个,因此需要她手动解决冲突。解决页面有如下的内容: + +```cpp +// Hello.cpp + #include + using namespace std; + int main() { + <<<<<<< master + cout << "Bonjour le monde!" << endl; + ======= + cout << "Hello world!" << endl; + return 0; + >>>>>>> XiaoHong/improve-code-style + } +``` + +```bash +// Contributors.txt + XiaoLi + <<<<<<< master + XiaoMing + ======= + XiaoHong + >>>>>>> XiaoHong/improve-code-style +``` + +注意到 README.md 文件不需要解决冲突,因为只有小明作了修改;Git 还是能意识到这一点的。怎么解决上述问题对小丽这样的人类还是非常显然的:只要同时留下两人所做的改动即可。因此,她删去了多余的内容,解决了冲突,并合并了小红的分支。文件现在的样子(`C4`): + +```cpp +// Hello.cpp +#include +using namespace std; +int main() { + cout << "Bonjour le monde!" << endl; + return 0; +} +``` + +```bash +// Contributors.txt +XiaoLi +XiaoMing +XiaoHong +``` + +```markdown +// README.md + +# Hello world + +A piece of C++ code that prints `Bonjour le monde!` +``` + +而在合并一个并不是自己的继承者的分支时,Git 会新建一个 commit: + +Git tree 6 + +此时,小丽、小明、小红三人就成功地完成了一次在 GitHub 上的开源项目合作。 + +如果想要学习更多 Git 有关的知识,并深入研究它的树状结构,可以访问这个网站:[Learn Git Branching](https://learngitbranching.js.org) + +## 拓展阅读 + +如果想要了解 `pull`, `push`, `commit`, `add`, 和 `checkout` 时具体发生了什么,可以参考以下网站: + +- [Git SCM - Getting Started: Git Basics](https://git-scm.com/book/en/v1/Getting-Started-Git-Basics) +- [Git SCM - Git Branching: Branches in a Nutshell](https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell) +- [Git SCM - Git Branching: Branching Workflows](https://git-scm.com/book/en/v2/Git-Branching-Branching-Workflows) +- [Stack Overflow - What's the difference between HEAD, working tree and index, in Git?](https://stackoverflow.com/questions/3689838/whats-the-difference-between-head-working-tree-and-index-in-git) +- [Understanding Git: Data Model](https://hackernoon.com/https-medium-com-zspajich-understanding-git-data-model-95eb16cc99f5) +- [Understanding Git: Branching](https://hackernoon.com/understanding-git-branching-2662f5882f9) +- [Understanding Git: Index](https://hackernoon.com/understanding-git-index-4821a0765cf) + +除此之外,如果你不喜欢阅读长篇大论,你可以观看下面这个长约 82 分钟的 YouTube 视频: + +- [\[VIDEO\] Introduction to Git with Scott Chacon of GitHub](https://www.youtube.com/watch?v=ZDR433b0HJY) + +也可以在这个可视化的页面上尝试各类 Git 指令: + +- [Learn Git Branching](https://learngitbranching.js.org) diff --git a/i18n/en/docusaurus-plugin-content-blog/2020-10-10-algorithm1.mdx b/i18n/en/docusaurus-plugin-content-blog/2020-10-10-algorithm1.mdx new file mode 100644 index 00000000..82e8ad10 --- /dev/null +++ b/i18n/en/docusaurus-plugin-content-blog/2020-10-10-algorithm1.mdx @@ -0,0 +1,141 @@ +--- +title: 斐波那契数列 +author: Josh Cena +authorTitle: Leader of Computerization +authorURL: https://github.com/Josh-Cena +authorImageURL: https://avatars2.githubusercontent.com/u/55398995?s=400&u=88dc0dcb0691877524dd8739db9fde7ed4fa9721&v=4 +tags: [algorithm] +--- + +import useBaseUrl from '@docusaurus/useBaseUrl'; + +这是 C 社算法团队的第一次活动。我们介绍了斐波那契数列的第$n$项求解方法,主要运用了矩阵快速幂算法。 + + + +export const Question = ({ children, color }) => ( +
+ {children} +
+); + +## 题目 + + + 斐波那契数列: + +$$ +F_{n}= +\begin{cases} + 0,&n=0\\ + 1,&n=1\\ + F_{n-2}+F_{n-1},&n>1 +\end{cases} +$$ + +给定$n$,求$F_{n}\text{ mod }10^9+7$。 + +| 数据规模 | 内存限制 | 运行时间 | +| ------------------- | -------- | -------- | +| $0\le n\le 10^{19}$ | 64MB | 1.0s | + + + +## 题解 + +$10^{19}$显然灭掉了所有用循环解决的想法。有没有比简单的$\mathcal{O}(n)$更好一点的方法?用**矩阵快速幂**,可以达到$\mathcal{O}(\log n)$。观察到: + +$$\begin{pmatrix}F_{n+1}\\F_{n+2}\end{pmatrix}=\begin{pmatrix}F_{n+1}\\F_{n}+F_{n+1}\end{pmatrix}=\begin{pmatrix}0&1\\1&1\end{pmatrix}\begin{pmatrix}F_{n}\\F_{n+1}\end{pmatrix}$$ + +这一步对于所有递推数列都是适用的,因此在有经验之后应该非常容易得到。一般地,对于$F_{n+2}=aF_{n}+bF_{n+1}$,有 + +$$\begin{pmatrix}F_{n+1}\\F_{n+2}\end{pmatrix}=\begin{pmatrix}F_{n+1}\\aF_{n}+bF_{n+1}\end{pmatrix}=\begin{pmatrix}0&1\\a&b\end{pmatrix}\begin{pmatrix}F_{n}\\F_{n+1}\end{pmatrix}$$ + +从递推式中有 + +$$\begin{pmatrix}F_{n+m}\\F_{n+m+1}\end{pmatrix}=\begin{pmatrix}0&1\\1&1\end{pmatrix}^m\begin{pmatrix}F_{n}\\F_{n+1}\end{pmatrix}$$ + +取$n=0$,得到 + +$$\begin{pmatrix}F_{m}\\F_{m+1}\end{pmatrix}=\begin{pmatrix}0&1\\1&1\end{pmatrix}^m\begin{pmatrix}F_0\\F_1\end{pmatrix}$$ + +因此把问题转化成了如何求矩阵$m$次方的问题。如果设$m=2^0a_0+2^1a_1+2^2a_2+\dots$(也就是把$m$用二进制表示),那么有 + +$$\begin{pmatrix}0&1\\1&1\end{pmatrix}^m=\left(\begin{pmatrix}0&1\\1&1\end{pmatrix}^{1}\right)^{a_0}\times \left(\begin{pmatrix}0&1\\1&1\end{pmatrix}^{2}\right)^{a_1}\times \left(\begin{pmatrix}0&1\\1&1\end{pmatrix}^{4}\right)^{a_2}\dots$$ + +而这些矩阵的$2^k$次方,完全可以预处理。当$m$的数量级为$10^{19}$时,$k<\log_2 10^{19}<64$,最多只需要存储 63 个矩阵。并且 + +$$\begin{pmatrix}0&1\\1&1\end{pmatrix}^{2^k}=\begin{pmatrix}0&1\\1&1\end{pmatrix}^{2^{k-1}}\times \begin{pmatrix}0&1\\1&1\end{pmatrix}^{2^{k-1}}$$ + +这些乘方可以在$\mathcal{O}(\log m)$时间内得到。这便是快速幂的思想:计算所有的$2^k$次方,然后把其中需要的那些组合起来即可。 + +## 程序 + +下面是 C++ 代码,其中最繁琐的部分是实现矩阵乘法: + +```cpp +#include +#include + +using namespace std; + +struct mat { + unsigned long long a[4]; + mat operator *(mat o) { + mat t; + t.a[0] = (this->a[0] * o.a[0] + this->a[1] * o.a[2]) % 1000000007; + t.a[1] = (this->a[0] * o.a[1] + this->a[1] * o.a[3]) % 1000000007; + t.a[2] = (this->a[2] * o.a[0] + this->a[3] * o.a[2]) % 1000000007; + t.a[3] = (this->a[2] * o.a[1] + this->a[3] * o.a[3]) % 1000000007; + return t; + } +}; + +// 预处理的矩阵 2^k 次幂 +mat mat_pow[64]; + +int fib(unsigned long long k) { + // 临时矩阵,每次在此上面乘以 mat_pow 中的某项 + mat tmp; + tmp.a[0] = 1; + tmp.a[1] = 0; + tmp.a[2] = 0; + tmp.a[3] = 1; + for (int i = 0; i < 64; i++) { + // 如果 a_i 为 1 + if (k & (1ull << i)) { + tmp = tmp * mat_pow[i]; + } + } + return tmp.a[1]; +} + +int main() { + mat_pow[0].a[0] = 0; + mat_pow[0].a[1] = 1; + mat_pow[0].a[2] = 1; + mat_pow[0].a[3] = 1; + for (int i = 1; i < 64; i++) { + mat_pow[i] = mat_pow[i-1] * mat_pow[i-1]; + } + unsigned long long n; + cin >> n; + cout << fib(n) << endl; + return 0; +} +``` + +补充一下矩阵的乘法公式: + +$$\begin{pmatrix}a_0&a_1\\a_2&a_3\end{pmatrix}\times\begin{pmatrix}b_0&b_1\\b_2&b_3\end{pmatrix}=\begin{pmatrix}a_0b_0+a_1b_2&a_0b_1+a_1b_3\\a_2b_0+a_3b_2&a_2b_1+a_3b_3\end{pmatrix}$$ + +$$\begin{pmatrix}a_0&a_1\\a_2&a_3\end{pmatrix}\times\begin{pmatrix}b_0\\b_1\end{pmatrix}=\begin{pmatrix}a_0b_0+a_1b_1\\a_2b_0+a_3b_1\end{pmatrix}$$ diff --git a/i18n/en/docusaurus-plugin-content-blog/2020-11-04-algorithm3.mdx b/i18n/en/docusaurus-plugin-content-blog/2020-11-04-algorithm3.mdx new file mode 100644 index 00000000..fe2a0ad4 --- /dev/null +++ b/i18n/en/docusaurus-plugin-content-blog/2020-11-04-algorithm3.mdx @@ -0,0 +1,112 @@ +--- +title: 阶乘字符串 +author: DoremySwee +authorTitle: Member of algorithm team +authorURL: https://github.com/DoremySwee +authorImageURL: https://avatars0.githubusercontent.com/u/66953201?s=400&u=58b3bbef3de5713252ff2d597346a72432399daf&v=4 +tags: [algorithm] +--- + +import useBaseUrl from '@docusaurus/useBaseUrl'; + +这是 C 社算法团队的第三次活动。我们研究了一道上海省选的题目,主要运用了状态压缩动态规划算法。其中数学部分比较困难,尚未给出严格证明。 + + + +export const Question = ({ children, color }) => ( +
+ {children} +
+); + +## 题目 + + + 原题链接 + +给定一个由前$n$个小写字母组成的串$S$。串$S$是阶乘字符串当且仅当前$n$个小写字母的全排列(共$n!$种)都作为的子序列(可以不连续)出现。 + +由这个定义出发,可以得到一个简单的枚举法去验证,但是它实在太慢了。所以现在请你设计一个算法,在 1 秒内判断出给定的串是否是阶乘字符串。 + +| 数据规模 | 内存限制 | 运行时间 | +| ------------------------- | -------- | -------- | +| $\|S\|\le 450$, $n\le 26$ | 125MB | 1.0s | + + + +## 题解 + +暴力解法自然是枚举全排列并检验,30%的分数到手,不过这个程序没有其它太大意义,甚至由于阶乘级的时间复杂度难以对拍。不多作讨论。 + +考虑 70%的分数。$n\le 20$,可以考虑$\mathcal{O}(2^n)$的算法。既然不能进行全排列的枚举,那么完全可以考虑状态压缩动态规划,枚举一个字母是否出现在状态中。由于要求解的是整个字符串中是否存在前$n$个字母的全排列,则考虑$f(x)$表示$x$对应的几个字母的全排列最早出现在字符串种的何处。 +状态转移方程举例: + +$$ + \begin{aligned} + f(a,b,c,e)=\max(&从f(a,b,c)开始找第一个\texttt{'e'}, \\ + &从f(a,b,e)开始找第一个\texttt{'c'}, \\ + &从f(a,c,e)开始找第一个\texttt{'b'}, \\ + &从f(b,c,e)开始找第一个\texttt{'a'}) + \end{aligned} +$$ + +但是如果对于每一个寻找都是通过循环寻找的话,时间会有点长,只能拿 50 分,需要进行一定的预处理。可以在预处理之后用二分查找,但是方便起见建议添加一个数组标记每一个位置下一个目标字母的位置,所需时间不长,$450\times 26$而已。 + +最后,考虑剩下的分数点。可以发现,对于过大的$n$,可以直接输出`"No"`,至于这个值如何确定?按照$n=3\implies S=\mathtt{abcbab}$,$n=4\implies S=\mathtt{abcdcbabcdcba}$这种构造方式$S$的长度为$n^2-n+1$,$n\le 21$,不过证明过于困难。为保险起见,因为$n=22$时用时是可以接受的,取$n\ge 23$时直接输出`"No"`。 + +## 程序 + +```cpp +#include + +using namespace std; + +int main(){ + int t; + cin >> t; + while (t--) { + int n; + cin >> n; + string s; + cin >> s; + if (n >= 23) { + cout << "NO" << endl; + } else { + short NEXT[26][450]; + for (int i = s.length() - 1; i >= 0; i--) { + if (i == s.length() - 1) { + for (int j = 0; j < 26; j++) + NEXT[j][i] = -1; + } else { + for (int j = 0; j < 26; j++) + NEXT[j][i] = NEXT[j][i + 1]; + } + NEXT[s[i] - 'a'][i] = i; + } + short *f = new short[1 << n]; + for (int i = 0; i < (1 << n); i++) { + f[i] = 0; + for (int j = 0; (1 << j) <= i; j++) { + if (i & (1 << j)) { + if (NEXT[j][f[i - (1 << j)]] == -1) { + cout << "NO" << endl; + return 0; + } + f[i] = max(f[i], NEXT[j][f[i - (1 << j)]]); + } + } + } + cout << "YES" << endl; + } + } +} +``` diff --git a/i18n/en/docusaurus-plugin-content-blog/2020-12-02-algorithm5.mdx b/i18n/en/docusaurus-plugin-content-blog/2020-12-02-algorithm5.mdx new file mode 100644 index 00000000..107653a0 --- /dev/null +++ b/i18n/en/docusaurus-plugin-content-blog/2020-12-02-algorithm5.mdx @@ -0,0 +1,170 @@ +--- +title: Livestock Lineup +author: Josh Cena +authorTitle: Leader of Computerization +authorURL: https://github.com/Josh-Cena +authorImageURL: https://avatars2.githubusercontent.com/u/55398995?s=400&u=88dc0dcb0691877524dd8739db9fde7ed4fa9721&v=4 +tags: [algorithm] +--- + +import useBaseUrl from '@docusaurus/useBaseUrl'; + +这是 C 社算法团队的第五次活动。由于 12 月 USACO 竞赛在即,我们展开了针对性的练习。第一次活动我们从铜组开始练习,由于成员们水平较高,我们挑选了一道有一定编程水平要求的铜组题目。铜组题目只要求对循环的掌握,一定可以通过枚举得到结果,因此对算法和数据结构没有太高要求。 + + + +export const Question = ({ children, color }) => ( +
+ {children} +
+); + +## 题目 + + + +**题目来源:****USACO 2019 December Bronze 3** + +Every day, Farmer John milks his 8 dairy cows, named Bessie, Buttercup, Belinda, Beatrice, Bella, Blue, Betsy, and Sue. + +The cows are rather picky, unfortunately, and require that Farmer John milks them in an order that respects $N$ constraints. Each constraint is of the form "$X$ must be milked beside $Y$", stipulating that cow $X$ must appear in the milking order either directly after cow $Y$ or directly before cow $Y$. + +Please help Farmer John determine an ordering of his cows that satisfies all of these required constraints. It is guaranteed that an ordering is always possible. If several orderings work, then please output the one that is alphabetically first. That is, the first cow should have the alphabetically lowest name of all possible cows that could appear first in any valid ordering. Among all orderings starting with this same alphabetically-first cow, the second cow should be alphabetically lowest among all possible valid orderings, and so on. + +| 数据规模 | 内存限制 | 运行时间 | +| ------------- | -------- | -------- | +| $1\le N\le 7$ | 256MB | 2.0s | + + + +## 题解 + +这道题在理解了题目的需求——生成一个符合给定约束的字典序最小的排列后,应该难度不高。我们可以按字典序生成全部的排列(一共有$8!=40320$种),然后输出第一个满足所有约束条件的。如果不会用回溯算法生成全排列,可能需要借助 `algorithm` 中的 `next_permutation` 函数。这也是典型的铜组思路:因为规模极小,可以暴力枚举之后*挑选*解而不是*构造*解。 + +当然,这种方法对于有一些竞赛经验的参赛者来说反倒不容易想到。这些参赛者会试图通过约束条件来构造解。这需要一点点贪心的思想:为了让排列字典序最小,就一定要让每一位上的奶牛字典序尽可能小。我们可以把一个排列看作一个“约束链”,其中每一头奶牛都因为它相邻位置奶牛的约束而只有唯一的可能。每完成一条约束链的连接后,都可以从剩下未被安排进队的奶牛中挑选编号最小的,但不能是有两个未满足的约束的(因为一个“约束链”中头和尾的奶牛都只能和它相邻的一头奶牛间有约束),然后在确定了链头之后,就可以非常自然地得到整个链条。重复同样的构造过程,直到所有奶牛都被添加入队列。 + +## 程序 + +暴力法的代码: + +```cpp +/** + * Adopted from official solution at + * http://www.usaco.org/current/data/sol_lineup_bronze_dec19.html + */ +#include +#include +#include +#include + +using namespace std; + +string names[8] = {"Beatrice", "Belinda", "Bella", "Bessie", "Betsy", "Blue", "Buttercup", "Sue"}; +// beside_a 和 beside_b 中对应下标的奶牛表示一组约束关系 +vector beside_a, beside_b; +int n; + +int getID(string name) { + for (int i = 0; i < 8; i++) + if (names[i] == name) + return i; + return -1; +} + +bool satisfies_constraints() { + for (int i = 0; i < n; i++) + if (abs(getID(beside_a[i]) - getID(beside_b[i])) != 1) + return false; + return true; +} + +int main() { + ifstream fin("lineup.in"); + ofstream fout("lineup.out"); + fin >> n; + string a, b; + for (int i = 0; i < n; i++) { + fin >> a >> b >> b >> b >> b >> b; + beside_a.push_back(a); + beside_b.push_back(b); + } + // 遍历所有的8头奶牛的排列,输出第一个满足约束的解 + do { + if (satisfies_constraints()) { + for (int i = 0; i < 8; i++) + fout << names[i] << endl; + return 0; + } + } while (next_permutation(names.begin(), names.end())); + return 0; +} +``` + +构造法的代码: + +```cpp +#include +#include + +using namespace std; + +struct cow { + int adj[2]; // 需要和这头奶牛相邻的奶牛的ID + int adjcnt; // 这头奶牛一共有几个约束条件;决定了能否把它放在约束链的开头 + bool chosen; // 是否已经进队 +} cows[8]; +string names[8] = {"Beatrice", "Belinda", "Bella", "Bessie", "Betsy", "Blue", "Buttercup", "Sue"}; + +int getID(string name) { + for(int i = 0; i < 8; i++) + if(names[i] == name) + return i; + return -1; +} + +int main() { + ifstream fin("lineup.in"); + ofstream fout("lineup.out"); + int n; + fin >> n; + string a, b; + for (int i = 0; i < n; i++) { + fin >> a >> b >> b >> b >> b >> b; + cows[getID(a)].adj[cows[getID(a)].adjcnt++] = getID(b); + cows[getID(b)].adj[cows[getID(b)].adjcnt++] = getID(a); + } + int prev = -1; + // 每次循环向队列中添加一头奶牛;如果上一头奶牛没有更多的约束条件了,则可以选择一头新的,否则选择需要和上一头相邻的奶牛 + for (int _ = 0; _ < 8; _++) { + if (_ == 0 || cows[prev].adjcnt == 0) { + for (int i = 0; i < 8; i++) { + if (!cows[i].chosen && cows[i].adjcnt < 2) { + cows[i].chosen = true; + fout << names[i] << endl; + prev = i; + break; + } + } + } else if (cows[prev].adjcnt == 1) { + int i = cows[prev].adj[0]; + cows[i].chosen = true; + // 这里的操作是在把cows[i]添加入队列的同时“删除”掉它已经满足的那条约束 + cows[i].adjcnt--; + if(cows[i].adj[0] == prev) + cows[i].adj[0] = cows[i].adj[1]; + fout << names[i] << endl; + prev = i; + } + } + return 0; +} +``` diff --git a/i18n/en/docusaurus-plugin-content-docs/current/about-us.md b/i18n/en/docusaurus-plugin-content-docs/current/about-us.md new file mode 100644 index 00000000..deb154be --- /dev/null +++ b/i18n/en/docusaurus-plugin-content-docs/current/about-us.md @@ -0,0 +1,53 @@ +--- +id: about-us +title: C社是什么 +license: Creative Commons Attribution 4.0 International License +--- + +我们是一个长期在幕后工作的,以面向社团的知识性服务为主的,一个小而精的 CS 社团 + +### 我们的名字 + +**C 社 << Computerization << 世外信息化社** +我们的全称是 Computerization,世外信息化社; +不过我们更喜欢被称之为 C 社,一是因为简洁明快,二也是因为与 C 语言同名(笑) + +### 我们对 CS 的看法 + +我们眼中的程序,不仅仅只是作为形式载体的代码,而是其背后的程序逻辑和思想; +是 Algorithms 造就了 Computer Scientists,而不是代码, +**这是我们坚定的信念**,也是我们自称为**CS 社团**而不是编程社团的原因。 + +也正是因此,我们有着程序设计交流的社团文化。 + +### 我们主要做些什么 + +我们的主要工作是**向各个社团和学生会提供知识类服务**。 +比如我们编写的[SAM 平台](https://github.com/Computerization/SAM/),就曾在各种场合下独力承担了以下工作: + +- “世外杯”的报名工作 +- 新社团/五星社团/末尾社团答辩的打分和统计工作 +- 2017 Why Charity 的在线拍卖 +- 2018 学年社团活动教室的预约工作 +- 世外社团列表的展示 +- …… + +### 我们还做些什么 + +在与各社合作完成各类项目之余,我们还: + +- 组织程序设计交流 +- 备赛信息学奥林匹克(NOIP) +- 学习离散数学、线性代数等一切可能用到的工具 + +此外,我们也开展一系列课程和教学,如 MATLAB、LaTeX、或是 Python、R + +### 你为什么应该加入我们 + +在 C 社里,你不仅仅能**与大佬们交流,获得自我提升**;你也能获得**展现自我**的平台; +你能和同学讲述你所知道的**计算机原理**、**网络安全知识**, +你能在**Techomedia**推送自己的科技文章, +你能在**数学社**的讲堂上讲授自己的丰富知识积累, +你还能在学校的**信息化平台 SAM**中加入自己的想法,并帮助到其他的许许多多社团和组织; + +**在这里没有用技术实现不了的困难,只有你能不能想到的 Idea** diff --git a/i18n/en/docusaurus-plugin-content-docs/current/activities.md b/i18n/en/docusaurus-plugin-content-docs/current/activities.md new file mode 100644 index 00000000..242a3fac --- /dev/null +++ b/i18n/en/docusaurus-plugin-content-docs/current/activities.md @@ -0,0 +1,19 @@ +--- +id: activities +title: C社都做些什么 +license: Creative Commons Attribution 4.0 International License +--- + +### 定期活动 + +2020 学年,我们社团三个部门都有各自的定期活动时间: + +- 周一放学是和数学社合作的**人工智能**与数学建模课程; +- 周三放学是**算法部门**的课程,包括 NOIP、USACO 等比赛题目的讲解和一些算法、数据结构的分析; +- 周三、周四中午是**Web 团队**的开发时间,组员们一起学习前后端框架,为社团的 [GitHub 项目](https://github.com/Computerization) 做贡献。 + +### 不定期活动 + +我们还承办各类学校内的社团信息化工作,比如我们曾为 Techomedia 联合主办的[THE Hack 创客马拉松 ](https://thehack.org.cn)提供技术支持,主要工作为负责各类功能性网站的编写,比如选手报名平台、[选手提问平台](https://github.com/hackinit/helpq)、[硬件预约/追踪平台](https://github.com/hackinit/cog)等等。 + +目前正处于 [Enspire](enspire/what-is-enspire) 平台的开发初期,我们也不定时地会从学生会或者校内老师那里获得一些新功能需求,这个时候可能会短期内进行比较高强度的开发。 diff --git a/i18n/en/docusaurus-plugin-content-docs/current/enspire/what-is-enspire.md b/i18n/en/docusaurus-plugin-content-docs/current/enspire/what-is-enspire.md new file mode 100644 index 00000000..b7c3a6ce --- /dev/null +++ b/i18n/en/docusaurus-plugin-content-docs/current/enspire/what-is-enspire.md @@ -0,0 +1,42 @@ +--- +id: what-is-enspire +title: Enspire是什么 +license: Creative Commons Attribution 4.0 International License +--- + +Enspire 是一个初生的企划,旨在为**校内 CAS 活动**提供一个**技术支持平台** + +### 为什么要做这个项目? + +保持初心 :fire: + +C 社是服务类社团,其创始初心是为学校生活提供便利(即 SAM 平台) + +如今我们发现,校内同学们 CAS 活动中遇到的管理、技术、宣传问题,是比作业上传和教室预约更大的需求缺口 + +enspire 的目标很简单,**make CAS life easier for every one** (in WFLA, at least for now) +当然,如果能做到让各个社团能从我们的 enspire 中 inspired,就更好啦 + +### 作为一个 C 社社员,我一定要参加 Enspire 开发吗? + +**不一定** + +如果你觉得 enspire 是一个**有价值的 project**,你**愿意投入自己的时间和精力**去开发,那就来吧 + +Enspire 是**C 社所属的开源项目**,但你可以选择不参加,可以选择做出很少的贡献,也可以选择爆肝 :boom: + +如果你不了解**开源项目**是什么,可以参考这个网站 https://opensource.guide/ + +如果你想来参与这个项目的话,请一定好好读上述网站中的 https://opensource.guide/how-to-contribute/ +其中写了很多很基础但是每个 contributor 都必须知道的东西 + +### 卫星放了这么多,Enspire 到底会有哪些功能? + +基于前文提到的**社团管理、技术、宣传问题**,这是目前的想法: + +- 每个社团的 blog post 和成员 contacts +- 按照标签搜索社团 +- “我对这个社团感兴趣”以及“我想加入” +- 其他社团对 C 社的技术问题 FAQ +- 全校社团各项排名?! +- …… (欢迎继续 commit 你的想法:bulb:) diff --git a/i18n/en/docusaurus-plugin-content-docs/current/matlab-and-modeling.md b/i18n/en/docusaurus-plugin-content-docs/current/matlab-and-modeling.md new file mode 100644 index 00000000..f9fc7a3c --- /dev/null +++ b/i18n/en/docusaurus-plugin-content-docs/current/matlab-and-modeling.md @@ -0,0 +1,40 @@ +--- +id: matlab-and-modeling +title: MATLAB与数学建模 +license: Creative Commons Attribution 4.0 International License +--- + +MATLAB 的教学是 C 社与数学社合作开展的**数学建模系列课程**中的一部分 + +### 你为什么应该学习 MATLAB + +MATLAB 是一门**面向科学计算和工程计算**的高级计算机语言。 + +相比它的同行来说,MATLAB 具有以下的优势: + +- 易于使用和学习 +- 拥有丰富的原生函数,尤其是矩阵方面 +- 拥有强大的图形处理功能,可以轻松画出复杂的图形 +- 许多功能函数可以自适应算法,自动选择最优算法,避免错误,提高效率 + +### 你能学到什么 + +在完成基础语法学习后,你将主要通过实践的方式,在学习数学模型的同时,通过 MATLAB 对数学模型进行程序实现,学习 MATLAB 在数学建模中的用法 + +以下是我们的基础课程大纲: + +1. MATLAB: 运算符,程序逻辑 +2. 常见函数拟合 +3. 线性规划 +4. 统计回归模型 +5. 概率模型 +6. 离散模型(层次分析法) +7. LaTeX 入门 + +### 课程大纲(supplementary) + +我们还提供以下内容供有兴趣的学生选修: + +1. 神经网络,聚类分析 +2. 微分方程模型 +3. LaTeX 进阶使用 diff --git a/i18n/en/docusaurus-plugin-content-docs/current/syllabus.md b/i18n/en/docusaurus-plugin-content-docs/current/syllabus.md new file mode 100644 index 00000000..cd4765b2 --- /dev/null +++ b/i18n/en/docusaurus-plugin-content-docs/current/syllabus.md @@ -0,0 +1,113 @@ +--- +id: syllabus +title: C社前端开发培训 +license: Creative Commons Attribution 4.0 International License +--- + +import useBaseUrl from '@docusaurus/useBaseUrl'; + +每年,社团的新同学们在加入前端开发部门后,都要经过一系列的培训。由于加入部门并不要求任何前置知识,因此对于一些零基础的同学们来说,是个挑战。但即使有一定编程基础,也同样要面对**完全崭新的规范和工具**,因此系统的教学必不可少。 + +## 第一阶段:熟悉基础工具(10 周) + +### Git(3 周) + +整个社团的项目都在 GitHub 上开源,实现版本控制、持续部署、代码管理,等等。因此,学习 git 技巧是成为开发者的第一步。 + +我们为新成员们准备了一个 [playground](https://github.com/Computerization/New-member-practice-commit)。每年,社长将新建一个以年份命名的文件夹,而社员们将完成如下任务: + +1. **安装 git。**Unix 系统自带 git,而 Windows 系统可以在[这里](https://git-scm.com/download/win)下载。 +2. **熟悉命令行工具。**在 Windows 上,使用 PowerShell;MacOS 上,使用 Terminal。 + - 学会 `cd` 和 `ls` 指令。 + - 通过 `git --version` 检查 git 是否成功安装。几乎所有命令行工具都提供 `--version` 参数,可以检查安装状态。 +3. **创建 GitHub 账号。**将自己的 email 或 GitHub id 发给社长,社长将把新成员加入社团的 GitHub 组织,并授予相应的读写权限。 +4. 按照我们撰写的 [git 指南](https://github.com/Computerization/New-member-practice-commit/blob/master/README.md)**选择适合自己的 git 工具**。推荐全社团使用 Visual Studio Code 作为编辑器及 git 管理工具。 +5. Clone repo 之后,**新建 branch。** +6. 在对应年份文件夹下**新建以自己的 GitHub id 命名的文件夹。**在文件夹中上传一份代码文件,任意语言均可,只要能够展现自己的代码水平; +7. 在 `Signatures.txt` 中**写下自己的 GitHub id。** +8. Commit, publish branch, and create pull request! + +这一部分往往是最具挑战性的。如果 GitHub 连接不畅,社长将提供相应的技术帮助。我们也推荐使用代理服务器连接。这一部分的操作会在社团活动时间开展,以便社长作一对一指导。由于 New-member-practice-commit 仅仅是一个 playground,即使发生了混乱(如直接向主分支 commit),也不会导致严重的后果,但请务必保证在后续的 GitHub 使用中,不会产生类似的问题。 + +### HTML / CSS / JavaScript(3 周) + +前端的基础是 HTML / CSS / JavaScript。它们分别负责了网页的结构、式样、功能。由于它们都是在浏览器中被解析的,因此这一部分不需要安装任何东西。任务是:**完成一个单页 Todo list 应用。**具体的任务要求,可以参考过往成员们的成品。 + +如果需要帮助,既可以参考 repo 中的所有项目,也可以利用搜索引擎寻找答案。搜索引擎和技术社区的使用是开发者必备的技能。 + +在这一部分,大多数社员将会使用 DOM 操作(`document.innerHTML = ...`),但在后续的开发中,需要避免这种写法。社长的关注重点应放在页面布局与设计、业务逻辑规划、以及代码规范上,而非具体的操作实现上。 + +### Vue(4 周) + +我们的 [Enspire](./enspire/what-is-enspire.md) 平台是使用 Vue 开发的,因此掌握 Vue 语法对于参与社团项目开发非常重要。 + +认真阅读 [Vue 的文档](https://vuejs.org/v2/guide/),**把自己的 todo list 用 Vue 重构。**建议整个 JavaScript 文件只包含一个 Vue 实例的定义,而没有任何全局变量或函数,整个 HTML 也应用 Vue 根组件 `
` 包裹,这样能最大程度地体验 Vue 的思维。 + +社员们很可能会需要了解以下 Vue 语法: + +- 双向数据绑定 `v-model`; +- 列表渲染 `v-for`; +- 事件绑定 `v-on`; +- 组件生命周期 `created` / `mounted`; +- 监听器 `watch` +- …… + +在这一部分,社长需要注意社员们是否最大程度地利用了 Vue 的语法。Vue 拥有浩如烟海的 API 和语法糖,每一个功能可能都有数种实现,因此我们不规定具体的实现,但希望尽可能地利用 Vue 的语法特性。建议保留原始的文档结构和式样表,这样可以节约开发时间,并更好地理解 Vue 在响应式渲染数据、基于组件树的动态更新等方面的优势。 + +--- + +这一阶段总共将安排 8 小时的社团活动,总持续时间不小于 8 周,如果一切按计划进行,将在第三次月考后完成(考试周不安排活动或作业上传)。其中最重要的是学习各项语法,如果 GitHub 相关的技术问题始终无法解决,社长可以考虑替代方案,但保证成员们仍能参与开发。 + +## 第二阶段:项目开发相关(10 周) + +### Vue-CLI(4 周) + +[Vue-CLI](https://cli.vuejs.org/zh/guide/) 是一套命令行工具,可以快速搭建 Vue 项目,并提供解析、集成、部署等其他功能。为了参与 Enspire 开发,需要学会 Vue-CLI 相关操作。 + +首先,安装包管理软件 [npm](https://www.npmjs.com/get-npm);然后,通过 npm 安装 yarn: + +```bash +$ npm -g install yarn +``` + +最后,安装 Vue-CLI: + +```bash +$ yarn global add @vue/cli +``` + +(请保证安装的是新版的 `@vue/cli`。) + +到了这一部分,社员们将拥有更大的自主探索机会。我们鼓励社员们新建一个 Vue 项目,比如一个个人网站,以此了解基于 Webpack 的完整 Vue 项目的结构与逻辑。我们也会为有服务器需求的社员们提供相应资源。 + +社员们还需要对代码规范工具有所了解,比如 ESLint 和 Prettier。 + +### 阅读源代码(4 周) + +在寒假中,社员们需要 clone [Enspire](https://github.com/Computerization/Enspire) 与 [docusaurus](https://github.com/Computerization/docusaurus) 两个 repo,运行它们,并理解源代码的逻辑。 + +Docusaurus 是我们的社团网页(也就是你现在正在浏览的)源码。它使用了 Docusaurus 框架,这是一个基于 React 的静态网页生成器。如果想要贡献,如撰写 docs 或 blog,只需要在对应文件夹中新建 Markdown 文件即可;如果想制作像 Alumni 一样的页面,则需要学习 React 语法。这不是必学内容。 + +Enspire 使用了 TypeScript,这是一种带类型标注与静态检查的 JavaScript。开学后,社长会详细介绍 TS 语法与其优势。 + +### GitHub 开发、集成与部署(2 周) + +社团的项目安装了一系列的 GitHub 工具,帮助完成集成与部署。在这一步,社员们要更加深入地了解 GitHub 的功能。包括: + +- 如何 review and merge pull requests(如果还不会 Markdown,这也是时候学习一下了); +- 负责集成与检查的 GitHub actions (build, check...); +- 负责部署的 Netlify, CircleCI; +- 负责依赖项更新的 Dependabot。 + +--- + +在学年过去 60% 后,社员们都应当成长为了有一定经验的开发者。他们掌握如下技能: + +- 通过搜索引擎与社区寻找需要的帮助与信息; +- 在命令行中调用、配置、执行程序; +- 通过 GitHub 完成协作开发; +- 了解并掌握前端开发的技术栈,如 Vue, TypeScript, Webpack 等; +- 熟悉代码写作规范; +- 能够独立完成小型项目,为业务逻辑建模并实现。 + +接下来,社员们除了需要接起社团内的日常技术维护事务,还要投身于系统的开发。 diff --git a/i18n/en/docusaurus-plugin-content-docs/current/what-is-sam.md b/i18n/en/docusaurus-plugin-content-docs/current/what-is-sam.md new file mode 100644 index 00000000..35c83a0c --- /dev/null +++ b/i18n/en/docusaurus-plugin-content-docs/current/what-is-sam.md @@ -0,0 +1,39 @@ +--- +id: what-is-sam +title: SAM是什么 +license: Creative Commons Attribution 4.0 International License +--- + +import useBaseUrl from '@docusaurus/useBaseUrl'; // Add to the top of the file below the front matter. + +SAM 是一个校内信息化平台。它目前的地址是[https://sam.shuye02.com](https://sam.shuye02.com) + +SAM 主要由以下三大部分组成: + +## 社团 + +社团部分是对于所有校内社团的索引和搜索。 + +目前正在开发中的功能有: + +- 发布文章/公告 +- 社团成员系统 +- 发布作业并追踪成员完成进度 + +Organization + +### 教室预约 + +这部分是社团活动教室的预约,只有社长有权限访问。这个功能是在 2018 年 9 月份为学生会社团部定做的,在 2018 年 9 月份中旬开放,目前处于关闭状态 + +### 投票 + +投票系统作为多功能用途的表单提交系统,可以进行多种用途的使用。 + +如下图,“世外杯”辩论赛曾通过投票系统进行观众报名,并统计观众报名场次 + +debate voting + +此外,学生会和 CAS 组也使用投票平台进行五星社团、新社团、末位社团的答辩和投票 + +Organization Defense Voting From 221715002a7d224d0fc3c9faf4b1f9af80d44bf2 Mon Sep 17 00:00:00 2001 From: Josh-Cena Date: Sat, 24 Apr 2021 11:49:52 +0800 Subject: [PATCH 6/8] Update README to document i18n --- README.md | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e9b91314..78ca1bf6 100644 --- a/README.md +++ b/README.md @@ -43,11 +43,19 @@ This command installs all depedendencies specified by the [`yarn.lock`](/yarn.lo $ yarn start ``` -This command starts a local development server and open up a browser window. You can preview your changes instantly with the development server as you edit the files. Most changes are reflected live without having to restart the server. +This command starts a local development server and opens up a browser window. You can preview your changes instantly with the development server as you edit the files. Most changes are reflected live without having to restart the server. + +### Other locales + +``` +$ yarn start --locale en +``` + +The default language for the website is simplified Chinese (`zh-Hans`). In order to view the English version locally, start the development server with the english locale. Note that each locale is an independent application, so you cannot use the language dropdown to switch between languages in development. ### Directory Structure -You may want to read the [Docusaurus v2 documents](https://v2.docusaurus.io/) beforehand. +You may want to read the [Docusaurus v2 documentation](https://docusaurus.io/) beforehand. ```bash . @@ -55,14 +63,28 @@ You may want to read the [Docusaurus v2 documents](https://v2.docusaurus.io/) be │ # Configuration file for Continuous Integration & Testing ├── .dependabot │ # Configuration file for auto-bumping dependencies +├── .github +│ # GitHub workflows to run checks on commit / pull request +├── .husky +│ # The pre-commit hook script run by husky; used for linting ├── blog │ # Markdown files for blog contents -│ # Refer to https://v2.docusaurus.io/docs/blog#adding-posts for help +│ # Refer to https://docusaurus.io/docs/blog#adding-posts for help ├── build │ # Generated by `yarn build`; Used for deployment ├── docs │ # Markdown files for documentation -│ # Refer to https://v2.docusaurus.io/docs/markdown-features for available features +│ # Refer to https://docusaurus.io/docs/markdown-features for available features +├── i18n +│ | # Internationalization support +| └── en +│ | # All data needed for the English translation +│ ├── docusaurus-plugin-content-blog +│ │ # All blog pages translated in English; for best tracking, the directory structure should be the same as /blog/ +│ ├── docusaurus-plugin-content-docs +│ │ # All docs pages translated in English; for best tracking, the directory structure should be the same as /docs/ +│ └── docusaurus-theme-classic +│ # Json files providing translation to the navbar and footer ├── node_modules │ # Stores the dependency files installed by `yarn` │ # Required for testing & deploying @@ -77,7 +99,7 @@ You may want to read the [Docusaurus v2 documents](https://v2.docusaurus.io/) be │ # React codes for actual pages └── static │ # All static files goes here - │ # Refer to https://v2.docusaurus.io/docs/static-assets + │ # Refer to https://docusaurus.io/docs/static-assets └── img ``` From 758b57c3d982ae6c658852c0b9d887446048f30b Mon Sep 17 00:00:00 2001 From: Josh-Cena Date: Sun, 25 Apr 2021 02:16:02 +0800 Subject: [PATCH 7/8] Better code highlight support --- docusaurus.config.js | 6 ++++++ package.json | 1 + src/css/custom.css | 11 +++++++++++ yarn.lock | 2 +- 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/docusaurus.config.js b/docusaurus.config.js index 31cc64f7..f68ac4db 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -8,6 +8,8 @@ const remarkMath = require('remark-math'); const rehypeKatex = require('rehype-katex'); +const githubTheme = require('prism-react-renderer/themes/github'); +const draculaTheme = require('prism-react-renderer/themes/dracula'); module.exports = { title: 'Computerization', @@ -89,6 +91,10 @@ module.exports = { }, copyright: `世外信息化社 © ${new Date().getFullYear()} 版权所有. 使用 Docusaurus 搭建.`, }, + prism: { + theme: githubTheme, + darkTheme: draculaTheme, + }, }, stylesheets: [ { diff --git a/package.json b/package.json index 5ba39655..988f311f 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "classnames": "^2.3.1", "node-fetch": "^2.6.1", "node-forge": "^0.10.0", + "prism-react-renderer": "^1.2.0", "react": "^17.0.2", "react-dom": "^17.0.2", "rehype-katex": "^4.0.0", diff --git a/src/css/custom.css b/src/css/custom.css index 9e43494b..c38b6b30 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -21,3 +21,14 @@ --ifm-color-primary-lighter: #81c5ec; --ifm-color-primary-lightest: #abd8f2; } + +.docusaurus-highlight-code-line { + background-color: rgb(221, 223, 225); + display: block; + margin: 0 calc(-1 * var(--ifm-pre-padding)); + padding: 0 var(--ifm-pre-padding); +} + +html[data-theme='dark'] .docusaurus-highlight-code-line { + background-color: rgb(28, 30, 37); +} diff --git a/yarn.lock b/yarn.lock index 8e7285db..c6710de4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8581,7 +8581,7 @@ pretty-time@^1.1.0: resolved "https://registry.yarnpkg.com/pretty-time/-/pretty-time-1.1.0.tgz#ffb7429afabb8535c346a34e41873adf3d74dd0e" integrity sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA== -prism-react-renderer@^1.1.1: +prism-react-renderer@^1.1.1, prism-react-renderer@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-1.2.0.tgz#5ad4f90c3e447069426c8a53a0eafde60909cdf4" integrity sha512-GHqzxLYImx1iKN1jJURcuRoA/0ygCcNhfGw1IT8nPIMzarmKQ3Nc+JcG0gi8JXQzuh0C5ShE4npMIoqNin40hg== From df2785b00d85077b7d6ab2a61abfbf03cad436bf Mon Sep 17 00:00:00 2001 From: Josh-Cena Date: Sun, 25 Apr 2021 11:01:04 +0800 Subject: [PATCH 8/8] Translate blogs --- .../2020-09-02-welcome.md | 16 ++--- .../2020-09-23-git-usage.md | 65 +++++++++---------- .../2020-10-10-algorithm1.mdx | 44 ++++++------- .../2020-11-04-algorithm3.mdx | 41 ++++++------ .../2020-12-02-algorithm5.mdx | 38 +++++------ 5 files changed, 102 insertions(+), 102 deletions(-) diff --git a/i18n/en/docusaurus-plugin-content-blog/2020-09-02-welcome.md b/i18n/en/docusaurus-plugin-content-blog/2020-09-02-welcome.md index 51b6b005..4086355f 100644 --- a/i18n/en/docusaurus-plugin-content-blog/2020-09-02-welcome.md +++ b/i18n/en/docusaurus-plugin-content-blog/2020-09-02-welcome.md @@ -7,14 +7,14 @@ authorImageURL: https://avatars2.githubusercontent.com/u/55398995?s=400&u=88dc0d tags: [welcome] --- -**Computerization**欢迎所有 2020 届新成员! +**Computerization** welcome all new members of class 2020! -在这里,你可以: +At Computerization, you can: -- 参与新平台 [Enspire](https://github.com/Computerization/Enspire) 的开发; -- 研究人工智能 (e.g. 神经网络、机器学习); -- 参与 Leetcode 周赛等各类算法竞赛; -- 学习前后端技术与网页设计,零距离体验 Web 项目开发; -- …… +- Join in the development of the new platform [Enspire](https://github.com/Computerization/Enspire); +- Research on artificial intelligence (e.g. neural networks, machine learning); +- Take part in algorithm contests (e.g. LeetCode weekly contest); +- Learn front-end / back-end technology and web designing, experience web development in the real world; +- ... -我们希望各位新成员能在这一年内愉快学习,获得自我提升,并结识志趣相投的伙伴。 +We hope that all new members can learn with joy, self-improve, and meet peers with the same interest. diff --git a/i18n/en/docusaurus-plugin-content-blog/2020-09-23-git-usage.md b/i18n/en/docusaurus-plugin-content-blog/2020-09-23-git-usage.md index 33e55bbb..9a0ad89a 100644 --- a/i18n/en/docusaurus-plugin-content-blog/2020-09-23-git-usage.md +++ b/i18n/en/docusaurus-plugin-content-blog/2020-09-23-git-usage.md @@ -1,5 +1,5 @@ --- -title: Git 使用指南:理解 Git 工作原理 +title: 'Git usage guide: understanding working principles of Git' author: Josh Cena authorTitle: Leader of Computerization authorURL: https://github.com/Josh-Cena @@ -9,21 +9,19 @@ tags: [git, guide] import useBaseUrl from '@docusaurus/useBaseUrl'; // Add to the top of the file below the front matter. -> 这篇文章是从[C 社的新成员练手 repo](https://github.com/Computerization/New-member-practice-commit) 的 README.md 的第一节转移过来的,添加了一些内容,并做了相应的翻译。(原文用英文的原因,应该是 sy 大佬和我都更习惯用英语写技术相关的内容吧……) +> This article is migrated from the first section of the README.md file in the [new member practice commit repo](https://github.com/Computerization/New-member-practice-commit). -添加文件时,你既可以用带图形用户界面(GUI)的 GitHub Desktop,也可以用命令行。你可以从 GUI 入手,但你会有一天意识到命令行功能的强大,开始用它的。另外,Visual Studio Code 的用户们也可以试试其自带的源代码管理工具。 +You can either add a file via Graphical-User-Interface(GUI)-powered GitHub Desktop or command line. You may begin with GUI, but you will someday get into command lines since they offer better control over your repo. Furthermore, Visual Studio Code users can try out the built-in source control. -我们觉得有必要给你解释你每一步究竟在做什么,而不是让你机械地重复我们写好的教程。这对你尤其有帮助,因为教程通常都把事情想得很完美,但现实则充满了各种意外和变数。阅读时,我们并不要求你事先懂得任何 Git 操作。 +We find it necessary to tell you what you are actually doing each step instead of having you follow the written instructions mechanically. This especially helps since things hardly go as beautifully as the tutorial expects. This section assumes no prior knowledge of any git operations. -你可以把 Git 理解成一个版本控制系统。它能记录每个文件的创建、更改、和删除,而仓库管理者可以在各个版本(commit[^commit])间自由切换,就好像游戏中的若干存档一样。 +You can understand git as a version control system. It keeps track of how each file has been created, modified, and deleted, and the repository owner can switch to any saved version (commit), just like the save files in a game. -[^commit]: 中文大致意思是“提交”——这也是我不喜欢用中文写作的原因,中英混杂总是难以避免。 +## Basic operations: clone, branch, commit, push, pull request -## 基础操作:clone, branch, commit, push, pull request - -假设现在 GitHub 上有这样一个叫 `Hello` 的仓库,是由小丽创建的,装着可能是历史上*最*著名的一段代码。它的目录长这个样子: +Suppose there's a repository out on GitHub named `Hello`, created by Alice to host perhaps _the_ most famous piece of code in history. Its directory looks like this: ```bash . @@ -56,13 +54,13 @@ XiaoLi A piece of C++ code that prints `Hello world!` ``` -你可以把每个 commit 看作是整个仓库的一个快照,一个拷贝。实际上它要比一份完整的拷贝轻量得多,但原理上它保存了那一时刻仓库的全部信息。比如上面的版本就可以看作 `C0` commit。(每个 commit 都有一个独有的哈希值,但长到人类无法阅读。因此用 `C0` 来指代就好了。)我们也管这个 commit 叫 `master` 分支。_一个分支即一系列有线性发展关系的 commit,而 `master` 分支则作为主分支。实际上,一个分支就是一个指向某个 commit 的指针。_ 该项目目前的树状结构如下: +View each commmit as a snapshot of the entire repo. In fact it's much more lightweight than a complete copy, but in essence it contains all the information at that moment. And this version can be viewed as commit `C0`. (Every commit has a unique hash that's too long to be human-readable, so `C0` will suffice.) We also call it the `master` branch. _A branch is a series of commits that form a linear relationship of succession, with the `master` branch being the "main" branch. In essence, it's a pointer to a commit._ Git tree 1 -语言学家小明发现了这个仓库。他对此很感兴趣,但他对小丽还在用古早的 `Hello world!` 非常不满,因此决定做点贡献。为此,他需要先把这个文件夹(也就是仓库)下载下来。这基本就是 **_克隆仓库 (clone the repo)_** 做的事情。 +Bob the linguist finds this repo. He finds great interest in it, but his strong objection to the clichéd `Hello world!` motivates him to make a contribution. To do this, he needs to download this folder (or repository, as people call it) first. This is basically what **_cloning_** does. -小明在自己的机器上有了一份完整的拷贝后,就可以像本地项目一样作编辑了。他对三个文件都作了更新: +After he has a complete copy of the code on his own machine, Bob sets out to make edits. He updates all three files: ```cpp // Hello.cpp @@ -87,29 +85,30 @@ XiaoMing A piece of C++ code that prints `Bonjour le monde!` ``` -现在他的直觉告诉他,他需要把这些代码发回 GitHub。要做到这一点,他可以直接提交一个 commit。但这里有个严峻的问题:_小丽对小明的行为完全没有控制。_ 事实上,大多数公开仓库(包括 C 社的)都限制了其他人直接向 `master` 提交 commit,因为没有哪个环节可以做安全验证。一旦成功 commit,小丽就会惊讶地发现她 GitHub 上的代码变成了法语。并且无论如何,这也是非常恶劣的行为:**在任何合作项目中,都永远不要直接向 master 分支提交 commit。**~~(除非你还有一周就要辞职了)~~ 向 `master` 提交 commit 还有一个问题,我们马上就会看到。 +And now he needs to send it back to GitHub, as his instinct tells him. This is done by directly making a commit. However there's a critical problem here: _Alice has zero control over Bob's action_. In fact, most public repos (including Computerization's) restrict people from commiting directly to `master`, because there's no point of authentication. Once the commit is made, Alice would be back and surprisedly find her code becoming French. And it's bad practice anyways: **In any collaborative repository, never commit directly to master.** ~~(Unless you are resigning in a week)~~ There's another problem with commiting to `master`, which we will shortly see. -因此为了解决这一问题,小明 **_新建了一个分支 (create a branch)_** ,并把它命名为 `XiaoMing/change-output-language`。我们可以认为,小明是在一个和 `master` 相同但独立的文件夹里工作,而他做出的任何改动都不会影响 `master`。这不仅能明确他的目的,确定他分支作者的地位,还能避免冲突和混乱。 +So to fix this problem, Bob **_creates a new branch_**, and names it `Bob/change-output-language`. We may see this as Bob working on a separate but identical folder, and anything he does will not affect `master`. This not only clarifies his purpose, identifies his position as an author, but also prevents conflict and/or confusion. -现在这些变更都会被记录在 `XiaoMing/change-output-language` 中。但当他准备 commit 时,他记起了另一条准则:**一个 commit 只应该实现一个功能。** 重新审视自己的改动,他觉得改变语言和在 `Contributors.txt` 里添加自己的名字应该是独立的改动。(这里的区别微乎其微,但在实际的项目中还是非常容易判断的。)因此他 **_上传了两个 commit (make a commit)_** ,分别命名为 `Change output to French` 和 `Add XiaoMing's name to Contributors.txt`,而它们的哈希值分别为 `C1` 和 `C2`。注意,他不一定是按顺序做出这些改动的,但 Git 把 `C2` 当作 `C1` 的继承者,因为它是后来的 commit。现在,`XiaoMing/change-output-language` 这一分支就指向了 `C2` commit。该仓库现在的 Git 树如下: +He made the said changes. But then he remembered another code of honor: +**one commit should only serve one purpose**. Looking back at his changes, he believes that changing the language and adding his name in the `Contributors.txt` should be separate things (the difference is minute here, but in real projects it gets obvious). Therefore he **_makes two commits_** called `Change output to French` and `Add Bob's name to Contributors.txt`, which will be neatly given hashes `C1` and `C2`. Note he did not necessarily work on them sequentially, but git treats `C2` as a successor of `C1` since it's a more recent commit. Now the branch `Bob/change-output-language` refers to the commit `C2`. Git tree 2 -此时他的改动还只是本地的——没人能在 GitHub 网页上看到它们。因此他接下来 **_发布了分支并将其推送至源 (publish branch and push to origin)_** 。这会把 `XiaoMing/change-output-language` 这一分支及其包含的所有 commit 上传到 GitHub 远程终端。 +At this point his changes have remained local -- no one can see it on the GitHub page. So then he **_publishes the branch and pushes it to the origin_**. This uploads this branch, `Bob/change-output-language`, with all the commits it contains, to the GitHub remote. -当他发布了分支之后,其后在该分支上做出的任何 commit 都会自动被同步到 GitHub 上。 +After he has published the branch, any further commits he makes on this branch will be automatically synchronized with GitHub as well. -紧接着,他 **_发布了拉取请求 (create pull request)_** ,请求代码拥有者(也就是小丽)合并这一分支。_分支被合并后,所有的改变都会在 `master` 中体现出来。_ +Directly after, he **_makes a pull request_** to ask the code owner (a.k.a. Alice) to merge this branch. _When a branch is merged, all the changes will now be reflected in `master`._ -只有一个分支时,事情非常简单,因为此时分支上所有的 commit 都是 `master` 的继承者,在合并分支时,Git 只需要把所有东西都加到 `master`,也就是 `C0` 上,就可以了。因此,它会移动 `master` 指针: +This sounds really simple when there's only one branch, because git simply adds everything to `master` when all commits are successors of `master`, which is now `C0`. So Git moves the `C0` pointer: Git tree 3 -而事实上,以上就是所有 Git 新用户需要明白的操作。但作为未来的 GitHub 代码管理者,你应当思考得更深入一点。 +And in fact, above is all for new git users to understand. But as future GitHub admins, you deserve to think a little deeper. -## 解决冲突 +## Resolving conflicts -为了让事情更有趣一点,我们又同时请来了守旧派小红。她对小丽忘记在 cpp 文件结尾加 `return 0;` 非常不满,因此决定修正这一问题。同样地,她复制了仓库,在 `master` 上新建了一个叫 `XiaoHong/improve-code-style` 的分支,而由于此时小明还没有提交分支,`master` 仍然指向 `C0`。文件改动如下(`C3`): +So to make thing more fun, Cindy the orthodox comes simultaneously with Bob. Outraged by Alice dropping the `return 0` in the cpp file, she decides to fix it. Similarly, she creates a new branch `Cindy/improve-code-style` from `master`, which at this point is still `C0`. The files are changed as: ```cpp // Hello.cpp @@ -135,15 +134,15 @@ XiaoHong A piece of C++ code that prints `Hello world!` ``` -她发布了分支并提交了合并请求。此时,Git 树如下: +She publishes the branch and opens a pull request. Git tree 4 -小丽午休结束之后,回到 GitHub 页面上,发现多了两个合并请求。她开心地合并了小明的请求: +Alice, after her tea break, comes back to find the two pull requests. She happily merges Bob's one; Git tree 5 -但却发现不能直接合并小红的。GitHub 警告说,该分支和 `master` 间有冲突,因为有同时作出的修改,Git 不知道要留下哪一个,因此需要她手动解决冲突。解决页面有如下的内容: +but then Cindy's one she can not merge on click of a button. GitHub throws a warning, telling her there's a conflict with `master`. She has to resolve the conflict manually, because git didn't know which version to keep when they are made parallelly. The resolving page shows something like: ```cpp // Hello.cpp @@ -169,7 +168,7 @@ A piece of C++ code that prints `Hello world!` >>>>>>> XiaoHong/improve-code-style ``` -注意到 README.md 文件不需要解决冲突,因为只有小明作了修改;Git 还是能意识到这一点的。怎么解决上述问题对小丽这样的人类还是非常显然的:只要同时留下两人所做的改动即可。因此,她删去了多余的内容,解决了冲突,并合并了小红的分支。文件现在的样子(`C4`): +Note that the README.md file needs no resolution because only Bob had made a change; git is smart enough to realize that. But the above issues are pressing. How to resolve them are pretty apparent to humans like Alice, though, so she quickly fixed these, and merged Cindy's branch with no conflict. The files are now (`C4`): ```cpp // Hello.cpp @@ -196,17 +195,17 @@ XiaoHong A piece of C++ code that prints `Bonjour le monde!` ``` -而在合并一个并不是自己的继承者的分支时,Git 会新建一个 commit: +And to merge a branch into a branch that is not a successor, Git will create a new commit: Git tree 6 -此时,小丽、小明、小红三人就成功地完成了一次在 GitHub 上的开源项目合作。 +And Alice, Bob, and Cindy are happy about their successful collaboration over GitHub on an open-source project. -如果想要学习更多 Git 有关的知识,并深入研究它的树状结构,可以访问这个网站:[Learn Git Branching](https://learngitbranching.js.org) +To understand more about git and its tree structure (as already implied above), check this out: [Learn Git Branching](https://learngitbranching.js.org) -## 拓展阅读 +## Further Reading -如果想要了解 `pull`, `push`, `commit`, `add`, 和 `checkout` 时具体发生了什么,可以参考以下网站: +To discover what happens when you `pull`, `push`, `commit`, `add`, or `checkout`, you can refer to the following sites: - [Git SCM - Getting Started: Git Basics](https://git-scm.com/book/en/v1/Getting-Started-Git-Basics) - [Git SCM - Git Branching: Branches in a Nutshell](https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell) @@ -216,10 +215,10 @@ A piece of C++ code that prints `Bonjour le monde!` - [Understanding Git: Branching](https://hackernoon.com/understanding-git-branching-2662f5882f9) - [Understanding Git: Index](https://hackernoon.com/understanding-git-index-4821a0765cf) -除此之外,如果你不喜欢阅读长篇大论,你可以观看下面这个长约 82 分钟的 YouTube 视频: +Alternatively, if you don't like reading long texts, you can watch this YouTube video (about 82-min long): - [\[VIDEO\] Introduction to Git with Scott Chacon of GitHub](https://www.youtube.com/watch?v=ZDR433b0HJY) -也可以在这个可视化的页面上尝试各类 Git 指令: +Or try the commands out on this visualized webpage: - [Learn Git Branching](https://learngitbranching.js.org) diff --git a/i18n/en/docusaurus-plugin-content-blog/2020-10-10-algorithm1.mdx b/i18n/en/docusaurus-plugin-content-blog/2020-10-10-algorithm1.mdx index 82e8ad10..b3715526 100644 --- a/i18n/en/docusaurus-plugin-content-blog/2020-10-10-algorithm1.mdx +++ b/i18n/en/docusaurus-plugin-content-blog/2020-10-10-algorithm1.mdx @@ -1,5 +1,5 @@ --- -title: 斐波那契数列 +title: Fibonacci sequence author: Josh Cena authorTitle: Leader of Computerization authorURL: https://github.com/Josh-Cena @@ -9,7 +9,7 @@ tags: [algorithm] import useBaseUrl from '@docusaurus/useBaseUrl'; -这是 C 社算法团队的第一次活动。我们介绍了斐波那契数列的第$n$项求解方法,主要运用了矩阵快速幂算法。 +This is the first activity of Computerization algorithm team. We introduced the method to find the $n$th term of the Fibonacci sequence, which mainly uses matrix exponentiation. @@ -28,10 +28,10 @@ export const Question = ({ children, color }) => (
); -## 题目 +## Problem - 斐波那契数列: + The Fibonacci sequence: $$ F_{n}= @@ -42,45 +42,45 @@ F_{n}= \end{cases} $$ -给定$n$,求$F_{n}\text{ mod }10^9+7$。 +Given $n$, find $F_{n}\text{ mod }10^9+7$。 -| 数据规模 | 内存限制 | 运行时间 | -| ------------------- | -------- | -------- | -| $0\le n\le 10^{19}$ | 64MB | 1.0s | +| Input constraints | Memory limit | Execution time | +| ------------------- | ------------ | -------------- | +| $0\le n\le 10^{19}$ | 64MB | 1.0s | -## 题解 +## Solution -$10^{19}$显然灭掉了所有用循环解决的想法。有没有比简单的$\mathcal{O}(n)$更好一点的方法?用**矩阵快速幂**,可以达到$\mathcal{O}(\log n)$。观察到: +The input size of $10^{19}$ obviously prohibits any attempt to solve it with loops. Is there a better way than a simple $\mathcal{O}(n)$? It turns out that with **matrix exponentiation**, we can achieve $\mathcal{O}(\log n)$. We observe that: $$\begin{pmatrix}F_{n+1}\\F_{n+2}\end{pmatrix}=\begin{pmatrix}F_{n+1}\\F_{n}+F_{n+1}\end{pmatrix}=\begin{pmatrix}0&1\\1&1\end{pmatrix}\begin{pmatrix}F_{n}\\F_{n+1}\end{pmatrix}$$ -这一步对于所有递推数列都是适用的,因此在有经验之后应该非常容易得到。一般地,对于$F_{n+2}=aF_{n}+bF_{n+1}$,有 +This step is applicable to all recursive sequences, so it should be easily reached for an experienced candidate. Generally, for $F_{n+2}=aF_{n}+bF_{n+1}$, we have $$\begin{pmatrix}F_{n+1}\\F_{n+2}\end{pmatrix}=\begin{pmatrix}F_{n+1}\\aF_{n}+bF_{n+1}\end{pmatrix}=\begin{pmatrix}0&1\\a&b\end{pmatrix}\begin{pmatrix}F_{n}\\F_{n+1}\end{pmatrix}$$ -从递推式中有 +From the recursive definition, $$\begin{pmatrix}F_{n+m}\\F_{n+m+1}\end{pmatrix}=\begin{pmatrix}0&1\\1&1\end{pmatrix}^m\begin{pmatrix}F_{n}\\F_{n+1}\end{pmatrix}$$ -取$n=0$,得到 +Substituting $n=0$, $$\begin{pmatrix}F_{m}\\F_{m+1}\end{pmatrix}=\begin{pmatrix}0&1\\1&1\end{pmatrix}^m\begin{pmatrix}F_0\\F_1\end{pmatrix}$$ -因此把问题转化成了如何求矩阵$m$次方的问题。如果设$m=2^0a_0+2^1a_1+2^2a_2+\dots$(也就是把$m$用二进制表示),那么有 +Now the problem is transformed into finding the matrix raised to the $m$th power. If $m=2^0a_0+2^1a_1+2^2a_2+\dots$ (representation in binary), then $$\begin{pmatrix}0&1\\1&1\end{pmatrix}^m=\left(\begin{pmatrix}0&1\\1&1\end{pmatrix}^{1}\right)^{a_0}\times \left(\begin{pmatrix}0&1\\1&1\end{pmatrix}^{2}\right)^{a_1}\times \left(\begin{pmatrix}0&1\\1&1\end{pmatrix}^{4}\right)^{a_2}\dots$$ -而这些矩阵的$2^k$次方,完全可以预处理。当$m$的数量级为$10^{19}$时,$k<\log_2 10^{19}<64$,最多只需要存储 63 个矩阵。并且 +The $2^k$th powers of the original matrix can, in fact, be preprocessed. When $m<10^{19}$, $k<\log_2 10^{19}<64$, so we only need to store at most 63 matrices. In addition, $$\begin{pmatrix}0&1\\1&1\end{pmatrix}^{2^k}=\begin{pmatrix}0&1\\1&1\end{pmatrix}^{2^{k-1}}\times \begin{pmatrix}0&1\\1&1\end{pmatrix}^{2^{k-1}}$$ -这些乘方可以在$\mathcal{O}(\log m)$时间内得到。这便是快速幂的思想:计算所有的$2^k$次方,然后把其中需要的那些组合起来即可。 +which implies that the powers can be attained within $\mathcal{O}(\log m)$ time. This is the idea of fast matrix exponentiation: compute all $2^k$th powers, and put those needed together. -## 程序 +## Program -下面是 C++ 代码,其中最繁琐的部分是实现矩阵乘法: +Below is the C++ code, where the most intractable part is probably implementation of matrix multiplication: ```cpp #include @@ -100,18 +100,18 @@ struct mat { } }; -// 预处理的矩阵 2^k 次幂 +// Preprocessed matrices raised to the 2^k power mat mat_pow[64]; int fib(unsigned long long k) { - // 临时矩阵,每次在此上面乘以 mat_pow 中的某项 + // Temporary matrix; each time multiply it by some term in mat_pow mat tmp; tmp.a[0] = 1; tmp.a[1] = 0; tmp.a[2] = 0; tmp.a[3] = 1; for (int i = 0; i < 64; i++) { - // 如果 a_i 为 1 + // If a_i is 1 if (k & (1ull << i)) { tmp = tmp * mat_pow[i]; } @@ -134,7 +134,7 @@ int main() { } ``` -补充一下矩阵的乘法公式: +The formulae for matrix multiplication are: $$\begin{pmatrix}a_0&a_1\\a_2&a_3\end{pmatrix}\times\begin{pmatrix}b_0&b_1\\b_2&b_3\end{pmatrix}=\begin{pmatrix}a_0b_0+a_1b_2&a_0b_1+a_1b_3\\a_2b_0+a_3b_2&a_2b_1+a_3b_3\end{pmatrix}$$ diff --git a/i18n/en/docusaurus-plugin-content-blog/2020-11-04-algorithm3.mdx b/i18n/en/docusaurus-plugin-content-blog/2020-11-04-algorithm3.mdx index fe2a0ad4..e9479ee0 100644 --- a/i18n/en/docusaurus-plugin-content-blog/2020-11-04-algorithm3.mdx +++ b/i18n/en/docusaurus-plugin-content-blog/2020-11-04-algorithm3.mdx @@ -1,5 +1,5 @@ --- -title: 阶乘字符串 +title: Factorial string author: DoremySwee authorTitle: Member of algorithm team authorURL: https://github.com/DoremySwee @@ -9,7 +9,7 @@ tags: [algorithm] import useBaseUrl from '@docusaurus/useBaseUrl'; -这是 C 社算法团队的第三次活动。我们研究了一道上海省选的题目,主要运用了状态压缩动态规划算法。其中数学部分比较困难,尚未给出严格证明。 +This is the first activity of Computerization algorithm team. We discussed a problem from Shanghai NOI regional selection, which leverages state compression dynamic programming. The mathematics is beyond our capacity to be rigorously proven. @@ -28,42 +28,43 @@ export const Question = ({ children, color }) => (
); -## 题目 +## Problem - 原题链接 + Problem link -给定一个由前$n$个小写字母组成的串$S$。串$S$是阶乘字符串当且仅当前$n$个小写字母的全排列(共$n!$种)都作为的子序列(可以不连续)出现。 +Given a string $S$ composed of the first $n$ lower-case letters, $S$ is a _factorial string_ if all the permutations of the first $n$ lower-case letters (there are $n!$ of them)(共$n!$种)are subsequences (not necessarily consecutive) of $S$. -由这个定义出发,可以得到一个简单的枚举法去验证,但是它实在太慢了。所以现在请你设计一个算法,在 1 秒内判断出给定的串是否是阶乘字符串。 +Given this definition, we can easily verify if a sequence is factorial by bashing, but it's too slow. Please design an algorithm that verifies if a string is factorial in 1 second. -| 数据规模 | 内存限制 | 运行时间 | -| ------------------------- | -------- | -------- | -| $\|S\|\le 450$, $n\le 26$ | 125MB | 1.0s | +| Input constraints | Memory limit | Execution time | +| ------------------------- | ------------ | -------------- | +| $\|S\|\le 450$, $n\le 26$ | 125MB | 1.0s | -## 题解 +## Solution -暴力解法自然是枚举全排列并检验,30%的分数到手,不过这个程序没有其它太大意义,甚至由于阶乘级的时间复杂度难以对拍。不多作讨论。 +The bashing solution is obviously enumerating all permutations and checking if they are subsequences. You get 30% of the score from this method, but the program is pretty meaningless, and the factorial time complexity prohibits further optimization, so we don't discuss further on this attempt. -考虑 70%的分数。$n\le 20$,可以考虑$\mathcal{O}(2^n)$的算法。既然不能进行全排列的枚举,那么完全可以考虑状态压缩动态规划,枚举一个字母是否出现在状态中。由于要求解的是整个字符串中是否存在前$n$个字母的全排列,则考虑$f(x)$表示$x$对应的几个字母的全排列最早出现在字符串种的何处。 -状态转移方程举例: +Now consider the rest 70% marks. For $n\le 20$ we may consider an $\mathcal{O}(2^n)$ algorithm. Since a full enumeration is not possible, we shall turn to state compression dynamic programming, and enumerate if a letter exists in the state. Since we need to find if all permutations of the first $n$ letters exist in $S$, we will keep track of the earliest occurence of $x$ in $S$. + +The state transfer equation: $$ \begin{aligned} - f(a,b,c,e)=\max(&从f(a,b,c)开始找第一个\texttt{'e'}, \\ - &从f(a,b,e)开始找第一个\texttt{'c'}, \\ - &从f(a,c,e)开始找第一个\texttt{'b'}, \\ - &从f(b,c,e)开始找第一个\texttt{'a'}) + f(a,b,c,e)=\max(&\text{first }\texttt{`e'}\text{ from }f(a,b,c), \\ + &\text{first }\texttt{`c'}\text{ from }f(a,b,e), \\ + &\text{first }\texttt{`b'}\text{ from }f(a,c,e), \\ + &\text{first }\texttt{`a'}\text{ from }f(b,c,e)) \end{aligned} $$ -但是如果对于每一个寻找都是通过循环寻找的话,时间会有点长,只能拿 50 分,需要进行一定的预处理。可以在预处理之后用二分查找,但是方便起见建议添加一个数组标记每一个位置下一个目标字母的位置,所需时间不长,$450\times 26$而已。 +But if every lookup is done by a loop, we would exceed the time limit and only get 50 points, so we need some preprocessing. We can conduct binary search after preprocessing, but for the sake of convenience, it may be better to maintain another array that marks the position of the next target letter at every position. The time for this is just $450\times 26$. -最后,考虑剩下的分数点。可以发现,对于过大的$n$,可以直接输出`"No"`,至于这个值如何确定?按照$n=3\implies S=\mathtt{abcbab}$,$n=4\implies S=\mathtt{abcdcbabcdcba}$这种构造方式$S$的长度为$n^2-n+1$,$n\le 21$,不过证明过于困难。为保险起见,因为$n=22$时用时是可以接受的,取$n\ge 23$时直接输出`"No"`。 +Now, consider the remaining marks. We notice that for large enough $n$, we can just output `"No"`. But how do we determine the exact threshold? If the construction is like $n=3\implies S=\mathtt{abcbab}$,$n=4\implies S=\mathtt{abcdcbabcdcba}$, the length of $S$ is about $n^2-n+1$,$n\le 21$, but we weren't able to prove it rigorously. To be on the safer side, because the runtime is still acceptable for $n=22$, we choose to output `"No"` for $n\ge 23$. -## 程序 +## Program ```cpp #include diff --git a/i18n/en/docusaurus-plugin-content-blog/2020-12-02-algorithm5.mdx b/i18n/en/docusaurus-plugin-content-blog/2020-12-02-algorithm5.mdx index 107653a0..59db5358 100644 --- a/i18n/en/docusaurus-plugin-content-blog/2020-12-02-algorithm5.mdx +++ b/i18n/en/docusaurus-plugin-content-blog/2020-12-02-algorithm5.mdx @@ -9,7 +9,7 @@ tags: [algorithm] import useBaseUrl from '@docusaurus/useBaseUrl'; -这是 C 社算法团队的第五次活动。由于 12 月 USACO 竞赛在即,我们展开了针对性的练习。第一次活动我们从铜组开始练习,由于成员们水平较高,我们挑选了一道有一定编程水平要求的铜组题目。铜组题目只要求对循环的掌握,一定可以通过枚举得到结果,因此对算法和数据结构没有太高要求。 +This is the fifth activity of Computerization algorithm team. Because the December USACO contest is almost there, we had some targeted practicing, starting with Bronze problems. Because members already have decent understanding, we chose a tough one. Bronze division problems only require mastery of loops, so a brute-force enumaration will always work, with no requirement of algorithms or data structures. @@ -28,11 +28,11 @@ export const Question = ({ children, color }) => (
); -## 题目 +## Problem -**题目来源:****USACO 2019 December Bronze 3** +**Problem source: ****USACO 2019 December Bronze 3** Every day, Farmer John milks his 8 dairy cows, named Bessie, Buttercup, Belinda, Beatrice, Bella, Blue, Betsy, and Sue. @@ -40,21 +40,21 @@ The cows are rather picky, unfortunately, and require that Farmer John milks the Please help Farmer John determine an ordering of his cows that satisfies all of these required constraints. It is guaranteed that an ordering is always possible. If several orderings work, then please output the one that is alphabetically first. That is, the first cow should have the alphabetically lowest name of all possible cows that could appear first in any valid ordering. Among all orderings starting with this same alphabetically-first cow, the second cow should be alphabetically lowest among all possible valid orderings, and so on. -| 数据规模 | 内存限制 | 运行时间 | -| ------------- | -------- | -------- | -| $1\le N\le 7$ | 256MB | 2.0s | +| Input constraints | Memory limit | Execution time | +| ----------------- | ------------ | -------------- | +| $1\le N\le 7$ | 256MB | 2.0s | -## 题解 +## Solution -这道题在理解了题目的需求——生成一个符合给定约束的字典序最小的排列后,应该难度不高。我们可以按字典序生成全部的排列(一共有$8!=40320$种),然后输出第一个满足所有约束条件的。如果不会用回溯算法生成全排列,可能需要借助 `algorithm` 中的 `next_permutation` 函数。这也是典型的铜组思路:因为规模极小,可以暴力枚举之后*挑选*解而不是*构造*解。 +Once we understand what the problem asks for—generating a permutation with the smallest lexicographical order that satisfies the given constraints—it should not be too hard. We can generate all permutations in lexicographical order (there are $8!=40320$ of them), and output the first that satisfies all constraints. If you don't know about backtracking algorithm, you can still get assistance from the `next_permutation` function provided by `algorithm`. This is a typical Bronze solution: because of the small input size, we can _choose_ a solution after an enumeration instead of _constructing_ one. -当然,这种方法对于有一些竞赛经验的参赛者来说反倒不容易想到。这些参赛者会试图通过约束条件来构造解。这需要一点点贪心的思想:为了让排列字典序最小,就一定要让每一位上的奶牛字典序尽可能小。我们可以把一个排列看作一个“约束链”,其中每一头奶牛都因为它相邻位置奶牛的约束而只有唯一的可能。每完成一条约束链的连接后,都可以从剩下未被安排进队的奶牛中挑选编号最小的,但不能是有两个未满足的约束的(因为一个“约束链”中头和尾的奶牛都只能和它相邻的一头奶牛间有约束),然后在确定了链头之后,就可以非常自然地得到整个链条。重复同样的构造过程,直到所有奶牛都被添加入队列。 +However, this approach may be less obvious to some experienced candidates. These candidates will attempt to construct a solution through the constraints. This needs some greedy strategy: to achieve the lowest lexicographical order, we need to have the smallest cow possible at every position. We can view an ordering as a "constraint chain", where every cow has only one possible location due to the cows that it must be adjacent to. After joining each chain, we can choose the smallest cow that hasn't been settled yet—but this cow cannot have two unmet constraints, since the cows at both ends of a chain can only be connected to one neighboring cow. After fixing the chain's head, we can naturally generate the entire chain. Repeat the same process until all cows have been settled. -## 程序 +## Program -暴力法的代码: +Brute-force enumeration: ```cpp /** @@ -69,7 +69,7 @@ Please help Farmer John determine an ordering of his cows that satisfies all of using namespace std; string names[8] = {"Beatrice", "Belinda", "Bella", "Bessie", "Betsy", "Blue", "Buttercup", "Sue"}; -// beside_a 和 beside_b 中对应下标的奶牛表示一组约束关系 +// beside_a[i] and beside_b[i] denote one pair of neighboring cows vector beside_a, beside_b; int n; @@ -97,7 +97,7 @@ int main() { beside_a.push_back(a); beside_b.push_back(b); } - // 遍历所有的8头奶牛的排列,输出第一个满足约束的解 + // Iterate over all permutations of the 8 cows, and output the first valid solution do { if (satisfies_constraints()) { for (int i = 0; i < 8; i++) @@ -109,7 +109,7 @@ int main() { } ``` -构造法的代码: +Construction: ```cpp #include @@ -118,9 +118,9 @@ int main() { using namespace std; struct cow { - int adj[2]; // 需要和这头奶牛相邻的奶牛的ID - int adjcnt; // 这头奶牛一共有几个约束条件;决定了能否把它放在约束链的开头 - bool chosen; // 是否已经进队 + int adj[2]; // ID(s) of the cow(s) that need to be neighboring this cow + int adjcnt; // Number of constraints for this cow; decides if this cow can be put at the head of a constraint chain. + bool chosen; // If already in the ordering } cows[8]; string names[8] = {"Beatrice", "Belinda", "Bella", "Bessie", "Betsy", "Blue", "Buttercup", "Sue"}; @@ -143,7 +143,7 @@ int main() { cows[getID(b)].adj[cows[getID(b)].adjcnt++] = getID(a); } int prev = -1; - // 每次循环向队列中添加一头奶牛;如果上一头奶牛没有更多的约束条件了,则可以选择一头新的,否则选择需要和上一头相邻的奶牛 + // On every iteration add a cow to the ordering. If the last cow has no additional constraints, we may choose a new one; otherwise, we need to choose the one that the constraint requires. for (int _ = 0; _ < 8; _++) { if (_ == 0 || cows[prev].adjcnt == 0) { for (int i = 0; i < 8; i++) { @@ -157,7 +157,7 @@ int main() { } else if (cows[prev].adjcnt == 1) { int i = cows[prev].adj[0]; cows[i].chosen = true; - // 这里的操作是在把cows[i]添加入队列的同时“删除”掉它已经满足的那条约束 + // Add cow[i] to the ordering, and "delete" the constraint already satisfied cows[i].adjcnt--; if(cows[i].adj[0] == prev) cows[i].adj[0] = cows[i].adj[1];