OI程序常见的设计陷阱
宏定义的问题
有时候为了方便,我会大量使用宏定义。但是最近我发现下面这两个宏定义老是出问题:
#define SET(x,a) memset(x,a,sizeof(x))
inline void work(){
SET(head,),SET(vis,),SET(dis,0x3f);
//do something
}
这个宏定义似乎在初始化的时候会莫名奇妙地出现一些问题。
另外,还有这个:
#define RP(i,a,b) for(register int i=a; i<=b; i++)
inline void work(){
vector<int> ver;
//do something
RP(i,,ver.size()-){
//do something
}
}
当你定义了一个 RP 的循环宏时,它的判断会出一些问题。比如说在上面这个例子,如果ver.size()==0,那么正常的for就不会进入这个循环。但是宏定义之后它的判断顺序似乎发生了改变。
很奇怪吧?因此,有些宏还是不要乱用。
另外,宏和函数不同。它相当于是让编译器对源码进行自动替换,而宏的语法如果不加注意,则会出错。举个例子,如果你想把二维坐标映射到一个整数,用宏ID(a,b) = a * M + b 来实现,那么这个语法肯定有问题。假设坐标从0开始,你想得到右下角ID(M - 1, M - 1),那这个宏会把它变成M - 1 * M - M - 1 = -M - 1。正确的语法应该为ID(a,b) = (a) * M + (b)。
不要乱卡常
网上有一些奇奇怪怪的卡常方式,比如说把i++写成i=-~i,或者用大量的逗号链接若干个语句。对于前者,这个二进制优化其实并不如想象中的那么出色,对速度的提升不明显。(虽然我本人也喜欢把i++写成++i以提高速度)对于后者,虽然逗号运算符在一定程度上可以提高效率,但有些时候会出现一些奇怪的问题。我记得很久以前,我喜欢把很多语句用若干个逗号连成一条;但是有时候,程序可能只会其中的部分几条,剩下的会被忽略!我不知道是否真的有这个问题,但是我的建议还是不要乱用逗号。
注意空间复杂度
在学习任何一个算法或数据结构时,一定要翔实记录它的空间复杂度。比如说,trie树的空间复杂度是多少?一般要开多大?用链式前向星存无向图,是否把边数组开成题给的两倍?这些问题不注意,你也许可以通过样例,但最后可能一分都拿不到。如果你是在网上评测,有时候评测机并不会反馈RE的信息,而是WA。如果不加注意,你会因为这个问题而调试很久。
另外,足够大的空间也可以从一定程度上提高程序的运行速度。这应该和“空间大易于伸展手脚”是一个道理。
注意类型转换
始终注意类型转换。有时候即便你把所有的数值变量开成long long类型,你可能会在赋值的时候忘记把一个int类型的表达式进行转换。这样,表达式在被赋值前就会发生溢出。任何时候要牢记各种变量的类型,并时不时转换一下。
另外,强制转换的速度会相当慢。如果你想转换成long long类型,直接在变量前乘上1ll;对于普通double类型,可以直接乘上1.0;对于更特殊的long double或是__int128类型,你就只能强制转换了。
慎用STL
STL会节省很多时间,而且大部分时候它们除了常数大以外,由于封装了很多函数,使得它们操作起来非常方便。但是有些时候,用STL很有可能会RE。当然,这是否需要“释放内存”,或者一些更高级的处理方法,这我不得而知。
学会设计参数
不久前在写矩阵快速幂的时候,发现“引用形参”比不引用形参要快得多。因此,当函数的参数是一个比较大的数据结构时,采用引用的写法会加速很多。
OI程序常见的设计陷阱的更多相关文章
- 小程序-文章:微信小程序常见的UI框架/组件库总结
ylbtech-小程序-文章:微信小程序常见的UI框架/组件库总结 1.返回顶部 1. 想要开发出一套高质量的小程序,运用框架,组件库是省时省力省心必不可少一部分,随着小程序日渐火爆,各种不同类型的小 ...
- Swing程序最佳架构设计—以业务对象为中心的MVC模式(转)
前言: 我打算写一系列关于Swing程序开发的文章.这是由于最近我在做一个Swing产品的开发.长期做JavaEE程序,让我有些麻木了.Swing是设计模式的典范,是一件优雅的艺术品,是一件超越时代的 ...
- 官方问答--微信小程序常见FAQ (17.8.21-17.8.27)
给提问的开发者的建议:提问之前先查询 文档.通过社区右上角搜索搜索已经存在的问题. 写一个简明扼要的标题,并且正文描述清楚你的问题. 提交 BUG:需要带上基础库版本号,设备信息(iOS, Andro ...
- C#WinForm窗体内Panel容器中嵌入子窗体、程序主窗体设计例子
C#WinForm父级窗体内Panel容器中嵌入子窗体.程序主窗体设计例子 在项目开发中经常遇到父级窗体嵌入子窗体所以写了一个例子程序,顺便大概划分了下界面模块和配色,不足之处还望指点 主窗体窗体采用 ...
- java.awt包提供了基本的java程序的GUI设计工具
java.awt包提供了基本的java程序的GUI设计工具.主要包括下述三个概念: 组件--Component 容器--Container 布局管理器--LayoutManager package T ...
- 微信小程序开发系列二:微信小程序的视图设计
大家如果跟着我第一篇文章 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 一起动手,那么微信小程序的开发环境一定搭好了.效果就是能把该小程序的体验版以二维码的方式发送给其他朋友使用. 这个系列 ...
- python学习笔记(2)——练习小程序之 " input " 隐藏陷阱
练习小程序之 ----------" input " 隐藏陷阱 age=input('please enter your age:') if age>=18: print(' ...
- 微信小程序常见的UI框架/组件库总结
想要开发出一套高质量的小程序,运用框架,组件库是省时省力省心必不可少一部分,随着小程序日渐火爆,各种不同类型的小程序也渐渐更新,其中不乏一些优秀好用的框架/组件库. 1:WeUI 小程序–使用教程 h ...
- 深入浅出 Java Concurrency (39): 并发总结 part 3 常见的并发陷阱
常见的并发陷阱 volatile volatile只能强调数据的可见性,并不能保证原子操作和线程安全,因此volatile不是万能的.参考指令重排序 volatile最常见于下面两种场景. a. 循环 ...
随机推荐
- 【Python基础】05_Python中的while循环
1.程序的三大流程介绍 顺序 —— 从上到下,顺序执行 分支 —— 根据条件判断,决定代码的分支 循环 —— 让特定代码执行 2.while 基本语法 while 条件(判断 计数器 是否达到 目标次 ...
- Secret的三种形式
Secret ConfigMap这个资源对象是Kubernetes当中非常重要的一个对象,一般情况下ConfigMap是用来存储一些非安全的配置信息,如果涉及到一些安全相关的数据的话用ConfigMa ...
- IntelliJ IDEA 搭建 Go 开发环境
本文介绍 Windows7 x64 基于 IntelliJ IDEA 搭建 Go 语言开发环境.主要是一些操作过程截图以及简单文字描述,如有不清楚的地方,欢迎指正.所有软件使用当前(2016.12. ...
- 怎样理解xhr.overrideMimeType()和xhr.responseType
一般情况下, 我们会通过 xhr.responseType 告诉服务器我们想要什么类型的返回数据. 然后xhr.response 会根据xhr.responseType属性值来自动解析返回值. 但有时 ...
- JavaScript实现按照指定长度为数字前面补零输出的方法
本文实例讲述了JavaScript实现按照指定长度为数字前面补零输出的方法.分享给大家供大家参考.具体分析如下: 例如我们希望输出的数字长度是固定的,假设为10,如果数字为123,则输出0000000 ...
- 【ES6 】Promise
Promise对象定义: 用来处理异步编程 Promise对象的特点 对象的状态不受外界影响 一旦状态改变,就不会再变,任何时候都可以得到这个结果 Promise对象的状态 pending(进行中) ...
- jquery model 框设定
https://www.bootcdn.cn/ 国内网址引用 js function searchItemInfo(conditionNo,lotCD,itemKey) { var conditi ...
- 启动tomcat提示某个端口被占用
原文参见:https://www.cnblogs.com/liuyanxia/p/6755520.html 解决办法 找出占用1099端口的进程,进入windows命令,查看什么进程占用了1099端口 ...
- java中的多态总结
一.多态的概述 ava作为面向对象的语言,同样可以描述一个事物的多种形态.如Student类继承了Person类,一个Student的对象便既是Student,又是Person. Java中多态的代码 ...
- json树迭代
getArray(data){ for (var i in data) { if(data[i].disabled){ data[i].disabled = false } if(data[i].ch ...