您的位置:首页 > 其它

基础 2016.4.16

2016-04-15 23:37 295 查看

1、大O记号(big‐O notation)

性质: 常系数可忽略:O(f(n)) = O(c × f(n))

低次项可忽略:O(n^a + n^b) = O(n^a), a > b > 0



常数(constant function)

2 = 2010 = 2010*2010 = 20102010 = O(1)

这类算法的效率最高



对数 O(logn):lnn | lgn | log100n | log2010n

常底数无所谓

∀ 常数 a, b > 0,lna / lnb = logab = O(1)

∀ n > 0 都有 logan = logab × logbn = O(logbn),反之亦然

常数次幂无所谓

∀ 常数 c > 0,log(n^c) = c × logn = O(logn)

这类算法非常有效

复杂度无限接近于常数











2、封底估算







3、memset()使用注意

初始化int类型的数组

只能初始化为 -1 和 0

初始化bool类型的数组

只能初始化为 false 和true

初始化char类型的数组

可初始化为任意的ASCII码字符

4、数据类型的取值范围

int -2147483648~2147483647 (-2e+9 ~ 2e+9)

unsigned int 0~4294967295 (0 ~ 4e+9)

long long

-9223372036854775808 ~ 9223372036854775807 (-9e+18 ~ 9e+18)

unsigned long long 0 ~ 18446744073709551615 (0 ~ 1e+19)

__int64

-9223372036854775808 ~ 9223372036854775807 (-9e+18 ~ 9e+18)

unsigned __int64 0 ~ 18446744073709551615 (0 ~ 1e+19)

__int64与long long 都是在32位平台开始使用的64位整数的数据类型,在存储方式和使用方式上没有区别

两者的区别在于,它们命名的发起人不同,支持的平台不同

long long这个数据类型,是UNIX平台发起并支持的

而__int64是微软从win95(VC6)开始发起并支持的

在老的windows开发平台下(如VC6),不识别long long

而老的UNIX,也不识别_int64

当然,现在比较新的平台,两种数据格式和相关的定义、函数都可以兼容了

同样,作为64位整数的printf输出格式定义,也是一样

微软使用的是%I64d

而UNIX使用的是%lld以及%llu(无符号64位)等形式

实际上,无论哪一种,在实际效果上没有不同,只是因为定义者和使用环境造成的支持或不支持的问题

float

只能提供6~7位有效数字

占4字节(32位)内存空间,其数值范围为 |3.4e-38| ~ |3.4e+38|

double

精确度比float高,可提供15~16位有效数字

占8 个字节(64位)内存空间,其数值范围为 |1.7e-308| ~ |1.7e+308|

5、输入输出

请使用 scanf 和 printf 来代替 cin 和 cout,某些情况下后者效率远远远远低于前者

scanf(“ %s%s”,str1,str2),在多个字符串之间用一个或多个空格分隔

若使用gets函数,应为gets(str1); gets(str2);

字符串之间用回车符作分隔

通常情况下,接受短字符用scanf函数,接受长字符用gets函数

而getchar函数每次只接受一个字符,经常c=getchar()这样来使用

6、Runtime Error

Runtime Error 是指程序在运行过程中出现了问题

通常是内存访问的问题,比如数组下标越界

一般这些问题在小规模测试的时候不会发现,而在 OJ 上大规模数据测试时候就容易暴露出来,所以请自行构造一些数据来调试程序

此外,需要注意的是, main

函数必须以 return 0;结束,如果返回值非 0,也会被认为是 Runtime Error

常见的是除 0 错误 和 内存访问错误

七、常用库函数

(1)qsort

Syntax:

#include <stdlib.h>
void qsort( void *buf, size_t num, size_t size, int (*compare)(const void *, const void *) );


The qsort() function sorts buf (which contains num items, each of size size) using Quicksort.

The compare function is used to compare the items in buf.

compare should return negative if the first argument is less than the second

zero if they are equal

and positive if the first argument is greater than the second.

qsort() sorts buf in ascending order.

Example code:

For example, the following bit of code uses qsort() to sort an array of integers:

int compare_ints( const void* a, const void* b ) {
int* arg1 = (int*) a;
int* arg2 = (int*) b;
if( *arg1 < *arg2 ) return -1;
else if( *arg1 == *arg2 ) return 0;
else return 1;
}

