程序设计竞赛小技巧

来源:互联网 发布:淘宝申请退款会不退吗 编辑:程序博客网 时间:2024/06/07 23:33
  • 扩栈
    在头文件处输入:#pragma comment(linker, “/STACK:102400000,102400000”)
  • 十进制正整数n的位数为(int)log10(n) + 1
  • O(2^n)子集枚举
    O(n!)排列枚举
if(i)//i-1    printf(" ");
  • “/”的取整是朝0方向的
  • 二分时用x + (y - x)/2来确保分界点总是靠近区间起点的
  • 头指针:struct node *head = NULL;
  • 指针不能用.号来访问结构体内部成员,而要用->
  • 用数学方法缩小枚举范围
while((c = getchar() != EOF){}
  • 中间结果的计算可能会溢出
  • [N / K]等于1,2,3,……,N中能被K整除的数的个数
  • 分治,递推,贪心等,都是将问题转化为规模更小的若干个问题
  • 倍增法,将环断开变成链
  • 尺取法:反复地推进区间的开头和末尾,来求满足条件的最小区间的方法
  • 二元关系可以用图来建模
  • 从主函数开始阅读程序是一个好习惯
while(scanf("%s",a) != EOF){}
  • 敲键盘的时候,如果在机器上思考超过三分钟,说明没准备好,应停下来想清楚再继续敲键盘。
  • 挑站类似的问题时要反复练习并注意精简代码,总结出自己满意的代码之后,便可以将其作为解决同类问题的模板加以活用
  • 使用位运算,可以枚举从n个元素中取出k个的共C(n,k)种状态或是某个集合中的全部子集
  • 翻几番就是用基数乘以2的n次方的结果(几何级数)
    翻几倍就是在基数的基础上增加几倍(算术级数)
    翻一倍 = 翻一番
    两番 = 4倍
    三番 = 8倍
    增加倍数 = 目标数 / 基数 -1
  • (正,反)(反,正)是不同的事件
  • X以上,X以下。都包含X这个值
  • 边界条件:用空输出,一个元素,两个元素,零值等
  • 找规律:打表或上http://oeis.org/
  • 画出状态转移树
  • 将相同的小球变成互不相同的小球:加上不同的标签或者全排列一下
  • 想删除数组中的某个元素:.erase()或者标记一下,被标记相当于被删除
  • 10^8 有8个0 共9位数 是一亿
  • 位运算一定要加括号
  • 使用Excel制作DP表格
  • 读入一行包含空格符的字符串
string s;getline(cin,s);
srand((unsigned)time(NULL)) //初始化随机数种子
  • 多想想为什么他能想到这一点
  • x与x+1互质
  • 必须要把所有条件都用上
  • 一步步推理,不要跳步 A=>B=>C=>D
  • 自己的想法为什么错了?
  • 代码风格
    ①首字母大写
    ②双目操作符前后加空格
    ③用空行来分块
    ④适当地加注释
  • 英文题可以提高阅读理解能力
  • 搜索理论上可以解决所有问题
  • 多用STL
  • 沉浸于思考大脑就不会觉得疲倦
  • 牢记算法思路与代码:
    ①遵循记忆规律,常复习,起床后回顾前一天所学内容
    ②用形象有趣的例子去记忆
  • 取log可以将乘法变为加法
  • 是否整除:用mod来判断
  • 写对拍(用c++,Python或批处理脚本),不用费劲去调试,可以节约时间
  • 分清哪一些是需要学习的,哪一些是需要独立思考的
  • 写解题报告时写出推理过程
  • 可以利用全局变量增加与函数联系的通道,从而使函数得到一个以上的返回值
  • 分析大于的情况,小于的情况还有相等时的情况
  • 要把一段内存全部置为无穷大,我们只需要
memset(a,0x3f,sizeof(a))
  • 通过输出字符串来定位出错语句的位置
  • 小心因为重复使用n导致变量重复
  • 2^31 - 1 二进制下有32位,1位是符号位,剩下31位全1,且2^31有32位
  • ceil()取上整,floor()小取下整
  • 曼哈顿距离:在平面上,坐标(x1, y1)的i点与坐标(x2, y2)的j点的曼哈顿距离为:d(i,j)=|X1-X2|+|Y1-Y2|.
  • 应避免将一个很大的浮点数和一个很小的数直接相加或相减,这样会丢失小的数
  • 贪心的题一般来说都会用到两种东西——排序和优先队列。

    排序一般适用于只贪心一遍的题,而优先队列则更适合需要将上一次贪心的结果变成下一次的一个元素的题
  • i+1就是i!=-1
  • 题目变形方式:链变环
  • 对于坐标的处理方法:本来是用两个数来表示的坐标(x, y),可以用一个数来表示。为什么要这样?简便呗!第i行第j列的格子编号为i*m+j(横纵坐标的起点都是0)。于是编号为u的节点,其行号和列号分别为u / m; u % m
  • 如果eps取得太小了,就有可能会因为浮点小数精度的原因导致陷入死循环
  • 小技巧处理——差分+前缀和。
    所谓差分,就是把区间的操作转移到对区间端点的操作。比如我们对一个都是0的数组,要在5~13这段区间加上3,只要在5这个点上加上3,在14这个点上减掉3,这样在算前缀和的时候,0~4都是0,5~13都是3,14及以后又都成了0。这种操作修改是O(1),查询是O(n)
  • 后缀表达式总结:①栈是后进先出的数据结构,所以要注意减法运算与除法运算②注意样例中给出的虽然是个位数,但数据中有多位数,因此要考虑分词。对数的类型考虑要全面,如:整数,正数,负数,浮点数③.是用来分数的,不是用来分运算符号的④仔细分析有没有用long long的必要
  • 当程序逻辑没问题时,可能是爆int了
  • 离散化简单地来说就是只取我们需要的值来用,比如说区间[1000,2000],[1990,2012] 我们用不到[-∞,999][1001,1989][1991,1999][2001,2011][2013,+∞]这些值,所以我只需要1000,1990,2000,2012就够了,于是将其分别映射到0,1,2,3,在于复杂度就大大的降下来了。所以离散化要保存所有需要用到的值,排序后,分别映射到1~n,这样复杂度就会小很多很多
  • 一个数加一个负号是把这个数的二进制取反+1
原创粉丝点击