博文

目前显示的是标签为“Atalod”的博文

如何优(装)雅(B)地使用C++

介绍一些冷门的C++语法特性,供压行选手使用(雾) 前置知识 C++基础语法( 运算符重载 template 的初级应用(什么是初级呢,会用 template 写 max 就好) functor (只会提及,了解即可) 正文 1.匿名函数(lambda表达式) 需要C++11 比赛可用:★★★☆☆ 代码简化:★★★★☆ 匿名函数应用于需要使用短函数的场合,或者函数需要修改此作用域内(非全局作用域)的局部变量的场合。 常见用法是使用 sort 的时候,需要传入一个 cmp 数组,但是自行定义又太过于繁琐,这时候可以直接使用 lambda 表达式。 基础格式: [捕捉局部变量列表](参数){函数体} 例如,如果需要给 point 排序,以 x 为第一关键字从大到小排序,可以这么写: sort(pi+ 1 ,pi+ 1 +n,[](point a,point b){ if (a.x != b.x) return a.x<b.x; return a.y<b.y; }); lambda 本质是一种 functor ,即重载了 operator () 的类。 笔者曾经想使用 lambda 表达式作为返回值,然后就不想了 笔者曾经想使用 lambda 表达式来玩一些骚操作,然后被类型系统劝退了 2.语句内嵌表达式 无特殊要求 比赛可用:★★★★★ 代码简化:★★☆☆☆ 语句内嵌表达式应用于需要在传入一个值的场合运行一个表达式的情况。这么说可能有点抽象,具体来说,比如我们要执行以下程序段: int a = query( 1 , 1 ,n,l1,r1); int b = query( 1 , 1 ,n,l2,r2); printf ( "%d" ,a+b+a*b); 这时候,就可以使用这样的语法来代替: printf ( "%d" ,({ const int a = query( 1 , 1 ,n,l1,r1); const int b = query( 1 , 1 ,n,l2,r2); a+b+a*b; })); 也就是说,语句内嵌表达式的格式是这样子: (...

【洛谷】题解 P1633 【二进制】

dalao 都用 DP,我发一发贪心的题解。 DP 题硬生生被做成了思维题 首先,不考虑长度限制,只考虑两个数字的 1 的个数。设 A 中 1 的个数为  an a n  ,B 中为  bn b n  ,C 中为  cn c n  。 如果  an+bn<cn a n + b n < c n  的话,显然无解,因为 1 不可能被凭空创生而来。如果  an+bn=cn a n + b n = c n  的话,只需要不产生进位,即让两个加数的二进制表示全部错开就好。然后考虑  an+bn>cn a n + b n > c n  的情况。 在这种情况下,我们需要通过进位消掉  an+bn-cn a n + b n − c n  个 1,然后保证答案最小。 容易发现,可以简单地使用连续进位来消掉任意个数的 1: 11111 + 1 ------ 100000 消掉的 1 的个数即为第一个加数的长度。 严格来说,消掉的 1 的个数的范围为  [0,an+bn-1] [ 0 , a n + b n − 1 ]  。因为,我们可以这样子: 11111 1 + 111111 -------------- 100000000000 (空格为 0) 可行性可以保证。然后就是考虑最优性。 很显然,对于这样一组连续进位,两个加数在连续进位之前的位必须都是 0。也就是说,算式里面最多只能有一组连续进位。如果有两组连续进位,可以将这两组合并,然后偷掉一个位(全 0 位显然可以直接抠掉),这样两个加数都会变小,和也会变小。 唯一的进位处就在那个连续进位的地方。 同理,这个连续进位必须在最高位。如果不是的话,可以交换顺序使它在最高位,然后偷掉一个位。 基本框架就确定了,由于消掉的 0 的个数确定,连续进位的长度也确定了,然后只需要在这个基础上贪心地将 1 用完就好了。 在这个连续进位式骨架上,我们可以做的事情包括将一个连续进位中的改成 1,以及在后面跟单独一个 1。容易证明,最优的解就是尽量用 1 填那个进位中的空,如果还有多余的 1...

编程语言简介

图片
OIer从入门开始,使用的只有C++语言,最多听说过Pascal,可能以为编程只存在于OI了。殊不知,这是坐井观天的行为,井外还有一整个大千世界。了解、学习一下其余编程语言,对于提升OIer的个人素养无疑是极有好处的。 注:可能带有个人观点或列举不全,欢迎补充和纠正 编程语言的分类 此处依据语言范式分类。语言范式,即语言的计算模型,是区别各语言的一个重要的特征。另外还有领域专用语言-通用语言等的区分,留给OIer课后了解。 命令式 包括C++、C、Pascal、Java等 命令式程序明显的有“命令”的特征,即其程序由一行行指令构成,电脑按次序执行这一行行指令。 命令式可进一步细分为面向对象和面向过程,可以自行了解。 函数式 包括Haskell等 函数式语言最明显的特征是其没有副作用(即没有赋值语句与变量),这导致了其程序有高度的可并行性。函数式语言的工作原理为“映射”,通过函数将输入数据映射成输出数据。 函数式语言的工作方式较反人类,这导致了其较难推广和在工程上大规模使用。 纯函数式语言似乎只有Haskell,其余均为多范式语言,这体现了函数式语言的小众。 声明式 包括SQL、Prolog等 该语言最显著的特征是高度专业性。语言通过描述解的特征来给出解,类似于描述蛋糕的外观,产生制作蛋糕的程序。这导致该语言只能在一个特定的领域工作,例如SQL在数据库领域,Prolog在逻辑推理领域。 SQL已在工业中广泛运用。 多范式 包括F#、Scala、Lisp系等。 该语言支持多种编程范式,可以说是结合了多种范式的优点。大多数语言是综合了命令式和函数式,有助于程序员一边用着命令式一边尝试其函数式特性。C++在面向对象的传播中起到了类似作用。 此处“跨范式”不包括面向对象-面向过程的区分,因此C++不算在内。 学术界编程语言 学术语言 这类语言的学术价值较高,经常在学术界作研究项目存在。 Haskell 特点 :纯函数式编程语言,不支持任何赋值语句、变量等特性。有大量书籍 优点 :作为纯函数式编程语言,学术价值极高 缺点 :学习曲线陡峭、易沉迷,反人类 Scheme 特点 :作为Lisp方言,语法纯粹简洁,在SICP中作教学语言 优点 :多范式(偏向函数式),易于讲...