音乐
以下排名不分先后。 二次元名曲 打上花火(烟花) DAOKO x 米津玄师 我们二次元也有自己的难忘今宵! 伴随着你(天空之城) 久石让最好听的一首歌。 遠い空へ(缘の空) 央视都在用的音乐。 千本桜 初音万岁! 鸟之诗(AIR) 动漫届的国歌,未看其番,先闻其歌。再看其番,人过中年。 ...
感谢支持
就在昨天,我收到了自网站建立以来的第一笔赞助! 这份支持来自 *邦 大哥,对我来说意义非凡。 从搭建网站的第一行代码,到现在慢慢有人愿意浏览、愿意支持,这段路不算容易,但却无比值得。有你们在,我才更有动力继续创作、持续优化、不断前行。 感谢你们的认可和鼓励,未来我会继续更新内容,不负所托。
我掌握的技术栈
🖥️ 操作系统 Windows 系列:Windows XP、Windows 7、Windows 8、Windows 10、Windows 11 macOS Linux 发行版:Ubuntu、Arch Linux、Kali BSD 系列:OpenBSD 💻 编程语言 C++ Python JavaScript HTML / CSS 🛠️ 工具与框架 Adobe Photoshop Blender Adobe Illustrator Hexo Hugo Unreal Engine 4 / 5 ⚙️ 常用开发环境 主力系统:Arch Linux IDE:Visual Studio、VS Code 构建工具:g++ 版本控制:Git、GitHub 终端工具:zsh 🐧 Linux 运维经验 基础操作:系统安装、用户权限、挂载、软件包管理(pacman / apt) 服务管理:使用 systemd、配置 SSH、Nginx 等服务 熟悉基本的日志查看与问题排查方法 🎮 小插曲:做过一款“胎死腹中”的游戏 曾尝试使用 Unreal Engine 5 开发一款游戏,但因为队友太拉,项目草草结束。 但也因此接触到了虚幻引擎的蓝图系统和关卡搭建,对游戏开发产生了一定兴趣。
【MIT 6.006】Lecture 1 Notes
本文件内容源自麻省理工学院开放课程资料平台,根据官方英文讲义翻译而成,由 ChatGPT 初步翻译,并经人工精校润色。打印版参见:https://linmoh.github.io/mit6.006/l1.html 算法导论:6.006 麻省理工学院 讲师:Erik Demaine、Jason Ku 和 Justin Solomon 讲座 1:导论 本课程的目标是教会你如何解决计算问题,并说明你的解决方案是正确且高效的。 问题 问题输入与正确输出之间的二元关系 通常不会为所有输入指定每一个正确输出(太多了!) 提供一个可验证的谓词(属性),正确输出必须满足它 6.006 研究的是大规模、通用输入空间上的问题 非通用:小输入实例 例子:这个房间里是否有两位同生日的学生? 通用:任意大的输入 例子:给定任意 n 位学生,是否存在一对同生日的学生? 若生日只在 365 天中选,对于 n > 365,根据鸽巢原理,答案一定为真 假设生日的精度超过 n(包含年份、时间等) 算法 一个过程:将每个输入映射到一个输出(确定性) 若算法对每个问题输入都返回正确输出,则称其解决了该问题 例子:一个解决同生日问题的算法 保持一个姓名和生日的记录(初始为空) 按某个顺序询问每个学生 ∗ 若生日已在记录中,返回这对学生! ∗ 否则,将姓名和生日加入记录 若全部学生都询问完仍无结果,则返回 None 正确性 程序/算法是有限大小,如何证明其正确? 对于小输入,可使用情况分析 对于任意大的输入,算法必须以某种方式使用递归或循环 必须使用数学归纳法(递归在计算机科学中的关键原因) 例子:生日匹配算法的正确性证明 对 k 归纳:记录中已有的学生数量 假设:若前 k 位中有匹配,算法在询问第 k+1 位前就返回 基础情况:k = 0,前 k 位无匹配 假设归纳假设对 k = k₀ 成立,考虑 k = k₀ + 1 若前 k₀ 位已有匹配,算法已返回(由归纳) 否则,若前 k₀ + 1 位有匹配,匹配一定包含第 k₀ + 1 位 那么算法直接检查第 k₀ + 1 位学生的生日是否已在记录中 效率 算法生成正确输出的速度有多快? ...
【公告】关于以后的打算 & 网站的更新规划
以后的打算 以后我将学习以下几门科目(按优先度排序,不算课内内容) 计算机科学:这是为将来找工作打基础的必修课。 经济学:扩展知识面,也希望能培养点经济头脑。 英语:既是学业需求,也为就业做准备。 生物学(高中部分):主要为了应付现在的考试。 日语:算是兴趣加未来可能的国际发展准备。 总体上,我把学习内容分成两类: 就业导向:计算机科学、经济学、英语、日语,都是为了以后能顺利步入社会。 学业导向:英语和生物学,主要是为了应付眼下的课业和考试。 说实话,现在看来时间真的挺紧的,感觉总是不够用。以后得更加合理规划时间,娱乐时间肯定得压缩点,争取高效学习。 网站的更新规划 因为山东现在实行双休,时间上宽裕了不少,所以我打算给网站多花点时间。具体计划是: 题解:只写那些真有价值、有深度的题目,避免泛滥。 算法笔记 / 教学内容 / 数学相关:暂时先停一停,腾出精力做更重要的事情。 高质量文章:每个月争取写两篇,力求内容有深度、有用。 普通文章:保持频率,每周三篇,主要分享日常感想和一些技术内容,保持网站活跃。 总之,我想通过集中精力产出更优质的内容,让网站更有价值,同时也能兼顾学业和个人规划。希望以后大家多多支持!
【微观经济学】经济学十大原理
引言:我开始学习经济学 我有一个众所周知的小秘密:我希望我的下一代,甚至下下一代,能够进入上流社会,拥有更好的生活。 为了实现这个目标,我决定开始学习经济学,研究怎么搞钱 探索市场的规律和财富增长的奥秘。 经济学十大原理 原理一:人们面临权衡取舍 在资源有限的世界中,我们做每一个选择时,通常都意味着要放弃一些别的东西。这就是所谓的「权衡取舍」。简单说,就是:选择 A,就必须放弃 B。 举例解析 比方说,你是一个初中生,晚上有 2 小时自由时间,你面临三个选项: 做数学作业 看喜欢的动漫(比如《孤独摇滚》) 和朋友语音聊天打游戏 如果你决定用这两个小时做数学作业,那么你就放弃了看动漫和打游戏的机会,这就是一种权衡取舍。 原理二:某种东西的成本是为了得到它所放弃的东西 在经济学中,这个原理强调的是机会成本的概念。 当你做一个选择时,真正的成本不只是你花了多少钱或多少时间,而是你为做这个选择所放弃的「最有价值的其他选择」。 举例解析 比方说,假设你晚上可以: 花 2 小时看《孤独摇滚!》 或者用这 2 小时学习 C++ 和算法 你选择了看动漫,那么你为此所付出的「成本」,并不仅仅是2小时,而是你放弃了这2小时里可能提升编程技能、提高 OI 成绩的机会。所以你看动漫的「经济学成本」是这段时间本来可能带来的知识积累或竞赛得分。 原理三:理性人考虑边际量 在经济学中,「理性人」指的是那些有目的、有逻辑地做决策的人。他们不会轻易浪费资源,会在做决策时考虑「边际变化」。 边际量 「边际」意思是额外的一点点变化。也就是说,理性人不是考虑「全部」或「一刀切」的选择,而是问: 如果我再多做一点,会不会更好? 如果我再少做一点,是不是更节省? 边际分析就是衡量「多做一点」带来的额外收益和额外成本,然后做出最优选择。 举例解析 你明天要考 CSP-J,今天已经学习了 6 小时,考虑是否要再学 1 小时。 你就要考虑: 边际收益:再学 1 小时能不能再提升 5 分? 边际成本:这 1 小时可能让你太疲惫、没时间吃饭或影响睡眠 如果你判断这额外 1 小时学不到什么新东西,还可能影响明天状态,那理性选择就是不再继续学。 理性人的决策方式 if 边际收益 ≥ 边际成本: do it! else if 边际收益 < 边际成本: don't do it! 原理四:人们会对激励做出反应 在经济学中,「激励」指的是能影响人们行为的奖励或惩罚。 人们做出决策时,常常会根据激励来改变自己的选择。激励可以是:金钱、时间、成绩、情绪、声望等。人们不是凭空改变行为,而是因为有「改变行为的理由」,这就是激励。 举例解析 老师说:「谁今天晚上 8 点前交作业,就多加 2 分。」 ...
国产软件,越做越「重」
好的设计是看不见的服务,坏的设计是强迫性的对话。 ——唐纳德·诺曼《设计心理学》 自从几年前开始「科学上网」后,我的手机界面也悄然发生了变化:国内 App 和海外 App 仿佛成了两个不同世界的缩影。 图标设计:两个「审美」体系 最直观的区别,或许就是图标了。 海外 App 的图标普遍追求极简主义:形状规整、配色克制、更新缓慢。比如 Twitter(现𝕏)沿用蓝鸟符号十余年,Telegram的纸飞机、Spotify的声波图标,这些软件的图标几乎从未做过大幅修改。简洁、稳定,是它们传递出的第一印象。 反观国内 App,一年四季「百变造型」:618、双十一、春节、暑期档、开学季……各种节日与营销活动层出不穷,图标就像广告牌,忙得不亦乐乎。银行 App 图标还会直接加上版本号,给人一种“更新=进化”的错觉。美团、阿里、百度系的软件甚至会把品牌 LOGO 直接换成节日口号,一时间让人难以辨认。 ...
我开始记录代码之外的东西了
过去这个站主要是放技术内容,像博客、命令、折腾记录。现在也还是,但好像有点变了。准确说,我的关注点变了。 比如那天晚上写「焦虑的夜」,其实没想太多,就是单纯想把那种感觉写下来。写完后居然挺轻松的,比刷完一道算法题更像「做成了一件事」。 这两年我写了很多代码,建了几个站,刷了一些题,也搬了几次系统(是的,我真的折腾过头了)。但很少去想我自己在这些事中处于什么状态。也许这就是为什么最近我开始写这些「不那么技术」的东西。它们没有那么「有用」,但对我好像挺必要。 以后可能会在这里写点音乐、写作业的内容、写点聊天记录、做梦的内容。或者说,这个站会变得更「人」一点,而不是「作品集」那样的东西。
关于音乐
我一向对娱乐圈的“乱象”持反感态度,因此从不关注相关资讯。我与所谓的“饭圈文化”始终保持着清晰的界限。也正因如此,我更倾向于聆听那些真正触动人心的作品,比如米津玄师的歌。 其中,我最喜欢的一首歌之一,是《Lemon》,这是米津玄师为祖父的去世而作的,讲的是生死的理解。歌词如下: 日文 中文翻译 夢ならばどれほどよかったでしょう 如果这一切都是梦境该有多好 未だにあなたのことを夢にみる 至今还能在梦中寻到你的身影 忘れた物を取りに帰るように 就像归家取回遗忘之物 古びた思い出の埃を払う 打扫尘封的记忆 戻らない幸せがあることを 幸福无可再挽回 最後にあなたが教えてくれた 是你最后告诉了我 言えずに隠してた昏い過去も 那些未对他人提及过的晦暗往事 あなたがいなきゃ永遠に昏いまま 如果没有你它们将永远沉睡在黑暗中 きっともうこれ以上傷つくことなど 明白必定不会再有其他 ありはしないとわかっている 伤心胜过于此 あの日の悲しみさえ 甚至那日的悲伤 あの日の苦しみさえ 甚至那日的痛苦 そのすべてを愛してた あなたとともに 将所有一切,连同深爱的你一起 胸に残り離れない 都化作深深烙印在我心中 苦いレモンの匂い 苦涩柠檬的香气 雨が降り止むまでは帰れない 在雨过天晴前都无法归去 今でもあなたはわたしの光 时至今日 你仍是我的光芒 暗闇であなたの背をなぞった 在黑暗中追寻着你的身影 その輪郭を鮮明に覚えている 那轮廓至今仍鲜明地刻印于心 受け止めきれないものと出会うたび 每当遭遇无法承受的苦痛时 溢れてやまないのは涙だけ 汹涌不停的都只有泪水 何をしていたの 曾经历过什么 何を見ていたの 曾目睹过什么 わたしの知らない横顔で 脸上浮现着我不曾见过的神情 どこかであなたが今 如果你正在什么地方 わたしと同じ様な 与我一样 涙にくれ淋しさの中にいるなら 终日过着以泪洗面的寂寞生活 わたしのことなどどうか忘れてください 就请你将我的一切全部遗忘吧 そんなことを心から願うほどに 我从心底里祈愿 今でもあなたはわたしの光 时至今日 你仍是我的光芒 自分が思うより恋をしていたあなたに 我深深地恋慕着你 甚至超出自己的想象 あれから思うように息ができない 自那以后 再不能随心呼吸 あんなにそばにいたのにまるで嘘みたい 明明曾如此贴近 如今却恍如虚幻 とても忘れられないそれだけが確か 唯一能确定的是 对你难以遗忘 あの日の悲しみさえ 甚至那日的悲伤 あの日の苦しみさえ 甚至那日的痛苦 そのすべてを愛してた あなたとともに 将所有一切,连同深爱的你一起 胸に残り離れない 都化作深深烙印在我心中 苦いレモンの匂い 苦涩柠檬的香气 雨が降り止むまでは帰れない 在雨过天晴前都无法归去 切り分けた果実の片方の様に 如同被切开的半个柠檬一般 今でもあなたはわたしの光 时至今日 你仍是我的光芒 然而,最近在 B 站上偶然刷到一段视频,其中某些团体成员将《Lemon》的情绪深意“创意性”地嫁接到了咀嚼柠檬的体验之上,例如: ...
课本剧剧本《范进中举》
人物: 范进:老实忠厚的穷书生 母亲:年老体弱,慈爱却辛苦操持 胡屠户:范进的岳父,粗鲁泼辣 报录人(邻居):兼任报喜人、邻里、说书者角色 道具: 一瓶酒(可为空瓶) 报帖(写着“范讳高中广东乡试第七名亚元”) 一小桌、一张椅子若干 【一幕】范进中举 (舞台分两边,左为范进家草棚,右为集市,桌椅作背景) 【场景一:家中报喜】 (范进推门而入) 范进:(欢喜地)娘!我中了!中了秀才啦! 母亲:(激动)哎呀!我的儿啊!你可算熬出来啦! (母子相拥,妻子(由母亲客串)也在灶下烧饭) (胡屠户提着“肠子”和“酒”走进) 胡屠户:(甩手坐下)我倒了八辈子血霉,把女儿嫁给你这现世宝。如今不知我哪辈子积了德,你倒中了相公。我带了点酒来贺喜。 范进:(唯唯连声)多谢岳父,多谢岳父! 胡屠户:(训诫)你既中了相公,要立起个体统。你若见着那些扒粪种田的还拱手作揖,岂不是坏了规矩?也丢我的脸! 范进:岳父见教的是。 胡屠户:(一拍桌)你那亲家母也来坐着吃!这些年我闺女跟你吃了多少苦?猪油都不知吃过两三回! (众人吃饭,胡屠户喝酒,吃得醉醺醺) (胡屠户摇摇晃晃退场) 【场景二:借钱不成】 (范进走至胡屠户家,敲门) 范进:(小心翼翼)岳父,我想进乡试……没银子盘缠…… 胡屠户:(怒骂)癞蛤蟆想吃天鹅肉!你以为中个相公就真是你文章好?是宗师瞧你老可怜赏你的!如今还想中举人?我一天杀一个猪的钱,给你去丢水里?滚! (胡屠户啐他一脸) (范进退场,愁眉不展) 范进:(自言自语)宗师说我火候已到,如何甘心不去? 【场景三:卖鸡途中报喜】 (母亲扶墙出来) 母亲:我已饿得眼花……把那只下蛋母鸡卖了,买几升米来熬粥罢…… 范进:(点头)是,娘。 (抱鸡出门) (报录人骑马进场,锣鼓齐鸣) 报录人:快请范老爷出来,恭喜高中举人! 母亲:(吓得躲进屋)哎哟,啥事啊?……中啦?!哎哟我儿哟! (邻居上场,报录人喧哗要喜钱,邻居飞奔去集市找范进) 【场景四:范进听喜】 (集市) 范进:鸡便宜,三文钱……三文! (邻居跑来) 邻居:范相公,快回家!你中了举人啦! 范进:(摇头)高邻别哄我……今日要救命卖鸡,别误我生意。 (邻居夺鸡掼地,拉他) 【场景五:喜疯】 (范进被拉回家) (报帖高悬,众人簇拥) 范进:(看报帖)捷报贵府老爷范讳高中广东乡试第七名亚元…… (拍手,笑) 范进:(狂喜)噫!好了!我中了! (仰面跌倒,牙关紧咬) 母亲:(慌乱)快灌水! (范进醒来,又狂笑) 范进:(乱跑)哈哈!我中了!我中了! (跑出门,一脚跌进塘中,全身是泥) (众邻居愣住) 众人:这新贵人是喜疯了! 【场景六:“妙计救疯”】 母亲:(哭)中了一个举人,就疯啦!这可如何是好…… 邻居甲:莫急,我有法子!他最怕谁?找他怕的人来吓他,说“你没中”就好了! 邻居乙:他最怕胡老爹! (众人鼓掌) 【场景七:胡屠户救疯】 (胡屠户提肉登场) 胡屠户:(兴高采烈)我那女婿中啦?我特来贺喜! 母亲:(大哭)他疯啦…… 胡屠户:(怒)让我来! ...
焦虑的夜。
我很焦虑。 看着一些小学生、初一的同学已经能做出比我还难的算法题,心里忍不住泛起一种深深的失落感。回头看看这几年走过的编程之路,满是绕远与反复——一直在努力,却始终觉得偏离了方向。 四年后就是高考,山东的竞争压力之大不言而喻。而我的成绩,却一次比一次差。无论是文化课还是编程,我都感到自己在一点点落后,仿佛看不清前方的路。 更让我无助的是,无论是在学习还是编程上,我似乎都没有一个真正的引路人。没有人告诉我该怎么学,往哪走;没有人指出我做错了什么,也没有人告诉我哪一步其实并不算失败。 于是我开始反复回顾自己的选择,怀疑自己是不是不够聪明、不够勤奋、甚至不够幸运。那些比我小的孩子,那些更早接触、更早起步的人,就像一道道亮眼的光,而我站在阴影中,被照得无处遁形。 我时常觉得,自己就像站在一条奔流不息的河边,看着别人奋力向前,而我却困在原地,寸步难行。不是不想追赶,而是脚下的土地似乎随时都可能塌陷,我根本不敢迈出下一步。 但夜深人静的时候,我也会逼自己冷静地想一想:我到底是在害怕落后,还是害怕自己根本无法赶上?我是真的走错了路,还是只是还没走到成果显现的那一步? 焦虑也许是成长的副产品。它提醒我:我在意,我不甘心,我还没放弃。 我不知道未来会变成什么样,也不知道自己还能坚持多久。但至少现在,我还想试一试——哪怕没人指引,我也想摸索出自己的路。 谁知道呢,也许某一天,当我再次回头望向此刻的自己,会想说一句:你已经做得很好了,真的。
【五月月报】 算法、建站、焦虑与成长
看了看网站,已经整整一个月没有更新了,连 SSL 证书都悄悄过期了。这段时间,我到底在忙些什么? 一、刷题进度与学习状态 算法类 最近在洛谷持续刷题,目前累计通过了 112 道题目。 其中: 入门:86 题 普及−:23 题 普及/提高−:3 题(包括第一次 AC 的 P1205) 刷题过程中,《算法竞赛入门经典》的一些题让我抓狂得快要怀疑人生,于是我转向口碑不错的《深入浅出程序设计竞赛》寻求“救赎”。目前刚学到第二部分算法——排序章节,讲得确实比我想象中更清晰易懂。 此外,我还参加了 【LGR-226-Div.4】洛谷入门赛 #35,最终排名 518 名,感觉还能接受,但也暴露了不少薄弱环节。 学业 地生一模,地理校第3,生物第一,总分校第一、县第五。 其他的没什么好说的。 二、技能提升与项目积累 除了算法,我也在慢慢完善一些个人积累: GitHub 整理刷题代码 我在 GitHub 上新建了一个代码库,用来记录我在洛谷刷过的题: 👉 algo_code 仓库 同时也开始打理 GitHub 主页,探索 Markdown 的高级用法: 👉 我的 GitHub 主页 三、建站:从兴趣出发的小尝试 我重新拾起了建站这个兴趣,做了一些看似“离谱”、实则有自我风格的项目: 波奇酱非官方同人页:boochi.fans GitHub 仓库地址:boochi.fans 仓库 同时,我还注册了一堆脑洞清奇的域名: bailan.top boochi.fans 玩原神玩的.xyz → 跳转到学校官网 no.neijuan.fun(来自域名 neijuan.fun) pingyinshigao.icu 这些可能现在还“没用”,但对我来说是一种“试错式探索” —— 在技术与兴趣之间寻找乐趣和平衡。 四、心态波动与自我调整 坦白讲,这段时间我有些焦虑。 看着一些小学、初一的同学在洛谷上做出比我更高难度的题,甚至已经在 CSP-J 拿奖,我不止一次怀疑自己是否起步太晚,是否天赋不够。 但转念一想:别人强,只能说明他们开始得早,而我也在进步。 焦虑说明我在乎,进步说明我没放弃。与其沉溺比较,不如专注成长。只要今天的我强于昨天,那就是值得骄傲的成绩。真正重要的是:走自己的路,走稳、走远。 毕竟凉先辈说过: 五、未来计划与行动方向 接下来,我打算: ...
P5725 【深基4.习8】求三角形
题目描述 模仿例题,打印出不同方向的正方形,然后打印三角形矩阵。中间有个空行。 输入格式 输入矩阵的规模,不超过 $9$。 输出格式 输出矩形和正方形 输入输出样例 #1 输入 #1 4 输出 #1 01020304 05060708 09101112 13141516 01 0203 040506 07080910 题解 #include<iostream> using namespace std; int main() { int n; cin >> n; int cnt = 1; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { if (cnt <= 9) cout << 0 << cnt; else cout << cnt; cnt++; } cout << endl; } cout << endl; int count = 1; for (int a = 1; a <= n; a++) { int space = 0; while (space < 10 - 2 * (a + 1)) { cout << " "; space++; } for (int b = 1; b <= a; b++) { if (count <= 9) cout << 0 << count; else cout << count; count++; } cout << endl; } return 0; } 但是 WA 了 经过 debug,问题出在空格的输出上。 原本计算空格的公式为10 - 2 * (a + 1),应该为(n - a) * 2才对。 ...
第一节课讲义:认识 C++ 输入输出与基本变量类型
课程目标 掌握 cin 和 cout 的基本用法 理解 int、float、char 三种变量的用途 能编写简单的输入输出程序 一、C++ 程序的基本结构 1.1 代码框架 所有 C++ 程序都从 main 函数开始执行: #include <iostream> // 引入输入输出库 using namespace std; // 使用标准命名空间 int main() { // 程序入口 // 你的代码写在这里 return 0; // 程序结束 } #include <iostream>:提供 cin 和 cout 功能。 using namespace std;:避免重复写 std::cout,直接使用 cout。 二、输出内容:cout 的用法 2.1 输出文本与变量 语法:cout << 内容1 << 内容2 << endl; 示例:输出 “Hello, World!” #include <iostream> using namespace std; int main() { cout << "Hello, World!" << endl; // endl 表示换行 return 0; } 练习:输出你的名字 cout << "我的名字是:小蓝" << endl; // 将 "小蓝" 改为你的名字 2.2 输出多个内容 int age = 10; cout << "我今年" << age << "岁!" << endl; // 输出结果:我今年10岁! 三、输入内容:cin 的用法 3.1 基本输入操作 语法:cin >> 变量; 示例:输入年龄并输出 #include <iostream> using namespace std; int main() { int age; // 声明变量 cout << "请输入年龄:"; // 提示用户输入 cin >> age; // 读取输入 cout << "你的年龄是:" << age << "岁!" << endl; return 0; } 3.2 输入不同类型的数据 float height; char initial; cout << "输入身高(米):"; cin >> height; // 输入小数,如 1.75 cout << "输入姓名首字母:"; cin >> initial; // 输入单个字符,如 'A' 四、变量的基本类型 4.1 变量的作用 存储数据:像盒子一样保存程序中需要的数据(如数字、文字)。 4.2 常用变量类型 类型 用途 示例 注意事项 int 存储整数 int age = 15; 不能存储小数 float 存储小数 float pi = 3.14; 精度较低,适合一般计算 char 存储单个字符 char grade = 'A'; 必须用单引号 ' ' 4.3 变量的声明与赋值 int score; // 声明一个整数变量 score = 90; // 赋值 float price = 19.99; // 声明并初始化 char symbol = '$'; 五、综合练习 5.1 任务:输入个人信息并输出 #include <iostream> #include <string> // 必须包含此头文件才能使用 string using namespace std; int main() { int age; float height; cout << "请输入你的年龄:"; cin >> age; cout << "请输入你的身高(米):"; cin >> height; cout << endl << "===== 个人信息 =====" << endl; cout << "年龄:" << age << "岁" << endl; cout << "身高:" << height << "米" << endl; return 0; } 六、常见错误与注意事项 未包含头文件 ...
排列组合
之前做 CSP-J 初赛试题总是不会做排列组合的题,现在就来补坑。 阶乘 n!(读作“n 的阶乘”)表示从1到n的所有整数的乘积,即: n ! = n × ( n − 1 ) × ( n − 2 ) × ⋯ × 2 × 1 并且规定: 0 ! = 1 排列公式 P ( n , k ) = n ! ( n − k ) ! 排列****强调顺序,表示从n个不同元素中取出k个元素并考虑顺序的排列方式总数,即两个排列如果顺序不同就视为不同的情况。 例如: P ( 5 , 3 ) = 5 ! ( 5 − 3 ) ! = 5 ! 2 ! = 5 × 4 × 3 × 2 × 1 2 × 1 = 120 2 = 60 ...
【补】搜索
在这里,汇集了搜索算法,包括线性查找、二分查找等。 线性查找(Linear Search) 代码实现 #include <iostream> using namespace std; int main() { int nums[10]; for (int i = 0; i < 10; i++) { nums[i] = i + 1; // 初始化数组,1~10 } int find; cin >> find; // 线性查找 for (int i = 0; i < 10; i++) { if (nums[i] == find) { cout << i; // 输出找到的索引 return 0; } } cout << "Not found"; // 没找到 } 算法解析 这是最基本的查找算法,也是最简单的一种。 遍历数组 for (int i = 0; i < 10; i++),依次检查 nums[i] 判断是否匹配 if (nums[i] == find),如果找到目标值,就输出索引 i 提前返回 return 0; 避免多余的遍历,提高效率 未找到时输出 “Not found” 遍历结束仍然没找到目标值,则打印 “Not found” 时间复杂度为 O(n),适用于无序数组,或小规模数据 二分查找(Binary Search) 代码实现 #include<iostream> using namespace std; int main() { int nums[10]; for (int i = 0; i <= 9; i++) { nums[i] = i + 1; } int find = 0; // 要查找的元素 int left = 0, right = 9; // 元素下标 int mid = 0; // 元素下标 cin >> find; while (left <= right) { mid = (left + right) / 2; if (nums[mid] > find) { // 要找的元素在中点左边 right = mid - 1; continue; } if (nums[mid] < find) { //要找的元素在中点左边 left = mid + 1; continue; } if (nums[mid] == find) { cout << mid; return 0; } } cout << "Not found"; } 算法解析 初始化 nums 数组被初始化为 {1, 2, 3, …, 10},即 升序排列。 left = 0, right = 9,分别表示搜索范围的 左端 和 右端。 mid = (left + right) / 2,计算当前范围的 中间元素。 查找过程 如果 nums[mid] > find,说明目标在 左半部分,所以更新 right = mid - 1。 如果 nums[mid] < find,说明目标在 右半部分,所以更新 left = mid + 1。 如果 nums[mid] == find,找到目标,输出索引并终止程序。 终止条件 找到目标时,输出其索引并返回。 若 left > right,表示搜索范围为空,目标元素不存在,输出 “Not found”。 时间复杂度 二分查找的时间复杂度是 O(log N),原因是: ...
给朋友的 CS 书单:从入门到放弃(bushi)
最近莫名其妙成了“CS懂王”,每天被问最多的除了“代码跑不通怎么办”,就是“该看什么书”。为了保住人设(和友谊),特此奉上我的私藏书单!声明:所有书都是我亲自读过且成功催眠的,质量有保障! (其实最主要的原因是为了@Susan_2333而写的) 一、新手村装备(看这些不会秃头) 📖《计算机科学概论》 看这本书的目的是对 CS 进行一个简单的了解。但可以当故事书看!很有意思,不用看的太深,厕所读物首选,看到睡着算我输。 📺计算机科学速成课 不可否认的一点是,这不是书。但是,这个系列的视频每集只有10多分钟,从晶体管讲到神经网络,用浅显的语言讲解 CS,非常有趣。我推荐大家先看这个视频,然后再看《计算机科学概论》。 (虽然我只看了前3集就去追番了) 三、Python修仙指南(头发可再生) 📖《Python编程:从入门到实践》 这本书是 Python 的入门书籍,内容非常丰富,适合初学者。这本书的内容比较陡峭,但是,这本书的内容非常实用,能够帮助大家提高编程水平。 看完就能用Python算命!我三年级就开始学了! 📖《笨方法学Python》 这本书我没看过,但是据说很棒(@Susan_2333也这么说)。 说实话,我还是更喜欢学术性强一点的书。 二、C++の试炼(秃头预警) 📖《C++ Primer》 这本书是 C++ 的入门书籍,内容非常丰富,适合初学者。但是,这本书的难度较大,建议有一定编程基础的同学阅读。 C++界的《新华字典》,买前雄心壮志,买后防身利器!建议和编译器拜把子再看。 📖《C++ Primer Plus》 看名字也知道,这本书是 C++ Primer 的补充。这本书的难度较小,适合初学者。并且,这本书内容又多又杂,面面俱到,适合想要具体学习 C++ 的同学。 比楼上那本多了个"Plus",价格也Plus!但确实适合萌新,当年我就是靠它写了第一个"Hello World" Effective C++ 这本书是 C++ 的进阶书籍,内容非常丰富,适合有一定编程基础的同学阅读。这本书的内容比较难,但是,这本书的内容非常实用,能够帮助大家提高编程水平。 More Effective C++ 在 Effective C++ 的基础上进一步补充。 四、算法の奥义(彻底秃头) 🎮《Hello 算法》 这本书不同于其他的所有书籍,这本书一开始是在 Github 上开源的、社区维护的书,这也是我极为推荐这本书的原因。 Github 项目地址 在线网页 📚《算法导论》(CLRS) ...
进制转换
日常生活中我们使用十进制(0-9),但在计算机领域中,二进制(0-1)、八进制(0-7)和十六进制(0-9, A-F)更为常见。进制转换的核心是通过数学运算在不同基数(Base)之间转换数的表示形式。理解这一原理不仅是计算机科学的基础,也是编程、网络通信甚至密码学的必备技能。 为什么学习进制转换? 考试需求 信息学竞赛(如CSP、NOI)中频繁出现进制转换题目。例如,2024年山东CSP-J第一轮测试中便有一道关于二进制与十六进制转换的单选题。 计算机原理基础 计算机硬件基于二进制逻辑运行,而八进制、十六进制常用于简化二进制的表示(如内存地址、机器指令)。 编程实践 编程中常需处理不同进制的数据(如Python的bin()、hex()函数,C/C++的格式化输出)。 实际应用场景 计算机系统:二进制用于硬件设计,十六进制简化调试(如内存地址显示为0x1A3F)。 网络与编码:IPv6地址使用十六进制(如2001:0db8::ff00),ASCII码用十进制或十六进制表示字符。 密码学:大数运算(如RSA密钥)常以十六进制存储。 装逼 进制转换的核心原理 一、进制的基本概念 基数(Base):进制使用的符号数量。 十进制(Base 10):0-9 二进制(Base 2):0-1 十六进制(Base 16):0-9 + A-F(A=10, B=11, …, F=15) 权值(Positional Value) 每一位数字的值由其位置决定,计算公式为: 数值 ...
求和符号∑
1. 数学中的 ∑ ∑ 是数学中的求和符号,用于表示一系列数的累加。它的核心作用是将复杂的加法表达式简化为紧凑的形式。 基本结构 ...
数学专栏总序
当数学渣开始造轮子 “你要写数学专栏?!” ——来自三位好友的夺命连问 澄清一点,这个专栏的数学,是为了计算机科学服务的,而不是为了数学,毕竟我对数学可以说是到了“厌恶”的地步。所以,数学的难度,不会特别高,对于大佬们来说甚至是简单,但会尽量涵盖和 CS 有关的数学知识。 因此,我将题目改为: 为计算机科学而学习的数学知识 作为学校著名的数学渣渣,这个决定确实充满“魔幻现实主义色彩”。但当我第N次被《CLRS》和《CSAPP》中跃动的Σ符号击溃时,终于意识到:计算机科学大厦的裂缝,往往始于数学地基的沉降。 甚至复杂度也看不懂,我都不知道我是怎么学的算法。 本专栏绝非数学系的抽象漫游,而是程序员视角的生存指南: 撕开数学公式的裂口,直击计算机核心算法 毕竟,编写这个专栏的过程,本质上是一个数学渣渣的 debug 日志——那些让我头秃三天的数学路障,都将成为你前进路上的反光警示牌。 (注:本企划存活时长与读者催更力度呈正相关) 特别鸣谢 @Susan_2333 的数学外挂持续在线:他的B站主页(你敢信这只是一个初中生?)
社工初级考试复习资料 & 冲刺计划
声明:本篇文章系AI生成,仅供参考,如有错误,概不负责。 以下是针对 2025年5月25日山东省初级社会工作者考试 的 每日阶段复习计划(3月19日-5月25日,共67天),内容细化到每日任务、重点背诵条目及实操方法,可直接执行: 一、整体阶段划分 基础夯实阶段(3月19日-4月15日,28天):全面覆盖教材知识点 强化突破阶段(4月16日-5月10日,25天):高频考点+真题实战 冲刺提分阶段(5月11日-5月24日,14天):模拟考试+错题复盘 二、基础夯实阶段(3月19日-4月15日) 1. 综合能力(14天) Day 1-3:社会工作基础理论 学习内容: 社会工作的三大功能(治疗、预防、发展)及对应案例(如社区禁毒宣传=预防功能)。 专业伦理冲突处理模板: (1)识别伦理困境(如保密vs生命安全); (2)评估利益相关者(服务对象、家属、机构); (3)选择最小伤害方案(优先保护生命)。 背诵任务:默写伦理原则(保密、尊重、知情同意)并举例说明。 Day 4-7:人类行为与社会环境 学习内容: 埃里克森人生八阶段理论(重点背儿童期、青少年期、老年期): 青少年期(12-18岁):自我同一性 vs 角色混乱。 老年期(65岁以上):自我整合 vs 绝望。 家庭类型对儿童影响:单亲家庭常见心理问题(自卑、安全感缺失)。 实操任务:绘制“儿童发展阶段生理-心理特征对比表”。 Day 8-14:社会工作方法与政策法规 学习内容: 个案工作三大模式对比: 模式 适用场景 核心技巧 心理社会治疗 长期情绪问题 非反思性沟通 危机介入 突发创伤事件 快速评估+即时干预 山东低保政策:申请材料清单(身份证、收入证明、户籍证明)。 2. 实务(14天) Day 15-18:通用流程 学习内容: 接案阶段禁忌: 错误:过度承诺(“保证解决就业问题”); 正确:说明服务范围(“我们会尽力协调资源”)。 预估工具模板: (1)家庭结构图:标注冲突关系(如父子矛盾用虚线+闪电符号); (2)社会生态系统图:圈出可链接资源(社区服务中心、法律援助)。 背诵任务:默写接案会谈的5个核心问题(现状、需求、资源等)。 Day 19-22:儿童与青少年服务 学习内容: 儿童保护强制报告制度: 报告主体:教师、社工、医护人员; 报告时限:发现后24小时内报公安机关。 偏差行为干预策略: 网络成瘾:家庭契约(限制上网时间)+ 替代活动(体育兴趣小组)。 Day 23-28:老年与社区服务 ...
社工初级考试复习大纲
声明:本篇文章系AI生成,仅供参考,如有错误,概不负责。 版本一 以下是为您整理的2025年山东省初级社会工作者考试复习资料大纲,结合最新考试动态和历年重点内容,帮助您高效备考: 一、考试基本信息 报名时间:2025年3月12日9:00—3月24日16:00(已截止) 考试时间:2025年5月24日、25日 考试科目: 社会工作综合能力(初级):客观题,涵盖社会工作理论、方法与伦理等。 社会工作实务(初级):客观题,侧重实务流程与各领域服务技巧。 二、《社会工作综合能力》复习重点 1. 社会工作基础理论 内涵与目标:社会工作的核心功能(支持、预防、发展)、基本原则(如本土化、职业化)。 价值观与伦理:专业伦理内容(保密、尊重)、伦理难题处理原则(生命优先、最小伤害)。 2. 人类行为与社会环境 人生发展阶段:各阶段(儿童、青少年、老年)的生理、心理特征及主要问题。 社会环境构成:家庭、社区、文化等对行为的影响。 3. 社会工作方法 个案工作:心理社会治疗模式、危机介入模式的核心技巧。 小组工作:互动模式与发展模式的实施原则。 社区工作:地区发展、社会策划、社区照顾模式的特点及策略。 4. 政策与法规 重点法规: 社会救助:低保申请流程、医疗救助对象。 劳动权益:劳动合同、工伤保险认定标准。 特殊群体保护:老年人、妇女、未成年人的合法权益。 三、《社会工作实务》复习重点 1. 通用实务流程 接案与预估:接案注意事项、预估目的与步骤。 计划与介入:服务计划制定原则、介入行动分类(直接/间接服务)。 评估与结案:评估方法(过程/结果评估)、结案时服务对象的反应处理。 2. 各领域实务要点 儿童与青少年:需求分析(安全、教育)、服务方法(家庭干预、社区支持)。 老年与残疾人:老年心理支持、残疾人社会融入策略。 社区与家庭:社区资源整合、家庭关系调适技巧。 3. 高频考点 社会救助:最低生活保障的申请条件与流程。 矫正与优抚:矫正对象的心理疏导、优抚安置的资源链接。 四、备考策略与资料推荐 教材与大纲: 参考《社会工作综合能力》《社会工作实务》官方教材,结合2024年考试大纲(与2023年内容基本一致)。 真题与模拟题: 练习《2024年度山东社区工作者复习重点试题》,熟悉客观题答题技巧。 重点笔记: 使用233网校《干货笔记》梳理章节思维导图,强化记忆。 五、注意事项 时间管理:综合能力侧重理论记忆,实务需结合案例分析,建议分配复习时间6:4。 答题规范:客观题填涂需规范,避免因填涂错误失分。 政策更新:关注2025年最新社会救助、劳动法规调整动态。 六、延伸资源 免费题库:233网校提供历年真题解析及高频考点班课程。 政策文件:山东省人事考试中心官网获取最新考务通知。 版本二 以下是针对2025年山东省初级社会工作者考试的 超详细复习大纲,涵盖核心知识点、学习路径及每日计划建议,助您精准掌握考点: 一、考试科目与分值分布 1. 社会工作综合能力(初级) 题型:单选题(60题×1分)+多选题(20题×2分) 分值权重: 社会工作理论(30%) 方法与技术(40%) 政策法规(30%) 2. 社会工作实务(初级) 题型:单选题(60题×1分)+多选题(20题×2分) 分值权重: 通用流程(30%) 各领域实务(50%) 案例分析应用(20%) 二、《社会工作综合能力》逐章细化 第一章 社会工作基础 1.1 社会工作定义与功能 核心概念:社会工作的“助人自助”原则 三大功能:治疗、预防、发展(举例:社区青少年服务中的预防功能) 1.2 价值观与伦理冲突 必背伦理原则:保密性(例外:涉及生命安全时打破保密) 伦理难题处理步骤:识别问题→分析利益相关者→选择最小伤害方案 第二章 人类行为与社会环境 2.1 儿童发展阶段(0-12岁) 关键理论:埃里克森心理社会发展理论(如学龄期“勤奋vs自卑”) 典型问题:校园欺凌的干预策略(结合《未成年人保护法》) 2.2 老年阶段(60岁以上) 生理变化:认知衰退(阿尔茨海默病早期信号) 社会支持网络构建:社区日间照料中心的资源链接 第三章 社会工作方法 3.1 个案工作 心理社会治疗模式: 技巧:直接治疗(非反思性沟通)vs间接治疗(改善环境) 案例:单亲家庭青少年的情绪疏导流程 危机介入模式: 7阶段模型:评估危机→制定即时计划→实施干预 3.2 小组工作 互动模式: 核心:组员平等参与,社工扮演“协调者”角色 实操:设计一次“亲子沟通小组”的破冰活动 第四章 社会政策与法规 4.1 山东省社会救助政策 低保申请流程: 户籍地街道办提交材料(身份证、收入证明) 家庭经济状况核对(最长15个工作日) 公示与审批(公示期7天) 医疗救助对象:特困人员、低保户、低收入家庭(需提供医保结算单) 4.2 《妇女权益保障法》重点 职场性别歧视的界定与维权途径(向劳动监察部门投诉) 三、《社会工作实务》逐章细化 第一章 通用流程 1.1 接案阶段 注意事项: 避免过早承诺(如“一定能解决住房问题”) 紧急情况处理(如家暴受害者需立即启动保护程序) 1.2 预估工具 家庭结构图:符号含义(□男性、○女性、虚线表示关系冲突) 社会生态系统图:标注个人与家庭、社区、政策资源的互动 第二章 儿童与青少年服务 2.1 儿童保护 强制报告制度:教师、社工发现虐待需24小时内报公安机关 服务方案设计: 目标:提升儿童自我保护意识 活动:角色扮演“拒绝陌生人接触” 2.2 青少年偏差行为干预 常见类型:网络成瘾、逃学 介入策略:家庭治疗(改善亲子沟通)+ 学校社工介入(建立朋辈支持小组) 第三章 老年服务 3.1 老年需求评估 身体功能评估工具:ADL量表(评估穿衣、进食等日常能力) 心理支持:老年抑郁量表(PHQ-9)的使用与解读 3.2 社区养老服务 山东地方政策: “幸福食堂”项目申请条件(户籍限制、年龄≥80岁) 居家适老化改造补贴标准(最高3000元/户) 四、每日复习计划(8周冲刺) 第一周:基础理论搭建 Day 1-3:精读《综合能力》第一章,整理思维导图(重点:伦理原则表格对比) Day 4-5:学习《实务》通用流程,完成2套接案阶段案例分析题 第二周:核心方法突破 Day 6-8:掌握个案工作三大模式(心理社会、危机介入、任务中心),每个模式做1道真题 Day 9-10:背诵《社会救助暂行办法》关键条款(结合山东低保案例) 第三周:实务强化 Day 11-13:专项训练儿童/老年领域大题,总结答题模板(问题→需求→介入步骤) Day 14-15:模拟考试(限时完成2024年真题,错题标记) ……(后续每周细化至每日任务) ...
逻辑谬误
班里杠精太多了!像我们这种嘴笨的内向小男生,哪怕讲得再有理,也常常被对方带偏节奏,吵不赢,怎么办? 没关系!今天我们就来学点“逻辑谬误”,让他们无话可说! 什么是逻辑谬误? 不依据逻辑的议论,尤其是指论证中不符合逻辑的推论。逻辑谬误分为形式逻辑谬误与非形式逻辑谬误。非形式逻辑谬误,实质上就是前提错误谬误。 逻辑谬误的类型 以下是针对形式逻辑谬误与非形式逻辑谬误的分类详解,包含定义、示例及反驳方法: 一、形式逻辑谬误 形式逻辑谬误是因推理结构错误导致的无效论证,常见于演绎推理(如三段论、假言推理等)。其核心问题在于逻辑形式不成立。 1. 否定前件谬误(Denying the Antecedent) 定义:在假言命题中,错误地通过否定前件推出否定后件。 逻辑形式:若 P ➛ Q ,则非 P ➛ 非 Q。 示例: 前提:“如果下雨(P),地面会湿(Q)。” 错误推理:“今天没下雨(非 P),所以地面不湿(非 Q)。” 反驳: 指出结构漏洞:“即使不下雨,地面也可能因洒水车或水管漏水而湿。” 2. 肯定后件谬误(Affirming the Consequent) 定义:在假言命题中,错误地通过肯定后件推出肯定前件。 逻辑形式:若 P ➛ Q ,则 Q ➛ P。 示例: 前提:“如果一个人中毒(P),他会呕吐(Q)。” 错误推理:“他呕吐了(Q),所以他中毒了(P)。” 反驳: 列举其他可能性:“呕吐可能由食物过敏、晕车或怀孕引起,未必是中毒。” 3. 假两难推理(False Dilemma) 定义:将复杂问题简化为非此即彼的二元选择,忽略中间选项。 示例: “要么完全禁止社交媒体,要么放任虚假信息泛滥!” 反驳: 提出中间方案:“可以加强内容审核算法或提升用户媒介素养,而非极端选择。” 二、非形式逻辑谬误 非形式逻辑谬误是因论证内容或语境缺陷导致的错误,涉及语义模糊、证据不足或情感操控等。 1. 诉诸无知(Appeal to Ignorance) 定义:以“无法证伪”作为“为真”的依据(或反之)。 示例: “科学无法解释意识起源,所以灵魂一定存在!” 反驳: 明确举证责任:“科学未解释 ≠ 你的假设成立。需提供灵魂存在的直接证据。” 2. 循环论证(Circular Reasoning) 定义:结论被隐含在前提中,实质是同义重复。 示例: ...
P1089 津津的储蓄计划 [NOIP 2004 提高组]
题目 题目描述 津津的零花钱一直都是自己管理。每个月的月初妈妈给津津 $300$ 元钱,津津会预算这个月的花销,并且总能做到实际花销和预算的相同。 为了让津津学习如何储蓄,妈妈提出,津津可以随时把整百的钱存在她那里,到了年末她会加上 $20%$ 还给津津。因此津津制定了一个储蓄计划:每个月的月初,在得到妈妈给的零花钱后,如果她预计到这个月的月末手中还会有多于 $100$ 元或恰好 $100$ 元,她就会把整百的钱存在妈妈那里,剩余的钱留在自己手中。 例如 $11$月初津津手中还有 $83$ 元,妈妈给了津津 $300$ 元。津津预计$11$月的花销是 $180$ 元,那么她就会在妈妈那里存 $200$ 元,自己留下 $183$ 元。到了 $11$ 月月末,津津手中会剩下 $3$ 元钱。 津津发现这个储蓄计划的主要风险是,存在妈妈那里的钱在年末之前不能取出。有可能在某个月的月初,津津手中的钱加上这个月妈妈给的钱,不够这个月的原定预算。如果出现这种情况,津津将不得不在这个月省吃俭用,压缩预算。 现在请你根据 $2004$ 年 $1$ 月到 $12$ 月每个月津津的预算,判断会不会出现这种情况。如果不会,计算到 $2004$ 年年末,妈妈将津津平常存的钱加上 $20%$ 还给津津之后,津津手中会有多少钱。 输入格式 $12$ 行数据,每行包含一个小于 $350$ 的非负整数,分别表示 $1$ 月到 $12$ 月津津的预算。 输出格式 一个整数。如果储蓄计划实施过程中出现某个月钱不够用的情况,输出 $-X$,$X$ 表示出现这种情况的第一个月;否则输出到 $2004$ 年年末津津手中会有多少钱。 注意,洛谷不需要进行文件输入输出,而是标准输入输出。 输入输出样例 #1 输入 #1 290 230 280 200 300 170 340 50 90 80 200 60 输出 #1 -7 输入输出样例 #2 输入 #2 290 230 280 200 300 170 330 50 90 80 200 60 输出 #2 1580 分析 我们可以直接套模拟,模拟每个月的操作即可。 ...
P2669 金币 [NOIP 2015 普及组]
题目 题目背景 NOIP2015 普及组 T1 题目描述 国王将金币作为工资,发放给忠诚的骑士。第一天,骑士收到一枚金币;之后两天(第二天和第三天),每天收到两枚金币;之后三天(第四、五、六天),每天收到三枚金币;之后四天(第七、八、九、十天),每天收到四枚金币……;这种工资发放模式会一直这样延续下去:当连续 $n$ 天每天收到 $n$ 枚金币后,骑士会在之后的连续 $n+1$ 天里,每天收到 $n+1$ 枚金币。 请计算在前 $k$ 天里,骑士一共获得了多少金币。 输入格式 一个正整数 $k$,表示发放金币的天数。 输出格式 一个正整数,即骑士收到的金币数。 输入输出样例 #1 输入 #1 6 输出 #1 14 输入输出样例 #2 输入 #2 1000 输出 #2 29820 说明/提示 【样例 1 说明】 骑士第一天收到一枚金币;第二天和第三天,每天收到两枚金币;第四、五、六天,每天收到三枚金币。因此一共收到 $1+2+2+3+3+3=14$ 枚金币。 对于 $100%$ 的数据,$1\le k\le 10^4$。 分析 我们可以采用 按层计算 的方法,在脑海里想象,每一天发的金币数可以列成以下表格: 也就是说: $ 每一层发的金币数 = 层数$ $ i = c $ 由此,我们写出程序: #include<iostream> using namespace std; int main() { int day = 0, glod = 0, tday = 0; cin >> day; for (int c = 1; c <= day; c++) { for (int i = 1; i <= c; i++) { glod += c; tday ++; if (tday == day) { break; } } if (tday == day) { break; } } cout << glod; return 0; } 完美通过! ...
开灯问题
题目 题目描述 有n盏灯,编号为1~n。第1个人把所有灯打开,第2个人按下所有编号为2的倍数的开关(这些灯将被关掉),第3个人按下所有编号为3的倍数的开关(其中关掉的灯将被打开,开着的灯将被关闭),依此类推。一共有k个人,问最后有哪些灯开着?输入n和k,输出开着的灯的编号。k≤n≤1000。 样例输入: 7 3 样例输出: 1 5 6 7 解答 #include<iostream> using namespace std; int main() { /* 1:开 0:关 */ int n = 0, k = 0; cin >> n >> k; const int MAX = n; int a[MAX]; for (int z = 0; z <= n - 1; z++) { //生成一个全是1的列表 a[z] = 1; } for (int j = 0; j < n; j++) { for (int i = 1; i <= k; i++) { if (j % i == 0) { if (a[j] == 0) { a[j] = 1; } if (a[j] == 1) { a[j] = 0; } } } if (a[j] == 1) { cout << j << " "; } } return 0; } 这个程序当然不能运行,它存在以下问题: 数组 a[MAX] 未正确初始化,可以改用vector。 a 数组下标从 0 开始,但灯的编号从 1 开始,需要修正数组访问方式。 状态翻转逻辑错误,在翻转灯的状态时,不需要额外判断 a[j] == 0 或 a[j] == 1,直接 a[j] = !a[j]; 即可。 ...
纠错日记
这几天忙着配置网站,总结了一下 debug 过程中遇到的问题和排查流程: 检查权限:确保权限设置为 775。 确认 Node.js 版本:确保版本匹配,避免兼容性问题。 清理浏览器缓存:防止缓存导致的页面异常。 检查域名部署:确保域名已正确解析并部署到服务器上。 每一步看似简单,但往往就是这些小细节决定了最终能否顺利运行。
C++入门:浮点数 & 字符型
为什么0.1+0.2≠0.3?为什么’A’和65竟是孪生兄弟?准备好揭开编程世界最狡诈的伪装者真面目了吗?让我们直击浮点数与字符型的灵魂深处! 引言:当计算机遇上连续世界 浮点数的奇幻漂流 想象用乐高积木拼出圆周率——这就是浮点数的本质!它们用有限精度逼近无限可能,就像用火柴棒拼出蒙娜丽莎的微笑。 float pi = 3.14159; // 在内存中其实是314159×10⁻⁵的二进制版本 字符的七十二变 每个字符都是穿着ASCII外衣的整型间谍: char c = 'A'; // 表面是字母 int secret = c; // 暴露真身:65 一、浮点数的量子世界 1.1 浮点三巨头对比 类型 内存空间 有效数字 典型范围 适用场景 float 4字节 6-7位 ±1.18×10⁻³⁸ ~ ±3.4×10³⁸ 图形坐标 double 8字节 15-16位 ±2.23×10⁻³⁰⁸ ~ ±1.79×10³⁰⁸ 科学计算 long double 16字节 18-19位 ±3.36×10⁻⁴⁹³² ~ ±1.18×10⁴⁹³² 高精度金融 内存结构解密(IEEE 754标准): 符号位 [1] | 指数位 [8/11] | 尾数位 [23/52] 就像科学计数法的二进制版:(-1)^s × 1.m × 2^(e-127) 1.2 浮点数的七大罪 精度丢失案发现场: float a = 0.1f; double b = 0.2; cout << a + b; // 输出0.30000000000000004(不是笔误!) 比较浮点数的正确姿势: bool isEqual(double x, double y) { return fabs(x - y) < 1e-6; // 设置误差容忍度 } 特殊值禁区: ...
C++入门:简单变量 & 整型
开篇寄语:为什么你需要这篇指南? 最近听到不少同学的抱怨:“C++的数据类型怎么这么难?““变量和整型总是分不清怎么办?” 看着大家被各种int、short、unsigned绕得团团转,我决定用最接地气的方式,把这块硬骨头啃碎了喂给你们。相信我,学完这篇,你会拍着大腿说:“原来数据类型还能这么理解!” 引言:从"变量盒子"到数据存储哲学 为什么程序员总在讨论数据类型? 就像快递员要知道包裹是易碎品还是普通货物,程序需要明确数据是整数还是字符。C++的变量系统,本质上是一套精密的"内存货架管理系统”——给每个数据贴上类型标签,分配合适大小的存储空间。 int num = 5; // 给4字节的"货架"贴上"num"标签,存入数字5 一、变量系统全解析(破解初学者三大困惑) 1.1 变量的本质:内存空间的命名艺术 新手常见误区:“声明变量就是创建数据?” 实际上: int num; → 申请4字节内存(32位系统) num = 5; → 在地址0x7ffe…写入00000101 从此"num"成为该地址的永久门牌号 💡 变量三要素记忆口诀: 哪里存(地址)→ 存什么(值)→ 怎么存(类型) 1.2 变量命名规范:代码可读性的第一道防线 血泪教训案例: int a1 = 10; // 烂命名:半年后鬼知道a1是什么 int nStudentCount = 10; // 好命名:一眼看懂用途 命名进阶技巧: // 类型前缀法(匈牙利命名法) char szName[20]; // sz: 以零结尾的字符串 float fPrice; // f: 浮点型 bool bIsValid; // b: 布尔型 // 骆驼命名法 int studentCount; double totalAmount; 二、整型数据类型深度剖析 2.1 整型家族图谱:五兄弟对比 类型 内存空间 数值范围(典型值) 适用场景 char 1字节 -128127 或 0255 ASCII字符/微小整数 short 2字节 -32,768~32,767 节省内存的小数值 int 4字节 -2.1亿~2.1亿 通用整数存储 long 4/8字节 同int或更大 历史遗留系统 long long 8字节 -9×10¹⁸~9×10¹⁸ 天文数字计算 2.2 有符号与无符号的量子世界 二进制视角解密: ...
P1011 车站 [NOIP 1998 提高组]
题目描述 火车从始发站(称为第 1 站)开出,在始发站上车的人数为 a,然后到达第 2 站,在第 2 站有人上、下车,但上、下车的人数相同,因此在第 2 站开出时(即在到达第 3 站之前)车上的人数保持为 a 人。从第 3 站起(包括第 3 站)上、下车的人数有一定规律:上车的人数都是前两站上车人数之和,而下车人数等于上一站上车人数,一直到终点站的前一站(第 n−1 站),都满足此规律。现给出的条件是:共有 n 个车站,始发站上车的人数为 a,最后一站下车的人数是 m(全部下车)。试问 x 站开出时车上的人数是多少? 输入格式 输入只有一行四个整数,分别表示始发站上车人数 a,车站数 n,终点站下车人数 m 和所求的站点编号 x。 输出格式 输出一行一个整数表示答案:从 x 站开出时车上的人数。 输入输出样例 #1 输入 #1 5 7 32 4 输出 13 说明/提示 对于全部的测试点,保证 1≤a≤20,1≤x≤n≤20,1≤m≤2×104。 问题分析 + 求解 已知信息: 发站上车人数 a 车站数 n 终点站人数 m 所求的站点编号 x 我们定义 i:表示第二站上车、下车为 i 人 根据已知信息,我们可以列出表格: 站数(x) 上车人数 下车人数 发车时的人数 1 a / a 2 i i a 3 a+i i 2a+i 4 a+2i a+i 2a+i 5 2a+3i a+2i 3a+2i 我们可以找到规律: ...
参赛作品:算法与数据可视化工具集
说明 1. 累加计算器与可视化程序 功能描述: 该程序实现了一个简单的累加计算器,用户可以输入一个最小值和一个最大值,程序会计算从最小值到最大值的累加和并可视化累加过程。程序通过条形图展示每步累加的过程,实时显示累加结果。 主要流程: 用户输入最小值和最大值。 程序判断输入是否有效(最小值小于最大值)。 从最小值到最大值进行累加,并实时更新累加结果。 通过条形图可视化每一步的累加过程,展示当前最小值和当前累加和。 计算完成后,通过弹窗显示最终的累加结果。 使用说明: 在文本框中输入最小值和最大值。 点击“计算并可视化”按钮,程序会计算并显示累加结果。 程序会弹出对话框显示累加结果,并展示累加过程的条形图。 代码注释: entry_min 和 entry_max 是用户输入最小值和最大值的文本框。 plt.bar() 用于绘制条形图,显示累加过程。 messagebox.showinfo() 和 messagebox.showerror() 用于弹窗显示信息。 2. 选择排序与可视化程序 功能描述: 该程序实现了选择排序算法,并通过图形化界面展示每一步的排序过程。用户可以看到选择排序如何通过不断选择最小值并交换位置,逐步将数组排序完成。 主要流程: 随机生成一个包含 50 个元素的数组。 使用选择排序算法对数组进行排序,实时更新数组状态。 每次交换时,通过条形图展示当前数组状态,突出显示当前最小值、遍历元素以及已排序部分。 排序完成后,通过可视化展示排序结果。 使用说明: 程序会自动生成一个随机数组,并进行选择排序。 排序过程中会实时绘制条形图,显示每一步的排序情况。 排序完成后,会显示最终的排序结果。 代码注释: plt.bar() 用于绘制条形图,显示数组的排序过程。 plt.clf() 用于清除之前的绘图,准备更新图表。 plt.pause() 用于控制动画的更新速度,使排序过程可视化。 3. 插入排序与可视化程序 功能描述: 该程序实现了插入排序算法,并通过图形化界面展示每一步的排序过程。用户可以看到插入排序如何通过逐个插入元素到已排序部分,逐步将数组排序完成。 主要流程: 随机生成一个包含 50 个元素的数组。 使用插入排序算法对数组进行排序,实时更新数组状态。 每次插入元素时,通过条形图展示当前数组状态,突出显示当前插入元素及已排序部分。 排序完成后,通过可视化展示排序结果。 使用说明: 程序会自动生成一个随机数组,并进行插入排序。 排序过程中会实时绘制条形图,显示每一步的排序情况。 排序完成后,会显示最终的排序结果。 代码注释: plt.bar() 用于绘制条形图,显示数组的排序过程。 plt.clf() 用于清除之前的绘图,准备更新图表。 plt.pause() 用于控制动画的更新速度,使排序过程可视化。 4. 累加计算器(带最小值和最大值输入) 功能描述: ...
P1421 小玉买文具
题目 题目描述 班主任给小玉一个任务,到文具店里买尽量多的签字笔。已知一只签字笔的价格是 1 元 9 角,而班主任给小玉的钱是 a 元 b 角,小玉想知道,她最多能买多少只签字笔呢。 输入格式 输入只有一行两个整数,分别表示 a 和 b。 输出格式 输出一行一个整数,表示小玉最多能买多少只签字笔。 输入输出样例 输入 10 3 输出 5 说明/提示 数据规模与约定 对于全部的测试点,保证 0 ≤ a ≤ 10^4,0 ≤ b ≤ 9。 问题分析 无须分析。 解题 #include <iostream> using namespace std; int main() { double DanJia = 1.9; int a = 0, b = 0; cin >> a >> b; double GiveMoney = a + 0.1 * b; int GeShu = GiveMoney / DanJia; cout << GeShu; } AC,完美通过! ...
P5711 【深基3.例3】闰年判断
题目 题目描述 输入一个年份,判断这一年是否是闰年,如果是输出 1,否则输出 0。 1582 年以来,闰年的定义: 普通闰年:公历年份是 4 的倍数,且不是 100 的倍数的,为闰年(如 2004 年、2020 年等就是闰年)。 世纪闰年:公历年份是整百数的,必须是 400 的倍数才是闰年(如 1900 年不是闰年,2000 年是闰年)。 输入格式 输入一个正整数 n,表示年份。 输出格式 输出一行。如果输入的年份是闰年则输出 1,否则输出 0。 输入输出样例 输入输出样例 #1 输入 #1 1926 输出 #1 0 输入输出样例 #2 输入 #2 1900 输出 #2 0 输入输出样例 #3 输入 #3 2000 输出 #3 1 输入输出样例 #4 输入 #4 1996 输出 #4 1 说明/提示 数据保证,1582 ≤ n ≤ 2020 且年份为自然数。 解题 #include <iostream> using namespace std; int main() { int year; cin >> year; if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) { cout << "yes"; return 0; } else { cout << "no"; return 0; } } 完美通过! ...
T392143 水仙花数
题目描述 在自然数中,如果一个三位数等于自身各位数字之立方和,则这个三位数就称为是水仙花数。如:153=1+125+27,所以153是一个水仙花数。求所有的水仙花数。 输入格式 无输入 输出格式 若干个空格间隔的由小到大表示的整数,每个表示一个水仙花数。 解题 是不是很熟悉?这道题就是《算法竞赛入门经典》的习题 2-1,改一个输出就行。 #include<iostream> using namespace std; int main() { int a,b,c = 0; for (int num = 100; num <= 999; num++) { a = num / 100; b = (num / 10) % 10; c = num % 10; if (num == (a * a * a) + (b * b * b) + (c * c * c)) { cout << num << " "; } } } 完美通过! 本篇题解到此结束,祝各位读者早日成为神牛牪犇!
算法竞赛入门经典 第二章习题解答
习题 2-1 水仙花数(daffodil) 题目描述 输出 100~999 中的所有水仙花数。若 3 位数 ABC 满足 [ ABC = A^3 + B^3 + C^3 ] 则称其为水仙花数。例如 153= (1^3+5^3+3^3) ,所以 153 是水仙花数。 解答 #include<iostream> using namespace std; int main() { int a, b, c = 0; for (int num = 100; num <= 999; num++) { a = num / 100; b = (num / 10) % 10; c = num % 10; if (num == (a * a * a) + (b * b * b) + (c * c * c)) { cout << num << endl; } } } 没什么可说的。 习题 2-2 韩信点兵(hanxin) 题目描述 相传韩信才智过人,从不直接清点自己军队的人数,只要让士兵先后以三人一排、五人一排、七人一排地变换队形,而他每次只掠一眼队伍的排尾就知道总人数了。 输入包含多组数据,每组数据包含 3 个非负整数 a, b, c,表示每种队形排尾的人数(a < 3, b < 5, c < 7),输出总人数的最小值(或报告无解)。已知总人数不小于 10,不超过 100。输入到文件结束为止。 样例输入 2 1 6 2 1 3 样例输出 Case 1: 41 Case 2: No answer 解答 初版(有 bug) ...
算法入门经典 习题 2-3
题目 输入正整数 n≤20,输出一个 n 层的倒三角形。 例如,n=5 时输出如下: ######### ####### ##### ### # 解答 我们来分析一下: 行号 空格数 符号数 输出内容 0 0 9 ######### 1 1 7 ####### 2 2 5 ##### 3 3 3 ### 4 4 1 # 初版(有 bug) #include<iostream> using namespace std; int triangle(int a) { //a:层数 a = a * 2 - 1; for (int i = 0; i <= a; i = i + 2) { //i:每行个数 int b = 0; //添加空格 int j = 1; while(j <= i) { cout << " "; j++; } while(b <= i) { //b:每行输出次数 cout << "#"; b++; } cout <<endl; } return 0; } int main() { int n; cin >> n; triangle(n); } 输入: ...
算法入门经典 例题 2-4
题目 阶乘之和:输入 n,计算 S=1!+2!+3!+…+n!的末 6 位(不含前导 0)。n≤106 ,n!表示前 n 个正整数之积。 样例输入: 10 样例输出: 37913 解答 这里应该用双层 for 循环,对于每个 i,乘每一个 j(如程序)。 初版(有 bug) #include <iostream> using namespace std; int main() { int n; int sum = 0; cin >> n; for (int i; i <= n; i++) { int a = 1; for (int j; j <= i; j++) { a = i * j; sum = sum + a; } } sum = sum % 1000000; cout << sum; return 0; } 欸?输出是 0? 经过 debug 发现,未初始化循环变量,我在使用循环变量 i 和 j 时没有初始化。 改正版(有 bug) #include <iostream> using namespace std; int main() { int n; int sum = 0; cin >> n; for (int i = 1; i <= n; i++) { int a = 1; for (int j = 1; j <= i; j++) { a = i * j; sum = sum + a; } } sum = sum % 1000000; cout << sum; return 0; } 令人费解的是,程序仍然有 bug。 ...
杂谈 NOI 路线
刷知乎无意间刷到问题如何看待《算法竞赛进阶指南》与《信息学奥赛一本通·提高篇》多页内容雷同,后者疑似抄袭?中,李煜东大佬推荐的学习流程竟然惊人的一致为了能帮助广大和我一样的苦命 OIer,特地转载一下: OI / ICPC 入门到提高的话…… 我的建议是 买一本《C++ Primer Plus》(中文版就行),看前几章学语言(不用看面向对象之后的内容)。 买一本《算法竞赛入门经典》,学入门级别算法,上面也有一些语言的内容,所以 C++ Primer Plus 粗略地读就行了。 买一本《算法竞赛进阶指南》,提高算法和数据结构水平。 UPD:还有评论推荐《挑战程序设计竞赛》,不过我没读过…… 看作者应该还不错 之后就不用看书了,刷 OJ / 读论文 / 做 CF 等 Online Contest 应该都不是难事。 附一个回复: Ircon:请问对于您提到的那些书里面的例题,应该抱着什么态度去刷。是尽量自己做出。还是模仿例题代码写一遍后,搞明白原理,然后去刷习题? 李煜东:可以自己先简单思考一下,然后搞明白怎么做,最后独立写代码实现。不会的话可以学习例题的解法,代码尽量不要模仿,除非看完解法还是不懂…… 版权声明: 本文转载自知乎,“如何看待《算法竞赛进阶指南》与《信息学奥赛一本通·提高篇》多页内容雷同,后者疑似抄袭?”,https://www.zhihu.com/question/292823177/answer/482747918。版权归原作者所有,转载目的仅为分享知识与经验。如有侵权,请联系删除。
算法入门经典 例题 2-2
题目 猜想:对于任意大于1的自然数n,若n为奇数,则将n变为3n+1,否则变为n的一半。 经过若干次这样的变换,一定会使n变为1。例如,3→10→5→16→8→4→2→1。 解答 很简单的重复性程序,没什么技术含量。 #include <iostream> using namespace std; int main() { int n; cin >> n; int j = 0; while (n > 1) { if (n % 2 == 1) { j++; n = 3 * n + 1; continue; } else { j++; n = n / 2; continue; } } cout << j; return 0; } 但是,为了防止数据溢出,我们可以把变量改为 long。 #include <iostream> using namespace std; int main() { long n; cin >> n; int j = 0; while (n > 1) { if (n % 2 == 1) { j++; n = 3 * n + 1; continue; } else { j++; n = n / 2; continue; } } cout << j; return 0; } 祝各位读者早日成为神牛牪犇!
算法入门经典 例题 2-1
题目 输出所有形如 aabb 的 4 位完全平方数(即前两位数字相等,后两位数字也相等)。 解答 这个题目乍一看,有两种思路: 列举所有完全平方数,再找其中形如 aabb 的。 列举所有形如 aabb 的数,再找其中的完全平方数。 经过我的抉择,我选择了第一种思路 (绝对不是因为我不会判断一个数是否为完全平方数) 解答 #include<iostream> using namespace std; int main() { for (int i = 1; ; i++) { int allnum = i * i; if (allnum > 9999) { break; } int a1 = allnum / 1000; int a2 = allnum / 100 - a1 * 10; int b1 = allnum / 10 - a1 * 100 - a2 * 10; int b2 = allnum / 1 - a1 * 1000 - a2 * 100 - b1 * 10; if (a1 == a2 && b1 == b2) { cout << allnum << endl; } } return 0; } 程序没有问题,但是判断是否为 aabb 的数的过程未免太不优雅了! 所以,我给出了版本 2: #include<iostream> using namespace std; int main() { for (int i = 1; ; i++) { int allnum = i * i; if (allnum > 9999) { break; } int a1 = allnum / 1000; int a2 = (allnum / 100) % 10; int b1 = (allnum / 10) % 10; int b2 = allnum % 10; if (a1 == a2 && b1 == b2) { cout << allnum << endl; } } return 0; } 这样感觉也挺好。 ...
算法竞赛入门经典 第一章习题解答
习题 1-1 平均数(average) 题目描述 输入3个整数,输出它们的平均值,保留3位小数。 解答 #include <iostream> using namespace std; float average(float a,float b,float c) { float sum,aver; sum = a + b + c; aver = sum / 3; return aver; } int main() { float a,b,c,ans; cin >> a >> b >> c; ans = average(a,b,c); cout << ans; return 0; } 太过于基础,不过多描述。 习题1-2 温度(temperature) 题目描述 输入华氏温度f,输出对应的摄氏温度c,保留3位小数。提示:c=5(f-32)/9。 解答 #include <iostream> using namespace std; int main() { int f,c; cin >> f; float c = 5.0 * (f - 32) / 9; cout << c; return 0; } 也是相当简单的。 习题1-3 连续和(sum) 题目描述 输入正整数n,输出1+2+…+n的值。提示:目标是解决问题,而不是练习编程。 解答 终于是上难度了。 #include <iostream> using namespace std; int sum(int EndNumber) { int sum = 0; for (int i = 0;i <= EndNumber;i++) { sum = sum + i; } return sum; } int main() { int EndNumber,ans; cin >> EndNumber; ans = sum(EndNumber); cout << ans; } 这个题也可以用 等差数列求和公式 来解决。 ...
算法入门经典 例题 1-3
算法是思想的体操,竞赛是智慧的碰撞。 题目 输入两个整数 a 和 b,交换二者的值,然后输出。 解答 这一个例题甚至比上一个简单,解法直接使用经典的“三变量法”就行了。 解答 #include <iostream> using namespace std; int main() { int a,n,m; cin >> n >> m; a = n; n = m; m = a; cout << n << " " << m; } 过! 祝各位读者早日成为神牛牪犇!
算法入门经典 例题 1-4(鸡兔同笼)
题目 鸡和兔总数量为 n,总腿数为 m。输入 n 和 m,依次输出鸡的数目和兔的数目。若无解,那么输出 No answer。 解答 这里开始上难度,但是鸡兔同笼是小学学的。。。 定义变量 j、t,分别表示鸡的数量、兔子的数量。 先来写出两个关系式: j + t = n 2j + 4t = m 代入消元 t = (m-2n)/2 所以 j = n – t 并且,我们也要考虑,输入的 m、n 必须为正整数。 那么,我们可以写出以下代码: #include <iostream> using namespace std; int main() { /* n:总数量 m:总腿数 j:鸡数量 t:兔数量 */ int m,n,j,t; cin >> n >> m; t = (m - 2 * n) / 2; j = n - t; if (m % 2 != 0 || m < 2 * n || m > 4 * n) { cout << "No answer"; } else { cout << j << " " << t; } return 0; } 整体难度也不高。 ...
算法入门经典 例题 1-1
好的,从今天开始,我将学习刘汝佳老师的《算法竞赛入门经典》,以便冲刺今年九月份的 CSP-J。 题目 输入底面半径 r 和高 h,输出圆柱体的表面积,保留3位小数。 样例输入: 3.5 9 样例输出: Area = 274.889 解答 由于题目过于简单,上过小学的人都会逻辑,所以没有分析。 初版解答 #include <iostream> using namespace std; float area(r,h) { int s; s = 2 * pi * r ** 2 + 2 * pi * r * h; return s; } int main() { int r,h,a; cin >> r >> h; a = area(r,h); cout << "Area = " << a; return 0; } 大意了,这个程序存在以下问题: 参数类型缺失 float area(r,h) 未声明参数类型。 未定义常量 π C++ 标准库中没有预定义的 pi。 错误的幂运算符 C++ 不支持 ** 运算符。 变量类型不匹配 公式优化 这个故事告诉我们: 不要以为语言入门之后就能轻易地写出算法程序。 ——《算法竞赛入门经典》前言 这也是我以前存在的问题。 修改解答 #include <iostream> using namespace std; float area(float r,float h) { float s,pi; pi = 3.1415926; s = 2 * pi * r * r + 2 * pi * r * h; return s; } int main() { float r,h,a; cin >> r >> h; a = area(r,h); cout << "Area = " << a; return 0; } 完美通过 ...
算法入门经典 例题 1-2
题目 输入一个三位数,分离出它的百位、十位和个位,反转后输出。 解答 其实题目也很简单,难点在于如何分离出它百位、十位和个位。 百位 = n/100 十位 = n/10%10 个位 = n%10 解答 #include <iostream> using namespace std; int exchange(int n) { int hundred,ten,one,a; hundred = n / 100; ten = n / 10 % 10; one = n % 10; a = one * 100 + ten * 10 + hundred; return a; } int main() { int n,ans; cin >> n; ans = exchange(n); cout << ans; return 0; } 这一次也是认真多了,一遍过。 祝各位读者早日成为神牛牪犇!
STL
STL(Standard Template Library,标准模板库)是 C++ 标准库的一部分,提供了一组通用的、可重用的模板类和算法,用于处理常见的数据结构和操作。STL 通过提供高效、抽象和灵活的代码,使开发者能够更快速地实现常见的数据操作,而无需从头开始编写底层实现。 STL 的核心包括三部分: 容器(Containers):用于存储和管理数据的对象。 算法(Algorithms):用于操作容器数据的函数。 迭代器(Iterators):用于遍历容器的对象,类似于指针。 函数对象(Function Objects):即可调用的对象,通常与算法结合使用。 STL 的主要组成部分: 1. 容器(Containers) 容器是用于存储数据的对象,它们通过提供不同的结构(如数组、链表、哈希表等)来管理数据。STL 提供了多种容器,主要分为以下几类: 顺序容器(Sequence Containers): 这些容器按顺序存储元素,元素的位置由其在容器中的位置决定。 常见的顺序容器包括: vector:动态数组,支持快速随机访问和尾部插入/删除。 deque:双端队列,支持在两端进行高效的插入和删除。 list:双向链表,支持高效的在两端进行插入和删除,但不支持快速随机访问。 array:固定大小的数组,大小在编译时确定,提供常数时间的元素访问。 关联容器(Associative Containers): 这些容器根据元素的键值对存储元素,并支持高效的键查找。 常见的关联容器包括: set:集合,不允许重复元素,自动排序。 map:映射,存储键值对(key-value),键不重复,自动排序。 multiset:多重集合,允许重复元素,自动排序。 multimap:多重映射,允许键重复,自动排序。 无序容器(Unordered Containers): 这些容器基于哈希表实现,提供常数时间的查找操作,但元素没有顺序。 常见的无序容器包括: unordered_set:无序集合,基于哈希表存储元素。 unordered_map:无序映射,基于哈希表存储键值对。 2. 算法(Algorithms) STL 提供了大量的算法,涵盖了排序、查找、修改等常见操作。STL 算法是泛型的,即它们可以与任何符合要求的容器配合使用。常见的算法包括: 排序算法:sort、stable_sort、partial_sort 等。 查找算法:find、binary_search、lower_bound、upper_bound 等。 修改算法:reverse、rotate、swap 等。 数值算法:accumulate、count、fill 等。 集合操作:set_union、set_intersection、set_difference 等。 这些算法通常都接受迭代器作为参数,使它们与各种容器兼容。 3. 迭代器(Iterators) 迭代器是 STL 中用于遍历容器的对象,它们可以看作是容器的指针。通过迭代器,算法可以访问容器中的元素,而不关心容器的具体实现。迭代器的类型有: 输入迭代器(Input Iterator):只能进行单向读取。 输出迭代器(Output Iterator):只能进行单向写入。 前向迭代器(Forward Iterator):可以进行多次读取和写入,支持双向遍历。 双向迭代器(Bidirectional Iterator):除了前向迭代,还可以进行反向迭代。 随机访问迭代器(Random Access Iterator):支持随机访问,可以直接跳转到容器中的任何位置。 4. 函数对象(Function Objects) 函数对象是实现了 operator() 的对象,它们可以像普通函数一样被调用。STL 算法广泛使用函数对象来指定排序规则、判断条件等。例如: ...
Vector 向量
Vector 是一种动态数组,属于 STL 中的容器类之一,它提供了可以自动扩展大小的数组功能。与传统的数组不同,Vector 在需要时会自动调整大小,且支持快速访问、插入、删除等操作。 Vector 的特点: 动态大小:Vector 的大小是动态变化的,可以根据需要自动增长或缩小,避免了固定大小数组的限制。 按索引访问:可以像数组一样使用索引来访问 Vector 中的元素。 存储效率:Vector 会根据需要自动调整内部存储的大小,通常会预留一些额外空间来减少频繁的内存重新分配。 随机访问:支持快速随机访问,时间复杂度为 O(1),就像数组一样。 支持常见操作:Vector 提供了许多常见的操作,如插入、删除、查找、排序等。 Vector 的优点: 灵活性:不需要事先知道容器的大小,可以动态调整。 效率:与数组相比,Vector 在元素插入和删除时表现更好,尤其是插入到末尾时。 内存管理:Vector 会根据需要自动调整内部容量,减少了内存浪费。 Vector 的缺点: 在中间插入和删除效率低:虽然插入和删除操作通常很高效,但在 Vector 中间插入或删除元素时,可能需要移动大量的元素,时间复杂度为 O(n)。 内存重新分配:当 Vector 需要扩展容量时,它会分配一个新的更大的数组,并将元素复制到新的位置,这个过程可能会影响性能,尤其是元素较多时。 Vector 的常见操作: 访问元素:使用索引或迭代器访问元素。 插入元素:可以在末尾插入元素,或者在指定位置插入。 删除元素:可以删除指定位置的元素,或者删除末尾的元素。 查找元素:可以使用 find 等函数查找元素。 示例(C++): #include <iostream> #include <vector> // 引入vector头文件 using namespace std; int main() { // 创建一个空的vector vector<int> vec; // 在末尾插入元素 vec.push_back(10); // 插入10 vec.push_back(20); // 插入20 vec.push_back(30); // 插入30 // 访问元素 cout << "第一个元素: " << vec[0] << endl; // 输出: 10 cout << "第二个元素: " << vec.at(1) << endl; // 输出: 20 // 删除末尾元素 vec.pop_back(); // 删除30 // 遍历vector cout << "Vector中的元素: "; for (int i = 0; i < vec.size(); i++) { cout << vec[i] << " "; // 输出: 10 20 } cout << endl; // 在指定位置插入元素 vec.insert(vec.begin() + 1, 15); // 在第二个位置插入15 cout << "插入15后的元素: "; for (int i = 0; i < vec.size(); i++) { cout << vec[i] << " "; // 输出: 10 15 20 } cout << endl; return 0; } 代码解析: push_back:将元素添加到 Vector 的末尾。 vec[0] 或 vec.at(1):通过索引或 at 方法访问元素,at 方法会进行越界检查。 pop_back:删除 Vector 末尾的元素。 insert:在指定位置插入元素,vec.begin() + 1 表示第二个位置。 Vector 的应用: 动态数组:Vector 主要用于处理不知道大小的动态数据集合,且需要快速随机访问和插入删除操作。 实现其他数据结构:Vector 可以用来实现栈、队列等数据结构。例:栈可以用 push_back 添加元素,使用 pop_back 删除元素。 数据存储:适用于存储需要动态增加或删除元素的场景,如图像数据、传感器数据等。 算法优化:由于 Vector 支持高效的随机访问,它常用于一些需要按位置访问元素的算法,如快速排序、查找算法等。 总结: Vector 是一个灵活且高效的动态数组容器,广泛应用于需要动态管理数据的场景。相比传统数组,它提供了更好的内存管理和扩展能力,适用于频繁添加元素的场合。 ...
队列 Queue
队列(Queue)是一种线性数据结构,它遵循“先进先出”(FIFO,First In First Out)原则,即第一个进入队列的元素将是第一个被移除的元素。队列的结构像排队的人群,先到的人先得到服务。 队列的特点: 先进先出(FIFO):队列的访问顺序遵循先进先出的原则,最先加入的元素最先被移除。 操作限制:队列只允许在一端进行插入操作(称为队尾),只允许在另一端进行删除操作(称为队头)。 存储结构:队列可以使用数组或链表来实现。 队列的常见操作: enqueue(入队):将元素加入到队列的尾部。 dequeue(出队):从队列的头部移除元素,并返回该元素的值。 peek(或 front):查看队列头部的元素,但不移除它。 isEmpty:检查队列是否为空。 size:返回队列中元素的个数。 队列的应用: 任务调度:操作系统使用队列来管理进程调度。队列用于存放等待执行的任务,系统会按照先进先出的顺序执行这些任务。 打印队列:在打印机中,打印任务通常以队列的形式管理。先发出的打印任务先被处理。 消息队列:在计算机网络和多线程编程中,消息队列常用来管理不同任务或进程间的通信。消息按照先进先出的顺序进行传递。 广度优先搜索(BFS):广度优先搜索算法(BFS)使用队列来遍历图或树的节点。 队列的示例(C++): #include <iostream> #include <queue> // 引入queue头文件 using namespace std; int main() { queue<int> q; // 创建一个空队列 // enqueue操作:入队 q.push(10); // 入队10 q.push(20); // 入队20 q.push(30); // 入队30 // peek操作:查看队头元素 cout << "队头元素: " << q.front() << endl; // 输出: 10 // dequeue操作:出队 q.pop(); // 出队10 // 打印队头元素 cout << "出队后, 队头元素: " << q.front() << endl; // 输出: 20 // isEmpty操作:检查队列是否为空 if (!q.empty()) { cout << "队列不是空的!" << endl; // 输出: 队列不是空的! } // size操作:获取队列的大小 cout << "队列的大小: " << q.size() << endl; // 输出: 2 return 0; } 代码解析: push:将元素添加到队列的尾部。 front:查看队列头部元素的值。 pop:从队列的头部移除元素。 empty:检查队列是否为空。 size:返回队列中的元素个数。 队列的优缺点: 优点: ...
二叉树 Binary Tree
二叉树是一种每个节点最多有两个子节点的树形数据结构。它是一种广泛应用于计算机科学中的数据结构,常用于表达层次结构、实现查找、排序、表达式求值等任务。 二叉树的基本定义: 节点:二叉树中的每个元素,通常包含数据和指向其子节点的指针。 根节点(Root):二叉树的第一个节点,是树的起点。 子节点(Children):每个节点可以有最多两个子节点,分别是左子节点和右子节点。 叶节点(Leaf):没有任何子节点的节点,也叫终端节点。 父节点(Parent):指向某一节点的上级节点。 深度(Depth):从根节点到该节点的路径长度。 高度(Height):从该节点到最远叶子节点的路径长度。 二叉树的基本类型 满二叉树(Full Binary Tree): 每个节点要么没有子节点,要么有两个 子节点。 即,除了叶节点外,其他每个节点都有两个子节点。 完全二叉树(Complete Binary Tree): 除了最后一层外,每一层的节点都尽可能多,且最后一层的节点都集中在左侧。 平衡二叉树(Balanced Binary Tree): 任意节点的左右子树的高度差不超过 1。 例如,AVL树和红黑树是常见的平衡二叉树。 二叉搜索树(Binary Search Tree, BST): 对于树中的每一个节点,左子树的所有节点的值小于该节点的值,右子树的所有节点的值大于该节点的值。 二叉搜索树提供了高效的查找、插入和删除操作。 赫夫曼树(Huffman Tree): 一种带权路径长度最短的二叉树,常用于数据压缩算法中。 二叉树的基本操作 二叉树的操作主要包括遍历、插入、删除、查找等。下面介绍常见的操作: 1. 遍历(Traversal) 遍历是指按照一定的顺序访问二叉树的每个节点。常见的遍历方式有: 前序遍历(Pre-order Traversal):访问根节点,然后递归遍历左子树和右子树。 顺序:根 → 左 → 右 示例:A, B, D, E, C, F 中序遍历(In-order Traversal):递归遍历左子树,然后访问根节点,最后递归遍历右子树。 顺序:左 → 根 → 右 示例:D, B, E, A, F, C 后 序遍历(Post-order Traversal):递归遍历左子树和右子树,然后访问根节点。 顺序:左 → 右 → 根 示例:D, E, B, F, C, A 层次遍历(Level-order Traversal):逐层遍历树的节点,通常使用队列实现。 顺序:从根节点开始,逐层访问每个节点。 示例:A, B, C, D, E, F 2. 插入(Insertion) 二叉搜索树的插入:在二叉搜索树中插入节点时,根据节点的值与当前节点的值进行比较,决定将新节点插入到左子树还是右子树,直到找到合适的位置。 3. 删除(Deletion) 删除节点:删除二叉树中的节点时,需要考虑三种情况: 没有子节点(叶节点):直接删除。 有一个子节点:用子节点替代被删除的节点。 有两个子节点:通常用右子树中的最小节点或左子树中的最大节点来替代被删除的节点,然后递归删除替代节点。 4. 查找(Search) 二叉搜索树的查找:从根节点开始,根据查找的值与当前节点的值比较,决定是向左子树还是右子树查找,直到找到该节点或遍历完整棵树。 二叉树的应用: * / \ + + / \ / \ a b c d 表达式树:用于表示数学表达式。在计算机科学中,表达式树是二叉树的一种应用,其中每个叶子节点代表操作数,每个非叶子节点代表操作符。 例如:(a + b) * (c + d) 可以表示为以上代码块。 二叉查找树的应用: 高效查找:在二叉查找树中,查找操作的平均时间复杂度是 O(log n),比线性查找 O(n) 更高效。 排序:通过中序遍历二叉搜索树可以得到一个有序序列,从而实现排序。 堆(Heap): 二叉堆是一种特殊的二叉树,常用于实现优先队列。二叉堆有两种:最大堆和最小堆。最大堆的父节点的值大于等于子节点的值,最小堆则相反。 二叉树的平衡:AVL 树、红黑树等自平衡二叉树可以用于实现高效的查找、插入和删除操作,广泛应用于数据库索引、内存管理等领域。 二叉树的优缺点: 优点: ...
哈希表 Hash Table
哈希表(Hash Table)是一种用于存储键值对(key-value pairs)的数据结构,它可以实现非常高效的查找、插入和删除操作。哈希表通过哈希函数将键映射到哈希表的索引位置,从而能在常数时间 O(1) 内完成查找、插入和删除操作。 哈希表的基本原理 哈希函数:哈希表通过哈希函数将键(key)映射到哈希表中的一个特定位置(即索引)。哈希函数的目标是尽可能将不同的键映射到不同的索引,以减少冲突。 哈希函数的一种常见实现方法是:hash(key) = key % table_size,这里的 table_size 是哈希表的大小。 冲突(Collision):不同的键可能通过哈希函数计算后得到相同的哈希值,从而映射到同一个位置,这时就发生了冲突。解决冲突的常见方法有: 链式地址法(Separate Chaining):每个哈希表的槽位(bucket)存储一个链表,冲突的元素存储在同一个链表中。 开放定址法(Open Addressing):当发生冲突时,哈希表会尝试在表中寻找其他空位,直到找到一个空槽。 负载因子(Load Factor):负载因子是哈希表中的元素数量与哈希表大小的比值,用来衡量哈希表的填充程度。负载因子过高可能导致哈希冲突增多,从而降低性能。通常当负载因子超过某个阈值时,会对哈希表进行扩容(rehash)。 扩容与再哈希(Rehashing):当哈希表的负载因子超过设定的阈值时,可以通过增加哈希表的大小并重新计算每个元素的哈希值来减少冲突,从而提高查找效率。 哈希表的基本操作 插入(Insert): 使用哈希函数计算键的哈希值,并将其映射到对应的槽位。 如果槽位已被占用,则根据解决冲突的方法(链式或开放定址法)处理冲突。 查找(Search): 使用哈希函数计算键的哈希值,然后检查该槽位是否存在对应的值。如果有冲突,则需要继续检查链表或其他空槽。 删除(Delete): 使用哈希函数找到元素的位置,并删除它。如果存在冲突(如链式法),需要相应地删除链表中的元素。 扩容(Rehashing): 当哈希表的负载因子过高时,哈希表的大小需要扩大,通常是扩展为原来大小的两倍,然后重新计算每个元素的哈希值并重新插入。 哈希表的优缺点 优点: 快速查找:在理想情况下,哈希表的查找、插入和删除操作的时间复杂度是 O(1),即常数时间操作。 高效存储:由于哈希表通过哈希函数直接映射到槽位,因此可以在大规模数据存储时提供高效的访问。 缺点: 哈希冲突:当多个键映射到同一个位置时,会发生哈希冲突。虽然可以通过链式或开放定址法解决冲突,但会影响操作效率。 不适合排序:哈希表中的元素没有顺序,不能直接支持按键排序。 空间开销:哈希表为了避免过多冲突,通常需要比实际存储元素更多的空间。这可能导致内存浪费。 哈希表的应用 快速查找:哈希表用于实现快速查找功能,广泛应用于数据库索引、缓存系统等。 去重:通过将元素作为键存储,哈希表可以方便地去除重复元素。例如,在处理大数据时,通过哈希表去除重复记录。 计数统计:哈希表可以用于统计每个元素出现的次数,广泛应用于词频统计、数据分析等。 实现集合操作:哈希表常常用于实现集合(set)的操作,如交集、并集、差集等。 哈希表的示例实现(C++) #include <iostream> #include <list> #include <vector> using namespace std; class HashTable { private: vector<list<int>> table; // 哈希表的桶(使用链表处理冲突) int size; // 哈希表的大小 int hashFunction(int key) { return key % size; // 哈希函数(取模) } public: HashTable(int s) { size = s; table.resize(s); // 初始化哈希表 } // 插入操作 void insert(int key) { int index = hashFunction(key); // 计算哈希值 table[index].push_back(key); // 在对应的槽位插入键 } // 查找操作 bool search(int key) { int index = hashFunction(key); for (int element : table[index]) { if (element == key) { return true; // 找到元素 } } return false; // 未找到元素 } // 删除操作 void remove(int key) { int index = hashFunction(key); table[index].remove(key); // 从链表中删除元素 } // 打印哈希表 void display() { for (int i = 0; i < size; i++) { cout << "Bucket " << i << ": "; for (int element : table[i]) { cout << element << " "; } cout << endl; } } }; int main() { HashTable ht(7); // 创建一个大小为7的哈希表 ht.insert(10); ht.insert(20); ht.insert(15); ht.insert(7); ht.insert(30); ht.display(); // 显示哈希表 cout << "Search 15: " << (ht.search(15) ? "Found" : "Not Found") << endl; cout << "Search 25: " << (ht.search(25) ? "Found" : "Not Found") << endl; ht.remove(15); cout << "After deleting 15:" << endl; ht.display(); // 删除元素后显示哈希表 return 0; } 代码解析 HashTable 类:包含了哈希表的基本操作,如插入、查找、删除和显示哈希表。 insert():通过哈希函数计算插入元素的槽位,然后将元素插入到该槽位的链表中。 search():通过哈希函数找到槽位后,遍历链表检查是否有该元素。 remove():通过哈希函数找到槽位,并从该槽位的链表中删除元素。 display():显示哈希表的所有槽位及其存储的元素。 总结 哈希表是一种高效的键值对存储数据结构,能够提供常数时间复杂度的查找、插入和删除操作。它广泛应用于需要高效查找、去重和计数的场景。虽然哈希表在实际应用中需要解决哈希冲突问题,但通过合适的冲突解决方法,可以保证其高效性。 ...