int array[] = { -2, 99, 0, -743, 2, 3, 4 };
int array_size = 7;

printf( "Before sorting: " );
for( int i = 0; i < array_size; i++ ) {
printf( "%d ", array[i] );
}
printf( "\n" );

qsort( array, array_size, sizeof(int), compare_ints );

printf( "After sorting: " );
for( int i = 0; i < array_size; i++ ) {
printf( "%d ", array[i] );
}
printf( "\n" );


When run, this code displays the following output:

Before sorting: -2 99 0 -743 2 3 4
After sorting: -743 -2 0 2 3 4 99


八、转载一位过来人的忠告

学习方式

练习->总结->练习->总结->……

1、用模板是不好的

现在很多我们弱校的ACM-ICPC选手比较依赖模板

说实话,我也很依赖,但是我起码知道一点,这样是不对的

某种意义上说,这是你没有把算法学明白的一种表现。而且也严重影响编码速度

在我见过的huicpc035参加过的比赛中,他从来没有看过模板,全部现场敲,有一次比赛有个图强连通分量+缩点+染色+什么的题去了,我在他们机房做,我则抄模板,结果总共敲了1个半小时,而035明确算法之后,啪啦啪啦,估计30多分钟就敲完了

我觉得他敲代码的时间没有浪费,某牛曾说:因为每次敲都有可能有不同的错误,所以不用模板是好习惯

我最开始学dancing link的的时候,自己敲出了代码,然后接下来的几道题部分参考了以前的代码,后来基本上是直接copy

现在,当别人问我dancing link算法或有关的题目的时候,我已经是一脸茫然。

所以,用模板是不好的,有时候由于某些原因可能你用了模板,但你起码要知道这要做是不对的,并且有机会要改正

2、需要深入学习

像 ACRush、zzy、ahyangyi…等等国家队的天才们,本身难以说我们与他们之间有什么可比性

但是他们的学习方法应该还是值得借鉴的,他们的学习方法当然我们得不到言传身教,但是从他们在国家队集训的论文中和他们搞完ACM-ICPC以后的轨迹中,可以有所体现。那就是:深入学习。

其实这点我来讲可能还是不够有力,因为我这方面也很欠缺,我尽量说下我的想法。

首先,觉得ACMer学算法不应停留在看看代码实现这个层面,在算法思想上要有清醒的认识,在正确性分析上要也应该要有较好的逻辑。因为网上的代码的实现上的一些细枝末节很可能掩盖了算法本身有的简洁性、美感和思想。因而丧失了对算法整体上的一些认识。还拿dijkstra算法打比方,有些算法不是基于 dijskstra的直接建模,而是需要你修改这个算法,这时你对算法没有真正理解的话,也就一筹莫展了。

我为什么老说Dijkstra算法,因为确实很多人都只知道用模板,而且模板还不好,在我看到的Dijkstra实现中,只有czyuan_acm的代码写得好。不是说其他的不对,但确实是有问题,投机取巧了的。

所以,要阅读论文和书籍,尤其与英文书籍,窥到它的本质。另一方面,只有这样,你学的的东西才能在ACM-ICPC以外,给你一定的启发——否则你会迅速忘掉它的。

据我所知,035起码阅读了几十篇集训队论文,orzorzorz,而且切掉了例题

3、独立思考

这点我也很惭愧,因为我也是缺乏独立思考的

很多题我不会了就去搜解题报告,所以反而我的搜资料能力变得特别强

许多大牛在这点上做的比我好多了

他们遇到题不会的时候,也不会很急于把题目做出来

可能每隔一段时间又拿出来想一次,总有一天想通了

之后这一类型的题目基本上也就没有什么问题了

而我恰恰比较“虚荣”,做到的题目不会不太愿意想太久,就想尽量快些AC

于是急于看解题报告,这样导致的一个问题就是有些重要的东西解题报告中没有提到,而我也没去想就把他们忽略了,这样,我还是不会做

讨论问题的时候,我不会一般就直接找他要代码,但是他不懂的时候,顶多问我大体的思路,而绝对不会要代码的

在去年ACM赛区尾声的时候,我发现他做中难题的能力已经明显超过我一个档次

看他现在做的题目,已然是相当变态,几乎是都100以下人ac,这些题目我看了基本上没什么想法,更要命的时,解题报告也搜不到

