
C/C++基础及竞赛入门
精炼的讲解了C/C++语言的语法知识,编程解题的常用方法和基础算法
甜橘L
这个作者很懒,什么都没留下…
展开
-
5.6前缀和数组
类似地,易知s[r2][c1-1]、s[r1-1][c2]和s[r1-1][c1-1]的含义。s[r2][c2]减去s[r2][c1-1]、s[r1-1][c2]这两项后,,即s[i][j] = a[1][j] + …求s[i][j]的递推公式为:s[i][j-1]=s[i][j-1]+a[i][j]。其中s[i][j-1]为s[i][j]左边的元素,如图(b)所示;s[i-1][j]为s[i][j]正上方的元素,如图(c)所示;,就是s[i-1][j-1],如图(d)所示,,得到的结果就是s[i][j]原创 2024-03-03 21:53:45 · 373 阅读 · 0 评论 -
案例五:找零硬币数
按照“总是选取不超过当前差额的最大面值的硬币”贪心策略,如果输入的找零金额M=63,首先应该找一个50分的硬币,然后是一个10分的硬币、一个2分的硬币、一个1分的硬币,使用的硬币数是4。具体解法是:设当前差额为diff(初值为M),在硬币面值方案中找≤diff的最大硬币金额C,用了该硬币后,差额为diff-C;重复这一过程,直至差额diff为0,结束循环。本题本来应该用贪心算法求解,但贪心策略已经给定了,所以本题实际上是一道模拟题。按照题目中给定的贪心策略模拟找零过程,并累计使用的硬币数量即可。原创 2024-03-03 20:10:08 · 415 阅读 · 0 评论 -
4.7函数的设计
只要没有函数调用发生,就不会给形参分配存储空间,所以定义函数时的参数才称为形式参数,简称形参。,这种函数调用形式里有几个参数,分别是什么类型,是以此来确定函数的形参个数和类型;程序设计者希望函数执行以后是否得到一个结果,这个结果是什么类型的,是什么含义,这个结果是否需要返回到主调函数中,以此来确定函数的返回值及其类型含义等。,不明白函数形参的作用是什么,形参的值是在什么时候被“赋予”的。由于函数形参的值是由实参传递过去的,因此,,“函数”这个词的英文名称是“Function”,顾名思义,原创 2024-02-28 23:41:58 · 389 阅读 · 0 评论 -
案例一:特别数的和
用于检查一个数x是否符合题目要求。原创 2024-03-01 00:51:26 · 318 阅读 · 0 评论 -
5.2一维数组的定义与引用
,则这10个元素是:a[0]、a[1]、a[2]、a[3]、a[4]、a[5]、a[6]、a[7]、a[8]、a[9]。注意最后一个元素是a[9],而不是a[10]所谓引用数组元素,通俗的讲,就是使用数组元素。,即常量表达式中可以包括常量、常变量(加了const修饰的变量)和符号常量,但不能包含变量,也就是说,不允许对数组的大小作动态定义,即数组的大小不能依赖于程序运行过程中变量的值。计算出a[i]的地址后就很容易对a[i]进行存取。//a[5]~a[9]的值由编译器自动赋值为0。//输入a数组的长度。原创 2024-03-02 19:46:18 · 527 阅读 · 0 评论 -
案例二:点球大战
如果ta>tb,就假设剩下点球B全部罚进、A全部罚不进,B还是输;或者如果ta<tb,就假设剩下点球A全部罚进、B全部罚不进,A还是输。如果属于这2种情形之一,点球大战就提前结束了,比分锁定为ta:tb。如果点球大战没有结束,这一轮接下来B罚点球,罚中则tb加1;紧接着还是按照上述规侧判断点球大战是否会提前结束。如果能进入第2个阶段,处理就容易得多了,每一轮都是A先罚、B后罚,每一轮结束之后如果比分不同,点球大战就结束了。在第1个阶段的每一轮,A队先罚点球罚中则ta加1;原创 2024-03-03 12:00:18 · 509 阅读 · 0 评论 -
案例四:子弹装箱
此外,以下代码简化了判断和处理逻辑:如果n<=511,则至少有一个不用第10个箱子的解(如果有2个解,该解还要先输出),将n转换成二进制,进而如果n<489处理结束,否则继续处理;注意,10个箱子中的子弹数是固定的,不可能说对某些子弹数,10个箱子中的子弹数是一种方案,而对另一些子弹数n,10个箱子中的子弹数是另一种方案。本题比较麻烦的一点是,前9个二进制位权总和是511,因此第10个箱子就只有489颗子弹,而489不是二进制的位权。,就有两个解:用第10个箱子中的子弹,不用第10个箱子中的子弹。原创 2024-03-03 17:33:40 · 459 阅读 · 1 评论 -
4.5函数的调用
例如,如果main函数调用了mx函数,而mx函数的定义出现在main函数之后,则必须在函数调用语句(如“c=mx(a,b);”)之前对mx函数进行声明,否则会出现编译错误,提示:标识符"mx"未声明。即使写上,甚至声明时的形参名跟定义时的形参名不一致,也是可以的,因为声明时的形参名在编译时是忽略的。函数声明其实就是取了函数定义的第一行,然后加分号。,并不要求函数带回一个值,只是要求函数完成一定的操作。可以放在main函数里,也可以放在main函数之前,在函数调用后面加一个分号,构成一个语句,即。原创 2024-02-28 20:59:23 · 379 阅读 · 0 评论 -
案例四:求最大公约数
在使用上述递归函数gcd求“gcd(33,18)”时,要递归调用“gcd(18,15)”;在执行“gcd(18,15)”时又递归调用“gcd(15,3)”;而在执行“gcd(15,3)”时,因为15%3的结果为0,所以最终求得的最大公约数为3。例如,假设输入的两个正整数为18和33,则m=33,n=18,用辗转相除法求最大公约数的过程如下图所示。②取m对n的余数,即r=m%n,如果的值为0,则此时n的值就是a和b的最大公约数,否则执行第③步;③m=n,n=r,即m的值更新为n的值,而n的值更新为余数。原创 2024-03-02 01:16:10 · 475 阅读 · 0 评论 -
5.5模拟算法
1.模拟方法思想 2.模拟方法实现要点采用模拟思路求解程序设计竞赛题目时,要特别注意以下问题:原创 2024-03-02 21:59:07 · 346 阅读 · 0 评论 -
案例三:成绩分析
将所有得分遍历一遍,分别求最大值,最小值,平均成绩,注意平均分要保留两位小数。原创 2024-03-03 16:16:10 · 396 阅读 · 0 评论 -
案例五:三角形的个数
易知这些多出来的三角形其实就是1+2+3+…+(n-1)=n*(n-1)/2。从n-1层的三角形,在下面增加一层三角形,变成n层的三角形,会多出多少个三角形?根据上述公式,可以推导出求f(n)的公式。,递归函数结束的条件是f(1) = i。所以,本题也可以直接根据上述公式求解。原创 2024-03-02 15:39:36 · 696 阅读 · 0 评论 -
案例二:幸运双十一
计算出每年11月11日的星期数w,如果w为1,则计数。本题需要多次判断一个年份是否为闰年,所以。,即根据公历日期(年、月、日)推算出星期几。:先读入x和y,如果x和y为0,则用break语句退出while循环。比如,可以约定星期一到星期日为1~7。给定公历日期,可以采用。注意,第一次取余运算结果可能为负数,所以加7再取余。每个测试数据为x,y。当x和y为0时,输入结束。,与前面约定的星期数取值范围不一致,所以要。,且从给定日期到基准日期的天数是,则。例如,在本题中,我们可以查一下,原创 2024-03-01 16:38:52 · 389 阅读 · 0 评论 -
4.8递归函数
如果有一个函数f能实现求n的阶乘,其形式为:long long f(int n);时要使用到表达式:n*f(n-1),f(n-1)表示调用f()函数去求(n-1)!在该例子中,求n转换成求(n-1)!,而(n-1)又可以转换成求(n-2)!某些问题的求解可以转换成规模更小的、或者更趋向于求出解的同类子问题的求解,并且从这些。f函数包含了一个if语句,前2个分支判断出特殊情况后,直接返回值,不再递归调用下去。、(n-2)、(n-1)、n累乘起来,是。在上述例子中,f()函数有一个特点,它在。原创 2024-03-01 18:25:02 · 363 阅读 · 0 评论 -
4.9递推和递归
为了求fn,可以转而去求fn-1和fn-2,而求fn-1要转而去求fn-2和fn-3,求fn-2要转而去求fn-3和fn-4。如果有一个函数fun(n)能求出fn,则fun(n)要调用fun(n-1)和fun(n-2)。有些问题,则不得不用数组存储递推出的每一项。:定义一个数组存储求得的每一项,在fun(n)中,先在数组中检查一下第项的值是否已经求由来了,如果已经求出来了,直接返回它的值,没有求出来才会递归求解;比较经典的是Fibonacci数列,f1=f2=1,当n>2时,有fn=fn-1+fn-2。原创 2024-03-01 22:30:18 · 385 阅读 · 0 评论 -
案例一:数列1,2,3,2,3,4前n项和
也代表组的序号假设用变量k表示,组内每个数的序号用变量表示,k和j都从1开始计起,用for循环产生前1000项。最后输入n,累加数组a中前n项的和并输出。(像“排头兵”一样)原创 2024-03-02 21:48:43 · 501 阅读 · 0 评论 -
案例三:验证歌德巴赫猜想
下一步a的值递增2,即a=5,a是质数,而b=n-a=15不是质数,不符合要求。再下一步,a的值再递增2,即a=7,a是质数,而b=n-a=13也是质数,符合要求。如此枚举到n>10为止,如果继续枚举,得到的符合要求的分解形式只是将之前分解形式中a、b的值互换而已,根据样例输出可知,程序不应输出这些分解形式。例如,假设n的为值20,a=3时,a是质数,b=n-a=17,b也为质数,则20=3+17是符合要求的分解形式。,因为如果a的值为2,则b的值为大于2的偶数,不可能是质数;原创 2024-03-01 17:17:33 · 419 阅读 · 0 评论 -
4.6函数的嵌套调用
例如,图(a)中有3个函数,其中main函数调用了f1函数,而f1函数又调用了f2函数。整个嵌套调用的执行过程如图(b)所示。,即被调函数又作为主调函数去调用其他函数这种多层函数调用称为。原创 2024-02-28 21:48:33 · 392 阅读 · 0 评论 -
5.3二维数组的定义和引用
如果a[0][0]的地址是2000(十进制),则a[0][1]的地址是2004,…,最后一个元素a[2][3]的地址是2044。//a[0][2]、a[1][1]、a[1][2]由编译器自动赋值为0。对数组a,一共有3×4=12个元素,其中第0行的4个元素是:a[0][0]、a[0][1]、a[0][2]、a[0][3]这样该数组一共有3行,即上述语句等效于:int a[3][3]={1,2,3,4,5,6,7,8};例如:int a[ ][3]={1,2,3,4,5,6,7,8};原创 2024-03-02 20:38:54 · 1062 阅读 · 0 评论 -
5.1数组和元素
如果程序中有若干个数据,我们通常需要为每个数据定义变量。在定义数组时必须指定数组的类型,与普通变量的定义类似。③在C/C++中用方括号来表示下标,并且。数组中每个数据称为数组的元素。原创 2024-03-02 18:58:06 · 387 阅读 · 0 评论 -
5.4数组名作函数参数
注意,形参数组名实际上是一个指针变量,只是用a[ ]这样的形式表示a是一维数组名,以接收实参传来的地址。因此a[ ]中方括号内的数值并无实际作用,编译器对一维数组方括号内的内容不予处理。形参一维数组的声明中可以写元素个数,也可以不写。C/C++实际上只把形参数组名作为一个指针变量来处理,用来接收从实参传过来的地址。因此,假设函数的第一个形参为数组形式,则函数的原型有以下几种写法,作用相同。除了常量、变量、表达式等可以作函数实参外,原创 2024-03-02 21:05:16 · 421 阅读 · 0 评论 -
案例六:整数划分问题
当n=6,m=3时,有:q(6,3)=q(6-3,3)+q(6,2),q(6,3)表示最大加数不超过3的划分数,即虚线以下3行包括的划分,其中第一行是3开头的划分,个数是q(6-3,3),即从6中扣除3,剩下的值(即3)的最大加数不超过3的划分,后两行是q(6,2),表示最大加数不超过2的划分数。正整数n的最大加数n1不大于m的划分(个数为q(n,m),由n1=m的划分(个数为q(n-m,m)和n1≤m-1的划分(个数为q(n,m-1)组成。(2)当m>n时,q(n,m)=q(n,n)原创 2024-03-02 18:18:18 · 392 阅读 · 0 评论 -
案例六:纸张尺寸
根据题意维护长边长度a和短边长度b即可。对于A0而言,a=1189,b=841。循环x次后,依次输出a和b的值即可。(2)a除以2后,肯定比b小,原创 2024-02-05 10:38:48 · 431 阅读 · 0 评论 -
3.6枚举算法
例如,“百钱百鸡”问题:1只公鸡值5钱,1只母鸡值3钱,3只小鸡值1钱,某人用100钱买了100只鸡,问公鸡、母鸡、小鸡各有多少只。最后当x取44时,又考虑y取1、2、44。例如,求x^2+y^2=2000的正整数解,如果互换x和y视为同一组解,例如(8,44)和(44,8),那么y就不能从1枚举到44,否则得到的解就有重复,y只能从1枚举到×(或从x枚举到44)又如,求x^2+y^2=n的正整数解,实际上只需要枚举x就可以了,对x的每一个取值,判断(n-x^2)的平方根是不是整数就可以了。原创 2024-02-18 20:37:45 · 385 阅读 · 0 评论 -
4.3函数参数
若x=56,y=67,mx执行完毕后,变量m的值为67,将这个值返回到main函数中,即返回到“c=mx(a,b);如mx(3,a+b),但要求a和b有确定的值。如果实参是变量,为避免混淆,建议初学者将形参和实参用不同的变量名表示。假设实参为a和b,形参为x和y,在调用函数时将实参a和b的值分别传给形参x和y,C/C++提供了max函数,可以求两个数的较大值。”时,转而去执行mx函数。此外,每个实参的类型必须跟对应的形参的类型一致或赋值兼容。大多数函数都是带参数的。①在定义函数时指定的形参,在。原创 2024-02-28 20:31:19 · 352 阅读 · 0 评论 -
案例十一:Fibonacci(斐波那契)数列
下一轮循环,因为f1和f2的值已经更新了,所以再递推出f3,又是新的一项。递推出Fibonacci数列的每一项。,就递推出新的一项,原创 2024-02-16 16:14:27 · 370 阅读 · 0 评论 -
案例十七:干支纪年法
干支纪年法中天干和地支的搭配可以用右图来表示,因为“天干”有10个,“地支”有12个,从“甲子”开始到“癸酉”,天干已经用完,又从“甲”开始,所以下一个干支纪年是“甲戌由题目给定的2009年是己丑年,可以推算出。子、丑、寅、卯、辰、巳、午、未、申、酉、戌、亥。甲、乙、丙、丁、戌、己、庚、辛、壬、癸。原创 2024-02-28 19:07:56 · 529 阅读 · 0 评论 -
案例十六:二进制数
表示第1个输出的位置,初值为true;在输出pos前,先判断first的值是否为true,如果是则将first的值改为false,否则才输出一个空格。这样就做到了第1个位置之前不输出空格,然后在接下来的所有数码“1”的位置之前输出一个空格。pos的初值为0,每次将n除以2后,pos自增1。本题还需要处理多组测试数据,而且是第一种输入情形。但是我们并不知道要输出多少个位置。注意,有些竞赛题目对输出要求非常严格。原创 2024-02-28 15:31:23 · 435 阅读 · 0 评论 -
3.8多组测试数据的处理
这时就可以引入多组测试数据,不同算法的运行时间差异就会增大,有些算法可能就会超时。②有些题目,如果只处理一组数据,可能运行时间太短,难以。①输入数据文件中,第一行数据标明了测试数据的数目(,防止出现解答程序考虑不全面也能通过评判的情形;②输入数据文件中,有标明输入结束的数据(③输入数据文件中,测试数据一直到文件尾。原创 2024-02-28 14:59:33 · 665 阅读 · 0 评论 -
案例十:重复两遍的数
由于n值后面还要用到,所以先将n的值赋值给t。原创 2024-02-05 13:39:42 · 377 阅读 · 0 评论 -
案例八:刷题统计
需要实现大于等于n题,可以。原创 2024-02-05 12:14:50 · 399 阅读 · 0 评论 -
4.2函数的定义
注意,类型标识符不能省略,如果没有返回值,则类型标识符为void。函数名必须是合法的标识符。圆括号内的void加上了方括号“[]”,表示void可以省略。int f(int x,y,z) //(✘)在定义函数是,每个参数都必须用类型名修饰。定义有参函数时,要将参数以列表形式在圆括号内列出,有多少个参数就必须列出多少个,而且。int x,y,z;//(✔) 定义变量时,可以用一个类型名定义多个同类型变量。原创 2024-02-28 20:02:14 · 359 阅读 · 0 评论 -
案例九:修剪灌木
因为最开始从左往右进行修剪,当修剪到第i棵灌木时,它的高度为i;根据这个结论再用for循环可以求出每棵灌木的最大高度。对于第i棵灌木而言,原创 2024-02-05 12:53:54 · 418 阅读 · 0 评论 -
3.7算法的效率
在案例“既是平方数也是立方数”中,方法一要执行n次,因此算法时间复杂度就是O(n),方法二要执行n的3次平方根次,算法时间复杂度就是O(n的3次平方根);方法三的时间复杂度是O(n的6次平方根);方法四的时间复杂度是O(1),因为运算执行次数是固定的,跟n没有关系。O(1)、O(logn)、O(n的3次平方根)、O(n的2次平方根)、O(n)、O(nlogn)、O(n^2)、O(n^3)都属于。,在程序设计竞赛里,一般只有多项式时间复杂度的算法才有可通过评判系统的评判。为了度量算法的效率,我们需要引入。原创 2024-02-28 14:34:48 · 386 阅读 · 0 评论 -
4.4函数返回值
执行到哪个return语句,该return语句起作用。执行到某个return语句,函数就执行完毕,之后的语句就不执行了。,即函数值类型决定返回值的类型。对数值型数据,可以自动进行类型转换。return语句将被调用函数中的。原创 2024-02-28 20:40:30 · 424 阅读 · 0 评论 -
案例十五:猴子偷桃
但是当n=9时,第一轮桃子数已经接近于int型范围的上限了,程序中还有n*tot/(n-1)的运算,所以。,注意tot肯定能被(n-1)整除,另外,这个运算表示tot先除(n-1),再把得到的上乘以n。其实本题应该倒过来,从第只猴子开始算,因为每一轮的桃子数量肯定是越来越少的。后来发现公式越来越复杂,以至于无法表示出来。第一只猴子把桃子分成份,多了一个,本题还有一个坑,虽然题目保证。原创 2024-02-28 12:40:07 · 519 阅读 · 0 评论 -
案例十二:求解台阶问题
根据上述递推公式,就可以求得本题的答案。假设走了t步走到n阶台阶处,一定是。,不可能有其他情形,如下图所示。原创 2024-02-16 17:01:33 · 426 阅读 · 0 评论 -
4.1函数的概述
用户不必自己定义这些函数,可以直接调用它们,但必须把相关的头文件包含进来。例如,求平方根的函数sqrt,是在头文件cmath中声明的,因此调用sqrt函数时必须cmath包含进来。在这个例子中,把“输出100~200之内所有质数”的功能需求进行分解,把“判断一个正整数是否为质数”的功能用prime函数去实现。“函数”这个名词的英文原文是“function”,而“function”的原意是“功能”。例如,要输出100~200之内的质数,可以用一个2重循环实现。用以解决用户的专门需要,由用户自己定义的函。原创 2024-02-28 19:38:21 · 383 阅读 · 0 评论 -
案例十四:区间内重复两遍的数
例如,n=742,则最小的重复了2遍的数是1010,它的一半n1是10;方法一在数据量比较大时,容易超时。这种方法需要处理很多特殊情况,比较复杂。原创 2024-02-28 11:33:31 · 371 阅读 · 0 评论 -
案例七:最少砝码
按照这个规律,下一个选重量多少的砝码呢?选1、3的砝码可以称重:1,3-1=2(减相当于放在天平左边),3,3+1=4。首先,如果要称的重量为1的话,只能选择重量为1的砝码,然后再称比1重的,反正都是要再加砝码,那我们为何不。当我们还需要再增加一个砝码时,按上述方法分析可得,选。先考虑选用两个砝码,是否能称1~N连续的重量。选1、4的砝码可以称重:1,无法称2,不合题意。选1、2的砝码可以称重:1,2,1+2=3。注意,虽然题目没有说,但稍加分析就知道,因此,如果只能选2个砝码,则。原创 2024-02-05 11:17:50 · 509 阅读 · 0 评论