ACM札记
1. 逗号表达式
在“计蒜客“的ACM教程中,看到这样一段很好的代码:
int n;
while (scanf("%d", &n), n) {
//do something
}
解释如下:
scanf后面有个逗号,这就是所谓的逗号表达式。整个表达式的结果就是用逗号分隔的最后一个表达式的值。当n的值为0时,整个表达式的值就是0,此时退出循环。
2. ACM惯用头文件
引用
#include <bits/stdc++.h>
而无需引用两个头文件
#include <iostream>
#include <cstdio>
这种方法并不是所有平台都适用的,用之前记得查阅平台的FAQ。不过在国内oj中,poj,hdu 不支持这个函数,这几个oj的编译器问题,其他国外的oj,还有台湾的oj都支持,CF(http://codeforces.com/),Topcoder也都支持。
3. 读取一整行字符串——scanf 与 gets
输入样本如下:
I promise I will no more cheat in tests.
2
1
在这里
scanf("%s", str);
是行不通的,因为文章——第一行的字符串——的内部会有空格,而这样的语句只能把空格之前的内容读入到str。
因此我们要使用读取一整行的函数,如下:
gets(str);
多提醒读者一句,使用gets的时候如果发生溢出的话程序是不会报错的,所以读者在使用gets的时候一定要小心哦!
4. 判断输入结束——scanf 函数
while (scanf("%d", &cnt) == ) {
    //do something
}
当scanf正确读入时,返回值是和读取的变量数目相等的。而当读取出错、读到文件末尾时,scanf函数会返回-1,因此当读到文件结束时,上述while循环就会中止。当然啦,也可以写成如下样式,效果是等价的。
while (scanf("%d", &cnt) != -){
    //do something
}
5. int不够用时——long long类型
输入数据的范围最大是10000,10000的立方是10^12,而int类型的最大值是2147483647,大约是2*10^9,远远超过了int的最大值,这样在计算过程中就会出现溢出的情况,导致结果错误。因此我们需要用更大的整数类型long long,它的最大值大约为10^19,即使10000个10^12也不会超过long long的取值范围。
此外,记得long long输出是用%lld而非%d哦。
6. 关于Bug
做题时不可避免会遇到程序错误(Bug),这时程序会在Online Judge上获得对应的错误信息,比如Wrong Answer, Runtime Error等。此时就需要各种debug方法来解决。通常debug有三类方法:通读程序;重读题目和使用数据调试。
循环自增变量笔误是常见的bug,多见于多重循环的内层中。
7. 编程比赛
Topcoder也是唯一一个必须下载客户端才能参加的程序设计竞赛。用户在Topcoder会有积分(rating)和积分对应的颜色标示,如上图中所 示,红>黄>蓝>绿>灰>白。积分最高的几个选手的id左侧会有一个类似靶心的标志,我们称之为target。 ACRush(楼天城)就是target选手之一。
在 Linux上与mingw对应的是gcc和g++,由于这些都是系统自带的程序,在安装Codeblocks的时候不需要再单独安装一遍了。两个编译器在 一些细微之处还是有不同的,比如64位整型变量的输入(scanf)和输出(printf),在Linux下参数为%lld,而Windows下的参数 为%I64d。
比如HDU(acm.hdu.edu.cn)和CF(codeforces.com)就是典型的Windows下搭建的OJ,不过大部分OJ还是Linux环境运行的。
在提交用到64位整型的代码时一定要注意平台的操作系统,一般可以通过查看OJ的FAQ或在比赛现场咨询裁判获知。
什么是代码能力?简单地说,如果你觉得学会了某一个算法或者数据结构,你能否在半个小时(或一小时)内完成程序,并且经过很少的调试一次通过?如果做不到 的话,只能说你还没彻底掌握这个算法或数据结构,要不断地训练,直到达到要求,只有这样才能保证在高度紧张的比赛中敢于实现而不犯错误。
8. 算法复杂度
复杂度分为时间复杂度和空间复杂度。通俗一点说,就是『跑多快』和『占多大内存』。
在分析复杂度时,我们通常考虑它与什么成正比,并称之为算法的阶。比如程序执行了一个三重循环,每重循环执行n次,那么运行时间就和n4成正比。我们将与n4成正比写作O(n4)。再比如程序开辟了一个二维数组,下标范围是[0..n-1][0..n-1],那么程序的空间复杂度就是O(n2)。
程序的运行时间不仅取决于时间复杂度,也会受计算复杂度、递归等因素的影响,但因此造成的差距最多也就是几倍。
估算一个复杂度是否能承受目前的数据规模时,就将数值可能的最大值待遇复杂度的渐进式中,就能简单的判断算法是否能够满足运行时间限制的要求。比如O(n2)的算法,将n=1000代入得到1000000。通常来讲按照上述方法计算得到108基本是1s时限的最大值。
9. 分治算法
分治,即“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。总结起来就是:分解、解决、合并,这三大步。
分治策略最经典的一个例子就是折半搜索算法,也就是二分查找——通过不断缩小解可能存在的范围,从而求得问题最优解的方法。二分查找是在有序数组中查找某一特定元素的搜索算法。搜索过程中从数组的中间元素开始,判断待查元素和中间元素的关系,来判断接下来是选择哪一半继续搜索。
由于折半搜索算法每次都把搜索区域减少一半,所以时间复杂度是O(logN),要比朴素算法的O(N)高效许多,这也就是分治策略的优势所在:高效。
分治策略的其他经典例子还有排序算法中的归并排序。归并排序的思路是将待排序的元素分成大致相同的两个子集合,分别对两个子集合进行排序,最终将排序的子集合合并成排好序的集合。
分治所能解决的问题一般具有以下特征:
另外如果每个子问题之间不是独立的,那么就要重复地求解公共的子问题,此时更适合用我们后面会讲到的动态规划算法。
10. 穷举算法 \ 搜索算法
穷举法,又称枚举法,是指从可能的解的集合中一一枚举各个元素,用给定的检验条件判定哪些是无用的,哪些是有用的。能使命题成立即为其解。
穷举法本质上属于搜索算法,但它与搜索有所不同,因为适用于枚举法求解的问题必须满足:可预先确定解的数量;预先确定解变量的取值范围。
穷举算法的关键,首先是确定循环的范围,其次是找出判断解的条件。将这两个关键点解决,穷举算法解题是轻而易举的。
搜索算法和穷举法类似,对于那些无法用循环写出的穷举算法,使用递归或队列来实现求解。搜索的过程构成了一颗搜索树,搜索实际上是对搜索树的遍历。
搜索的顺序分为两种:深度优先搜索(DFS)和广度优先搜索(BFS)。其中深度优先搜索是沿着搜索树的深度遍历树的节点,尽可能深地搜索树的分枝。DFS通常用递归的方法实现。
广度优先搜索每次搜索其可以扩展的每一个节点,当一层节点全部搜索完成后,再依次搜索第一个可扩展节点可以扩展的所有节点。
除了搜索的顺序之外,还有搜索的方法,一般分为盲目搜索和启发式搜索。
启发式搜索是在搜索过程中加入了与问题有关的启发式信息,用于指导搜索朝着最有希望的方向前进,扫除不必要的搜索过程,加速问题求解并得到最优解。
启发式搜索的常见算法有A*算法,模拟退火算法、遗传算法等,我们最常用的是A*算法。A*算法最经典案例是八数码问题,状态函数h设置为未到达目标位置的数字的个数。
11. 内存分区
计算机中的内存在用于编程时,被人为的进行了分区(Segment),分为:
-“栈区”(Stack)
-“堆区”(Heap)
-全局区(静态 区,Static)
-文字常量区和程序代码区
在前面的课程中,我们主要直接涉及到的是栈区的内存,在你的程序中,函数的参数值,局部变量的值等都被存在 了“栈区”,这部分的内存,是由系统来帮助你来管理的,没有特殊情况的时候,你是不需要对其进行特别处理的。计算机中内存的分配如下图。
 而针对堆区的内存,一般由程序员进行分配和释放, 使用堆内存的原因一般是
   而针对堆区的内存,一般由程序员进行分配和释放, 使用堆内存的原因一般是
-“栈上内存比较小,不够用”
-“系统管理内存的方式死板,不方便用”
对于堆上的内存,被程序员手动分配后,若程序员 不释放就可能会出现“内存泄漏”。很多企业级的应用,都因为内存泄漏而在“正常”运转很长时间后,轰然“坍塌”。在后面的入门课程中,我们会简单的对这块 的知识进行介绍。
全局区、文字常量区和程序代码区在我们入门阶段,暂时还可以不去过多理解(甚至看不懂也无妨),只需要知道他们的大致作用即可——全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 程序结束后由系统释放;文字常量区是用于储存常量字符串的, 程序结束后由系统释放;程序代码区用于存放函数体的二进制代码。
12. 动态内存分配
i, 申请单个对象
int *p;
p = new int;
ii, 或者你还希望直接在申请的堆内存里直接包含值,比方说一个整数100,你可以写成
int *p;
p = new int();
iii, 动态申请数组
int *p;
p = new int[n];
这样对于一个已经申明的变量n可以申请长度为n的动态数组,就和前面课程学习过的一样;但是这里不能进行初始化。
在这里,请注意一下new后类型后,一个值在圆括号和方括号里的区别。圆括号里值是用来赋初值的,方括号里是用来说明申请堆空间的大小的。
参考文献 “计蒜客” http://www.jisuanke.com/course
ACM札记的更多相关文章
- SCNU ACM 2016新生赛决赛 解题报告
		新生初赛题目.解题思路.参考代码一览 A. 拒绝虐狗 Problem Description CZJ 去排队打饭的时候看到前面有几对情侣秀恩爱,作为单身狗的 CZJ 表示很难受. 现在给出一个字符串代 ... 
- SCNU ACM 2016新生赛初赛 解题报告
		新生初赛题目.解题思路.参考代码一览 1001. 无聊的日常 Problem Description 两位小朋友小A和小B无聊时玩了个游戏,在限定时间内说出一排数字,那边说出的数大就赢,你的工作是帮他 ... 
- acm结束了
		最后一场比赛打完了.之前为了记录一些题目,开了这个博客,现在结束了acm,这个博客之后也不再更新了. 大家继续加油! 
- 关于ACM的总结
		看了不少大神的退役帖,今天终于要本弱装一波逼祭奠一下我关于ACM的回忆. 从大二上开始接触到大三下结束,接近两年的时间,对于大神们来说两年的确算不上时间,然而对于本弱来说就是大学的一半时光.大一的懵懂 ... 
- 第一届山东省ACM——Phone Number(java)
		Description We know that if a phone number A is another phone number B’s prefix, B is not able to be ... 
- 第一届山东省ACM——Balloons(java)
		Description Both Saya and Kudo like balloons. One day, they heard that in the central park, there wi ... 
- ACM之鸡血篇
		一匹黑马的诞生 故事还要从南京现场赛讲起,话说这次现场赛,各路ACM英雄豪杰齐聚南京,为争取亚洲总舵南京分舵舵主之职位,都使出了看 家本领,其中有最有实力的有京城两大帮清华帮,北大帮,南郡三大派上交派 ... 
- 【codeforces 415D】Mashmokh and ACM(普通dp)
		[codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=200 ... 
- acm 1002 算法设计
		最近突然想往算法方向走走,做了做航电acm的几道题 二话不说,开始 航电acm 1002 题主要是处理长数据的问题,算法原理比较简单,就是用字符数组代替int,因为int太短需要处理的数据较长 下面是 ... 
随机推荐
- Nginx或Apache通过反向代理配置wss服务
			nginx配置参考 前提条件及准备工作: 1.假设ws服务监听的是8282端口(websocket协议) 2.已经申请了证书(pem/crt文件及key文件)放在了/etc/nginx/conf.d/ ... 
- iOS - (多图上传已封装)
			/*** 上传带图片的内容,允许多张图片上传(URL)POST** @param url 网络请求地址* @param images ... 
- Jenkins自动化构建(一)执行selenium+python脚本
			Jenkins执行python写的selenium自动化脚本,通常会遇到,执行打不开浏览器,查看jenkins构建Console Output控制台输出信息,发现脚本是执行了的,但是出错了,打开浏览器 ... 
- WebSocket.之.基础入门-后端响应消息
			WebSocket.之.基础入门-后端响应消息 在<WebSocket.之.基础入门-前端发送消息>的代码基础之上,进行添加代码.代码只改动了:TestSocket.java 和 inde ... 
- Ubuntu 16.04卸载一些不必要的预装软件
			卸载libreoffices ~$ sudo apt-get remove libreoffice-common 卸载Amazon的链接 ~$ sudo apt-get remove unity-we ... 
- jdbc连接oracle时使用的字符串格式
			两种方式: SID的方式: jdbc:oracle:thin:@[HOST][:PORT]:SID SERVICE_NAME的方式: jdbc:oracle:thin:@//[HOST][:PORT] ... 
- <7>Lua类的表的实例创建
			根据上一节知识所述Lua中没有像C.C++.JAVA中的类概念,面向对象等 ,但我们可以模拟出来 如下 代码如下: --创建类的表 local Person = {} function Person: ... 
- <6>Lua元表和冒号 self
			Lua中没有像C.C++.JAVA中的类概念,面向对象等 ,但我们可以模拟出来 1. Lua中有个很重要的概念元表 设置元表setmetatable()函数 获取元表getmetatable()函数 ... 
- 关于poi导出excel方式HSSFWorkbook(xls).XSSFWorkbook(xlsx).SXSSFWorkbook.csv的总结
			1.HSSFWorkbook(xls) import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermo ... 
- Spark学习之路 (十五)SparkCore的源码解读(一)启动脚本
			一.启动脚本分析 独立部署模式下,主要由master和slaves组成,master可以利用zk实现高可用性,其driver,work,app等信息可以持久化到zk上:slaves由一台至多台主机构成 ... 
