算法入门(C++)

iostream,这个头文件里有很多常用的函数,比如swap交换两个变量的值,max求两个值的最大值等。

cstdio头文件,这个头文件里包含C风格的输入输出。如果你之前学习过C++语言应该知道cin读入和cout输出的方法。那么我们为什么还要用C的scanf和printf呢?因为scanf和printf要比cin和cout的效率高得多。

using namespace std 如果没这行的话,swap就要写成std::swap,代码写起来会麻烦些。

main函数它的返回值是int类型的。那么它到底返回的值是干什么的呢? 它是用来标记程序是否正确无错误返回的,在执行编译好的程序的时候会获得这个返回值。返回0意味着程序无错误退出。

输入格式: 每组数据第一行输入一个数N,表示一共有多少个正方形; 第二行输入N个正整数,表示每个正方形的边长。 如果N=0则输入结束。

输出格式: 每组输出一个值,表示该组所有正方形的总面积。

while (scanf("%d",&n),n)循环读入n,直到n为0时退出循环。这种输入格式在算法题目中非常常见。逗号表达式,整个表达式的结果就是用逗号分隔的最后一个表达式的值。当n的值为0时,整个表达式的值就是0,此时退出循环。

只引用一个头文件#include <bits/stdc++.h>而无需引用两个头文件。这种并不是所有平台都适用的,用之前记得查阅平台的FAQ。

输入要抄的原文内容,可能有的读者会想写scanf("%s", str);但在这里是行不通的,因为文章的内部会有空格,而这样的语句只能把空格之前的内容读入到str。因此我们要使用读取一整行的函数,如下:gets(str);多提醒一句,使用gets的时候如果发生溢出的话程序是不会报错的,所以在使用gets的时候一定要小心!

scanf函数的返回值:当scanf正确读入时,返回值是和读取的变量数目相等的。而当读取出错、读到文件末尾时,scanf函数会返回-1.while (scanf("%d", &cnt) != -1)

输入数据的范围最大是10000,10000的立方是10^12,而int类型的最大值是2147483647,大约是2*10^9,远远超过了int的最大值,这样在计算过程中就会出现溢出的情况,导致结果错误。因此我们需要用更大的整数类型long long,它的最大值大约为10^19,即使10000个10^12也不会超过long long的取值范围。

程序设计竞赛,顾名思义就是写代码的比赛。现在的程序设计竞赛有解题竞赛、性能竞赛、创意竞赛等各式各样的比赛。

ACM-ICPC,即国际大学生程序设计竞赛,是由美国计算机协会(ACM)主办的面向全球大学生的规模最大的程序设计竞赛。竞赛由三人组队,在5小时内完成8-12道题目,按照通过题目的数量和解决问题的累计时间综合排序决定最终名次。每通过一道题目会发给队伍一个气球。ACM-ICPC(简称为ACM)竞赛由区域赛和总决赛组成,其中区域赛由网络预赛和现场赛组成。网络预赛获得靠前名次的学校可以获得现场赛的名额,通常 每个学校会有1-3个名额,和学校的历史成绩、当场网络赛排名等有关。目前大陆地区的现场赛前15名队伍获得金牌,第16-45名获得银牌,前60%的余 下队伍获得铜牌。其中获得金牌名次靠前的学校可以代表中国大陆参加世界总决赛。世界总决赛共有4枚金牌,4枚银牌和4枚铜牌。大陆的队伍在总决赛的历史成绩出色,其中上海交通大学获得过3次冠军,浙江大学获得过1次冠军。

Topcoder(topcoder.com)是一个举办在线编程比赛的网站,上面有很多比赛类型,常见的有SRM(Single Round Match),Marathon(持续时间很长、且只有一道题,没有固定解的题目),TC Open等。我们接下来着重介绍SRM,也就是个人算法编程竞赛。用户需要下载指定的客户端(Arena下载链接) 才能参加SRM比赛,Topcoder也是唯一一个必须下载客户端才能参加的程序设计竞赛。用户在Topcoder会有积分(rating)和积分对应的 颜色标示,如上图中所示,红>黄>蓝>绿>灰>白。积分最高的几个选手的id左侧会有一个类似靶心的标志,我们称之为 target。ACRush(楼天城)就是target选手之一。

Topcoder(SRM) 每场比赛会按照用户赛前的rating将选手分为div1和div2各自比赛。比赛分为coding阶段、challenge阶段和system test阶段。每个division会有几十个room,每个room内的选手在challenge阶段可以互相查看对方代码,发现错误后可以提交测试数 据进行挑战,挑战成功(对方程序计算结果与正确输出不一致)后可加分,失败则会扣分。这也就是大家口中常说的"cha人",非常刺激。Arena的有趣之处还在于可以安装各式各样的插件(插件列表),这里推荐给你一个大家最常用的插件:ExampleBuilder,它的文档连接在这里。使用这个插件之后能够非常迅速的在本地编写、调试代码。

Google Code Jam(code.google.com/codejam)是谷歌举办的每年一次的世界规模的程序设计竞赛,参赛者要在2-3小时内解决大约4道题。从在线的几轮比赛中胜出后就能够参加现场(Onsite)总决赛。该赛事的特点是每道题都备有Small和Large两组输入数据。即便是难度系数较大的问题,只要输入规模足够小,依然可以简单地求解。另外Google-Code-Jam(通常简称为GCJ)并不在服务器上自动执行程序,而是要求将源代码和本地执行的结果一同提交。

在ACM竞赛的队伍中,队员的角色一般可分为队长、解题核心以及辅助等;比赛中需要完成的任务一般可分为读题、准备、编程和查错等。队长主要工作是统筹规划,制定队伍的计划并作出决策,包括比赛场上以及场下的训练。一个优秀的辅助对队伍起着非常重要的作用,稳定的查错能力、出色的出数据能力、细致的读题能力能够让团队的实力提升好几个档次。队友之间的互相了解是一切的基础。队友之间要清楚地知道擅长什么,不擅长什么,将每道题分配给最适合的人做。良好的配合基于队友之间的相互信任,并且队员之间能够准确地向队友表达自己的意思。这些可以通过训练慢慢培养。

IDE(Integegrated Development Environment),中文翻译为集成开发环境,对于ACM初学者来说使用IDE要比使用一个编辑器再使用编译器进行编译方便的多。ACM竞赛中常用的语言为C/C++或Java。C/C++最常用的IDE是CodeBlocks,Java最常用的IDE为Eclipse。需要注意的是下载Windows版本的Codeblocks一定要下载带mingw的,否则需要自己配置C++的编译器,对于初学者来说可能会比较麻烦。 mingw是Minimalist GNU on Windows的缩写,顾名思义是运行在Windows上的GNU库,用来编译C/C++代码。

在 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或在比赛现场咨询裁判获知。

网上有一些被称为Online Judge(简称OJ)的系统,他们能够自动评测以往程序设计竞赛中的算法题目,在OJ上可以进行练习。此外一些OJ也会定期举办自己的比赛,不妨经常参加一下。

输入格式:依次读入数据,直到文件结束。那么这种输入要怎么处理呢?下面我来给出各个语言的读入方法。

首先是C/C++:while(scanf("%d",&n) != -1){}   或  while(cin >> n){}

Java:Scanner cin = new Scanner(System.in);  while(cin.hasNext()){}

Python:for line in stdin:

Codechef(codechef.com)是印度人创办的OJ,有两种比赛形式,一种是Challenge,持续10天;一种是lunchtime,持续3小时。

Codeforces(codeforces.com)是俄罗斯创办的OJ,会定期举办算法比赛,比赛分为div1和div2,有一套积分和颜色系统,红色最高,红名用户拥有很多特权。

HDU(acm.hdu.edu.cn)是杭州电子科技大学维护的OJ,每年暑期会组织大批高校进行ACM训练,称为多校联合训练,是国内规模最大的ACM校际训练。

什么是代码能力?简单地说,如果你觉得学会了某一个算法或者数据结构,你能否在半个小时(或一小时)内完成程序,并且经过很少的调试一次通过?如果做不到
的话,只能说你还没彻底掌握这个算法或数据结构,要不断地训练,直到达到要求,只有这样才能保证在高度紧张的比赛中敢于实现而不犯错误。

写代码不是在解题,而是实现早已在脑子里准备好的一个逻辑流程。

在设计满足问题要求的算法时,复杂度的估算是非常重要的。我们不可能把每个想到的算法都去实现一遍看看是否足够快。应当通过估算算法的复杂度来判断所想的算法是否足够应付题目给出的数据规模。复杂度分为时间复杂度和空间复杂度。通俗一点说,就是『跑多快』和『占多大内存』。在分析复杂度时,我们通常考虑它与什么成正比,并称之为算法的阶。比如程序执行了一个四重循环,每重循环执行n次,那么运行时间就和n4成正比。我们将与n4成正比写作O(n4)。再比如程序开辟了一个二维数组,下标范围是[0..n-1][0..n-1],那么程序的空间复杂度就是O(n2)。程序的运行时间不仅取决于时间复杂度,也会受计算复杂度、递归等因素的影响,但因此造成的差距最多也就是几倍。估算一个复杂度是否能承受目前的数据规模时,就将数值可能的最大值待遇复杂度的渐进式中,就能简单的判断算法是否能够满足运行时间限制的要求。比如O(n2)的算法,将n=1000代入得到1000000。通常来讲按照上述方法计算得到108基本是1s时限的最大值。当数组长度为N时,二分查找的时间复杂度为O(lgN),把时间复杂度中的一个N优化到lgN是很常用的策略。同一道题的不同解法,即使时间复杂度相同也有可能运行时间差出很多倍,因此对于代码细节的效率优化也同样重要,尤其是重复计算的化简。

分治,即“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。总结起来就是:分解、解决、合并,这三大步。分治策略最经典的一个例子就是折半搜索算法,也就是二分查找。二分查找是在有序数组中查找某一特定元素的搜索算法。搜索过程中从数组的中间元素开始,判断待查元素和中间元素的关系,来判断接下来是选择哪一半继续搜索。由于折半搜索算法每次都把搜索区域减少一半,所以时间复杂度是O(logN),要比朴素算法的O(N)高效许多,这也就是分治策略的优势所在:高效。分治策略的其他经典例子还有排序算法中的归并排序。归并排序的思路是将待排序的元素分成大致相同的两个子集合,分别对两个子集合进行排序,最终将排序的子集合合并成排好序的集合。分治所能解决的问题一般具有以下特征:问题的规模缩小到一定程度就可以轻松解决;问题可以分解为若干个规模较小的相同子问题;分解出的多个子问题的解可以合并为原问题的解。另外如果每个子问题之间不是独立的,那么就要重复地求解公共的子问题,此时更适合用我们后面会讲到的动态规划算法。

Codeforces(codeforces.com)是俄罗斯创办的OJ,会定期举办算法比赛,比赛分为div1和div2,有一套积分和颜色系统,红色最高,红名用户拥有很多特权。

时间: 2024-08-03 15:21:28

算法入门(C++)的相关文章

第二章 算法入门 合并排序

在第二章中难的算法不多,接下来我会把稍微复杂一点的算法整理一下 #include <iostream> using namespace std; void mergeSort(int *A,int left,int mid,int right) { int *L=new int[mid-left+1]; int *R=new int[right-mid+1]; int i,j; for(i=0;i<mid-left+1;i++) { L[i]=A[left+i]; } for (j=0;

算法入门心得

最近看了刘汝佳写的算法入门经典  感觉自己的基础实在太烂了  所以总结了一些我们比较容易犯的错误给大家看看(大牛就不要看了O(∩_∩)O) 1.浮点数:两个整数计算的是浮点数的时候一定要把整数先化为浮点数  5-0.1计算机先把5变5.0之后再进行计算的 2.异或运算:这个是个很神秘的东西如果要在一个数组中找一个只有一个的数那么就可以用异或了 异或也可以用在两个数的交换a = a^b; b = a ^ b; a = a ^ b;就实现转换了 自己异或自己等于0: 3.逻辑运算符都是短路运算符a|

Cordic 算法入门

三角函数计算,Cordic 算法入门 三角函数的计算是个复杂的主题,有计算机之前,人们通常通过查找三角函数表来计算任意角度的三角函数的值.这种表格在人们刚刚产生三角函数的概念的时候就已经有了,它们通常是通过从已知值(比如sin(π/2)=1)开始并重复应用半角和和差公式而生成. 现在有了计算机,三角函数表便推出了历史的舞台.但是像我这样的喜欢刨根问底的人,不禁要问计算机又是如何计算三角函数值的呢.最容易想到的办法就是利用级数展开,比如泰勒级数来逼近三角函数,只要项数取得足够多就能以任意的精度来逼

算法入门经典第六章 例题6-14 Abbott的复仇(Abbott&#39;s Revenge)BFS算法实现

Sample Input 3 1 N 3 3 1 1 WL NR * 1 2 WLF NR ER * 1 3 NL ER * 2 1 SL WR NF * 2 2 SL WF ELF * 2 3 SFR EL * 0 Sample Output (3,1) (2,1) (1,1) (1,2) (2,2) (2,3) (1,3) (1,2) (1,1) (2,1) (2,2) (1,2) (1,3) (2,3) (3,3) 析 题目的大意是,输入起点,离开起点时的朝向和终点,求一条最短路. 每一个

写给嵌入式程序员的循环冗余校验(CRC)算法入门引导

写给嵌入式程序员的循环冗余校验(CRC)算法入门引导 http://blog.csdn.net/liyuanbhu/article/details/7882789 前言 CRC校验(循环冗余校验)是数据通讯中最常采用的校验方式.在嵌入式软件开发中,经常要用到CRC 算法对各种数据进行校验.因此,掌握基本的CRC算法应是嵌入式程序员的基本技能.可是,我认识的嵌入式程序员中能真正掌握CRC算法的人却很少,平常在项目中见到的CRC的代码多数都是那种效率非常低下的实现方式. 其实,在网上有一篇介绍CRC

算法导论(Introduction to Algorithms )— 第二章 算法入门 — 2.1 插入排序

一.插入排序:INSERTION-SORT 1.适用范围: which is an efficient algorithm for sorting a small number of elements. 对于少量元素的排序,插入排序是一种高效的算法. 2.原理: Insertion sort works the way many people sort a hand of playing cards. We start with an empty left hand and the cards

算法入门之快速排序

快速排序原理: 快速排序先把等待排序的集合打乱顺序,把第一个元素作为基准元素,为第二个元素和最后一个元素分配两个指针i和j,如果a[i]小于基准元素则i++,如果a[j]大于基准元素则j--,这样把大于基准元素的a[i]和小于基准元素的a[j]互换,以此类推,最终把基准元素与a[j]相交换,就得到一个a[j]左侧全部小于a[j],右侧全部大于a[j]的一个近似有序数组,然后按照如上步骤重新寻找每个被a[j]分开的数组中的分隔点,最终得到有序数组. 在通用排序中,一般都会选取快速排序来解决问题.

【转】循环冗余校验(CRC)算法入门引导

原文地址:循环冗余校验(CRC)算法入门引导 参考地址:https://en.wikipedia.org/wiki/Computation_of_cyclic_redundancy_checks#References  给出了CRC 计算的详细信息.想要深入学习,可以从这个网址开始.尤其是最后给出的 Reference 各个是精品 http://www.zorc.breitbandkatze.de/crc.html 是个非常有用的网站,文中给出的代码都与那里的结果进行了对比 写给嵌入式程序员的循

算法入门——递推

主要思想: 通过已知的条件(已知结果),利用特定的关系,逐步递推(顺推/逆推),直到有解或者无解. 主要分为两种:顺推,从已知条件出发,直至推出解. 逆推,从已知结果出发,直至推出解. 需要注意的:每一递推结果,都是下一步递推的条件. 顺推: 斐波那契数列  F0=0,F1=1,Fn=F(n-1)+F(n-2)(n>=2,n∈N*) 实例 兔子的总数有多少? 一对兔子,每月能生一对,而每对兔子3个月后可以生育.求12个月后共有多少兔子. #include<stdio.h> #define

POJ-1061 青蛙的约会-数论扩展欧几里德算法入门及推导

Description 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置.不过青蛙们都是很乐观的,它们觉得只要一直朝着某个方向跳下去,总能碰到对方的.但是除非这两只青蛙在同一时间跳到同一点上,不然是永远都不可能碰面的.为了帮助这两只乐观的青蛙,你被要求写一个程序来判断这两只青蛙是否能够碰面,会在什么时候碰面. 我们把这