4、做有意义的题

1.是不要做水题,这里的水题定义为:一眼就能看出做法,而且中途的实现可以预计没有太多问题的题目

2.是做能够强化你最近学到的东西的题目

3.你不会但你应该会的题目

这同时也是在说,某些没太多代表性的题目可以少做,因为对比赛帮助不大

(当然我这个参加比赛的目的很功利,非功利主义者另当别论)

刚才,我把我在poj上的号和他的号对比了下,他ac而我没ac的基本上是难题,我ac他没ac的一般是水题,看得我想哭,5555

补充一点:

ac的人多的并不一定代表着水题,有些几千人ac的题目,在现场赛中ac的人很少,这样的题目往往是有一定思维难度且编码不难的好题

这种题目要认真做

某个学长说:经典的题目啊,只有那么多,做一道,就少一道

5、估算好某种训练所需要的时间

我觉得我学网络流就是一个例子,我在大概赛区赛之前2个月开始学习网络流,1个月前开始学习费用流,但是对于我来讲,这两个月培养出来的网络流思维还是不够(虽然也做了不少题),特别是,这种题目往往作为中难的题目出现,不会让你随便水的,于是,北京赛区的那道网络流当时就没有想出来——功利地说,学习网络流没有得到好的效果。

所以,现在来看,当时其实我可以不搞网络流。如果要学一种比较有难度的东西,并且还必须把他搞好,应该较早地,全面地学习,必须长期的训练以培养这种思维。打个比方,如果你微积分平时不学,仅仅考试前一周狂做题目,我觉得上90分是很困难的。

当然,这要根据个人情况而定,我的理解能力应该说是中等水平,如果牛的话应该可以更快地学好。

6、有关训练的度

我有时候通宵刷体,这里我不知道huicpc035有没有这个习惯,不过我通宵的时候没见到他通宵。

我觉得其实通宵刷体,或者太长时间地做题,还是不好的。我们为什么会这样有热情的做题呢,因为我们有兴趣;但是一个人的成功不仅仅依赖于兴趣,还要依赖于自控。这和打游戏是一个道理,游戏太有趣以至于我们常常通宵——ICPC题目也太有趣,所以有时候通宵。而且很多时候是,由于一道题AC不掉,所以赌气一定要搞定才睡觉,这样一不小心,就通宵了。

其实我明白,通宵不一定效果好,这仅仅说明了你兴趣很高涨而已。通宵往往会打乱你的时间安排,打乱你的生物钟,进而影响你短期或是中期的训练计划。而且,疲惫的状态下做题,你往往只有ac题目的欲望,而完全丧失了ac题目的灵气。所以,我建议,ACMer一定要合理安排作息,能够自控,这样不仅仅对你做 ACM-ICPC有好处。

总之,有效训练是很重要,只有通过有效的训练你才能获得你参加这个比赛应得的东西。

还有就是,除了035以外,另一个值得大家学习的就是richardxx——我也很佩服,我并不觉得他是天才,我觉得他以全方位的努力让他自己变得优秀,大家看他的blog可以看到他的学习历程

最后要说下刻苦训练这一点,这个我主要想说给我们学校的acm队员:

客观的说,我们学校很多名校落榜生(我相比而言是水进的)

确实都蛮聪明的,但再聪明也比不上ACRush吧?

人家可是SGU都切满了!

ACM不是智力测试,不是你什么都不做就可以天上掉馅饼的

当然我不是说题目一定要做多少多少道,但如果你觉得你可以一心二用,从概率上来讲,你百分之九十地错了,我是个工科生,我相信概率而非奇迹

我觉得035这方面也是值得我们学习的,我比较喜欢扯淡,有时候聊题目的时候也经常不小心就去扯其他话题去了

在学习的时候,035是坚决不多聊乱七八糟的东西的,除了讨论上QQ,平时据我观察都是残酷地训练

现在回想起来,我有点后悔,QQ上和网上花掉的时间用来学习新的东西,也许结果会更好

ACM-ICPC绝不是大学生活的全部,也不是搞算法的全部

你大可以花时间去做其他研究,做项目

(我更欣赏那些对人生和职业有良好规划的ACMer)

但是

如果你搞ICPC的那段时间你不是全部投入,那的在ACM-ICPC生涯中,将只有后悔
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: