NOIP2012提高组day1
- 格式:pdf
- 大小:664.90 KB
- 文档页数:7
NOIP复习资料(C++版)主编葫芦岛市一高中李思洋前言有一天,我整理了NOIP的笔记,并收集了一些经典算法。
不过我感觉到笔记比较凌乱,并且有很多需要修改和补充的内容,于是我又搜集一些资料,包括一些经典习题,在几个月的时间内编写出了《NOIP复习资料》。
由于急于在假期之前打印出来并分发给同校同学(我们学校既没有竞赛班,又没有懂竞赛的老师。
我们大家都是自学党),《NOIP复习资料》有很多的错误,还有一些想收录而未收录的内容。
在“减负”的背景下,暑期放了四十多天的假。
于是我又有机会认真地修订《NOIP复习资料》。
我编写资料的目的有两个:总结我学过(包括没学会)的算法、数据结构等知识;与同学共享NOIP知识,同时使我和大家的RP++。
大家要清醒地认识到,《NOIP复习资料》页数多,是因为程序代码占了很大篇幅。
这里的内容只是信息学的皮毛。
对于我们来说,未来学习的路还很漫长。
基本假设作为自学党,大家应该具有以下知识和能力:①能够熟练地运用C++语言编写程序(或熟练地把C++语言“翻译”成Pascal语言);②能够阅读代码,理解代码含义,并尝试运用;③对各种算法和数据结构有一定了解,熟悉相关的概念;④学习了高中数学的算法、数列、计数原理,对初等数论有一些了解;⑤有较强的自学能力。
代码约定N、M、MAX、INF是事先定义好的常数(不会在代码中再次定义,除非代码是完整的程序)。
N、M、MAX针对数据规模而言,比实际最大数据规模大;INF针对取值而言,是一个非常大,但又与int的最大值有一定差距的数,如100000000。
对于不同程序,数组下标的下限也是不同的,有的程序是0,有的程序是1。
阅读程序时要注意。
阅读顺序和方法没听说过NOIP,或对NOIP不甚了解的同学,应该先阅读附录E,以加强对竞赛的了解。
如果不能顺利通过初赛,你就应该先补习初赛知识。
这本《NOIP复习资料》总结的是复赛知识。
如果没有学过C++语言,应该先选择一本C++语言教材。
第29届全国青少年信息学奥林匹克竞赛CCF NOI 2012第一试竞赛时间:2012年7月30日 8:00-13:00注意:最终测试时,所有编译命令均不打开任何优化开关。
随机数生成器【问题描述】栋栋最近迷上了随机算法,而随机数生成是随机算法的基础。
栋栋准备使用线性同余法(Linear Congruential Method)来生成一个随机数列,这种方法需要设置四个非负整数参数 m,a,c,X0,按照下面的公式生成出一系列随机数<X n>:X n+1=(aX n + c) mod m其中 mod m 表示前面的数除以 m 的余数。
从这个式子可以看出,这个序列的下一个数总是由上一个数生成的。
用这种方法生成的序列具有随机序列的性质,因此这种方法被广泛地使用,包括常用的C++和Pascal的产生随机数的库函数使用的也是这种方法。
栋栋知道这样产生的序列具有良好的随机性,不过心急的他仍然想尽快知道X n是多少。
由于栋栋需要的随机数是0,1,…,g−1 之间的,他需要将 X n除以 g 取余得到他想要的数,即 X n mod g,你只需要告诉栋栋他想要的数X n mod g 是多少就可以了。
【输入格式】输入文件random.in中包含6个用空格分割的整数 m,a,c,X0,n 和 g ,其中 a,c,X0是非负整数,m,n,g 是正整数。
【输出格式】输出到文件random.out中,输出一个数,即 X n mod g。
【样例输入】11 8 7 1 5 3【样例输出】2【样例说明】<X n>因此答案为 X5【数据规模与约定】骑行川藏【问题描述】蛋蛋非常热衷于挑战自我,今年暑假他准备沿川藏线骑着自行车从成都前往拉萨。
川藏线的沿途有着非常美丽的风景,但在这一路上也有着很多的艰难险阻,路况变化多端,而蛋蛋的体力十分有限,因此在每天的骑行前设定好目的地、同时合理分配好自己的体力是一件非常重要的事情。
NOIP 2012简要题解王赢绪东北师大附中高二二班499167119@2012年11月19日分数分布:Day 1:Problem Contest Current Vigenère密码(vigenere)100 100国王游戏(game)100 100开车旅行(drive)70 100Day 2:Problem Contest Current 同余方程(mod)100 100借教室(classroom)90 100疫情控制(blockade)50 100题解:Day 1:Problem 1 Vigenère密码(vigenere)这是一道模拟题,我的做法的先把密钥都换成大写或者小写。
然后对输入的加密文章进行处理,如果当前对应的密钥位置超过了密钥的总长度,则把当前位置转回1即可,并且注意加密文章的大小写问题。
时间复杂度为O(n+m),其中n和m分别为两个字符串的长度。
Problem 2国王游戏(game)这道题的主要考察点是高精度乘法除法以及贪心算法的应用。
这是USACO 2007年某次月赛的改编题。
我们不难观察出必存在一种最优的安排方案,是按照每个人左右手两个数的乘积由小到大排序后计算得来,对于乘积相同的我们可以不考虑他们的顺序。
Problem 3开车旅行(drive)这道题我只能想到用平衡树然后倍增维护每个点往前走2的次幂到达哪,以及需要的路程为多少。
具体实现是这样的,我们首先按照站点倒序的顺序进行处理,那么显然每个点离它最近的那个点一定是它高度值的前驱或者后继(如果存在的话),接下来我们考虑每个点的次近点,比如最近点为前驱,那么显然次近点为前驱的前驱或者后继,而如果最近点为后继,则次近点为后继的后继或者前驱。
所以我们可以花O(n log n)的时间处理完成每个点的最近点及次近点。
接下来由于我们已经有了每个点可以到达的最近点及次近点,那么我们可以处理出每个点走2的次幂以后,A走过的路程为多少,B走过的路程为多少,以及此时所在的位置。
CCF全国信息学奥林匹克联赛(NmP2012)复赛提高组day22. 1 ·同余方程〖问题描述〗求关于的同余方程三1 (mod句的最小正整数解。
输入〗输入文件为mod.ino输入只有一行,包含两个正整数用一个空格隔开输出〗输出文件为mod.outo输出只有一行,包含一个正整数№即最小正整数解。
输入数据保证一定有解。
〖输入输出样例〗对于40%的数据,2 L000:对于60%的数据,2 50,000,000:对于100%的数据,2,2,000,000,000。
2 ·借教室 (classroom. cpp/c/pas)问题描述〗在大学期间,经常需要租借教室。
大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室。
教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样。
面对海量租借教室的信息,我们自然希望编程解决这个问题。
我们需要处理接下来n天的借教室信息,其中第i天学校有个教室可供租借。
共有m份订单,每份订单用三个正整数描述,分别为d],斗t},表示某租借者需要从第丬天到第t]天租借教室(包括第丬天和第t)天),每天需要租借dj个教室。
我们假定,租借者对教室的大小、地点没有要求。
即对于每份订单,我们只需要每天提供d]个教室,而它们具体是哪些教室,每天是否是相同的教室则不用考虑。
借教室的原则是先到先得,也就是说我们要按照订单的先后顺序依次为每份订单分配教室。
如果在分配的过程中遇到一份订单无法完全满足,则需要停止教室的分配,通知当前申请人修改订单。
这里的无法满足指从第丬天到第t)天中有至少一天剩余的教室数量不足d)个。
现在我们需要知道,是否会有订单无法完全满足。
如果有,需要通知哪一个申请人修改输入〗输入文件为classroom.in第一行包含两个正整数n,m,表示天数和订单的数量。
第二行包含n个正整数,其中第i个数为ri,表示第i天可用于租借的教室数量。
接下来有m行,每行包含三个正整数dJ,s],t],表示租借的数量,租借开始、结束分别在第几天。
CCF全国信息学奥林匹克联赛(NOIP2012)复赛提高组 day1(请选手务必仔细阅读本页内容)注意事项:1、文件名(程序名和输入输出文件名)必须使用英文小写。
2、C/C++中函数main()的返回值类型必须是int,程序正常结束时的返回值必须是0。
3、全国统一评测时采用的机器配置为:CPU Intel Core2 Quad Q8200 2.33GHz, 内存2G,上述时限以此配置为准。
4、特别提醒:评测在NOI Linux下进行。
1.Vigenère密码(vigenere.cpp/c/pas)【问题描述】16世纪法国外交家Blaise de Vigenère设计了一种多表密码加密算法——Vigenère密码。
Vigenère密码的加密解密算法简单易用,且破译难度比较高,曾在美国南北战争中为南军所广泛使用。
在密码学中,我们称需要加密的信息为明文,用M表示;称加密后的信息为密文,用C表示;而密钥是一种参数,是将明文转换为密文或将密文转换为明文的算法中输入的数据,记为k。
在Vigenère密码中,密钥k是一个字母串,k=k1k2…k n。
当明文M=m1m2…m n时,得到的密文C=c1c2…c n,其中c i=m i®k i,运算®的规则如下表所示:®【输入】输入文件名为vigenere.in。
输入共2行。
第一行为一个字符串,表示密钥k,长度不超过100,其中仅包含大小写字母。
第二行为一个字符串,表示经加密后的密文,长度不超过1000,其中仅包含大小写字母。
【输出】输出文件名为vigenere.out。
输出共1行,一个字符串,表示输入密钥和密文所对应的明文。
对于100%的数据,输入的密钥的长度不超过100,输入的密文的长度不超过1000,且都仅包含英文字母。
2.国王游戏(game.cpp/c/pas)【问题描述】恰逢H国国庆,国王邀请n位大臣来玩一个有奖游戏。
首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。
然后,让这n位大臣排成一排,国王站在队伍的最前面。
排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。
国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。
注意,国王的位置始终在队伍的最前面。
【输入】输入文件为game.in。
第一行包含一个整数n,表示大臣的人数。
第二行包含两个整数a和b,之间用一个空格隔开,分别表示国王左手和右手上的整数。
接下来n行,每行包含两个整数a和b,之间用一个空格隔开,分别表示每个大臣左手和右手上的整数。
【输出】输出文件名为game.out。
输出只有一行,包含一个整数,表示重新排列后的队伍中获奖赏最多的大臣所获得的金币数。
【输入输出样例】【输入输出样例说明】按1、2、3号大臣这样排列队伍,获得奖赏最多的大臣所获得金币数为2;按1、3、2这样排列队伍,获得奖赏最多的大臣所获得金币数为2;按2、1、3这样排列队伍,获得奖赏最多的大臣所获得金币数为2;按2、3、1这样排列队伍,获得奖赏最多的大臣所获得金币数为9;按3、1、2这样排列队伍,获得奖赏最多的大臣所获得金币数为2;按3、2、1这样排列队伍,获得奖赏最多的大臣所获得金币数为9。
因此,奖赏最多的大臣最少获得2个金币,答案输出2。
【数据范围】对于20%的数据,有1≤ n≤ 10,0 < a、b < 8;对于40%的数据,有1≤ n≤20,0 < a、b < 8;对于60%的数据,有1≤ n≤100;对于60%的数据,保证答案不超过109;对于100%的数据,有1 ≤ n ≤1,000,0 < a、b < 10000。
3.开车旅行(drive.cpp/c/pas)【问题描述】小A和小B决定利用假期外出旅行,他们将想去的城市从1到N编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市i的海拔高度为H i,城市i和城市j之间的距离d[i,j]恰好是这两个城市海拔高度之差的绝对值,即d[i,j]=|H i−H j|。
旅行过程中,小A和小B轮流开车,第一天小A开车,之后每天轮换一次。
他们计划选择一个城市S作为起点,一直向东行驶,并且最多行驶X公里就结束旅行。
小A和小B 的驾驶风格不同,小B总是沿着前进方向选择一个最近的城市作为目的地,而小A总是沿着前进方向选择第二近的城市作为目的地(注意:本题中如果当前城市到两个城市的距离相同,则认为离海拔低的那个城市更近)。
如果其中任何一人无法按照自己的原则选择目的城市,或者到达目的地会使行驶的总距离超出X公里,他们就会结束旅行。
在启程之前,小A想知道两个问题:1.对于一个给定的X=X0,从哪一个城市出发,小A开车行驶的路程总数与小B行驶的路程总数的比值最小(如果小B的行驶路程为0,此时的比值可视为无穷大,且两个无穷大视为相等)。
如果从多个城市出发,小A开车行驶的路程总数与小B行驶的路程总数的比值都最小,则输出海拔最高的那个城市。
2. 对任意给定的X=X i和出发城市S i,小A开车行驶的路程总数以及小B行驶的路程总数。
【输入】输入文件为drive.in。
第一行包含一个整数N,表示城市的数目。
第二行有N个整数,每两个整数之间用一个空格隔开,依次表示城市1到城市N的海拔高度,即H1,H2,……,H n,且每个H i都是不同的。
第三行包含一个整数X0。
第四行为一个整数M,表示给定M组S i和X i。
接下来的M行,每行包含2个整数S i和X i,表示从城市S i出发,最多行驶X i公里。
【输出】输出文件为drive.out。
输出共M+1行。
第一行包含一个整数S0,表示对于给定的X0,从编号为S0的城市出发,小A开车行驶的路程总数与小B行驶的路程总数的比值最小。
接下来的M行,每行包含2个整数,之间用一个空格隔开,依次表示在给定的S i和X i下小A行驶的里程总数和小B行驶的里程总数。
【输入输出样例1】【输入输出样例1说明】各个城市的海拔高度以及两个城市间的距离如上图所示。
如果从城市1出发,可以到达的城市为2,3,4,这几个城市与城市1的距离分别为1,1,2,但是由于城市3的海拔高度低于城市2,所以我们认为城市3离城市1最近,城市2离城市1第二近,所以小A会走到城市2。
到达城市2后,前面可以到达的城市为3,4,这两个城市与城市2的距离分别为2,1,所以城市4离城市2最近,因此小B会走到城市4。
到达城市4后,前面已没有可到达的城市,所以旅行结束。
如果从城市2出发,可以到达的城市为3,4,这两个城市与城市2的距离分别为2,1,由于城市3离城市2第二近,所以小A会走到城市3。
到达城市3后,前面尚未旅行的城市为4,所以城市4离城市3最近,但是如果要到达城市4,则总路程为2+3=5>3,所以小B会直接在城市3结束旅行。
如果从城市3出发,可以到达的城市为4,由于没有离城市3第二近的城市,因此旅行还未开始就结束了。
如果从城市4出发,没有可以到达的城市,因此旅行还未开始就结束了。
【输入输出样例2说明】当X=7时,如果从城市1出发,则路线为1 -> 2 -> 3 -> 8 -> 9,小A走的距离为1+2=3,小B走的距离为1+1=2。
(在城市1时,距离小A最近的城市是2和6,但是城市2的海拔更高,视为与城市1第二近的城市,所以小A最终选择城市2;走到9后,小A只有城市10可以走,没有第2选择可以选,所以没法做出选择,结束旅行)如果从城市2出发,则路线为2 -> 6 -> 7 ,小A和小B走的距离分别为2,4。
如果从城市3出发,则路线为3 -> 8 -> 9,小A和小B走的距离分别为2,1。
如果从城市4出发,则路线为4 -> 6 -> 7,小A和小B走的距离分别为2,4。
如果从城市5出发,则路线为5 -> 7 -> 8 ,小A和小B走的距离分别为5,1。
如果从城市6出发,则路线为6 -> 8 -> 9,小A和小B走的距离分别为5,1。
如果从城市7出发,则路线为7 -> 9 -> 10,小A和小B走的距离分别为2,1。
如果从城市8出发,则路线为8 -> 10,小A和小B走的距离分别为2,0。
如果从城市9出发,则路线为9,小A和小B走的距离分别为0,0(旅行一开始就结束了)。
如果从城市10出发,则路线为10,小A和小B走的距离分别为0,0。
从城市2或者城市4出发小A行驶的路程总数与小B行驶的路程总数的比值都最小,但是城市2的海拔更高,所以输出第一行为2。
【数据范围】对于30%的数据,有1≤N≤20,1≤M≤20;对于40%的数据,有1≤N≤100,1≤M≤100;对于50%的数据,有1≤N≤100,1≤M≤1,000;对于70%的数据,有1≤N≤1,000,1≤M≤10,000;对于100%的数据,有1≤N≤100,000,1≤M≤10,000,-1,000,000,000≤H i≤1,000,000,000,0≤X0≤1,000,000,000,1≤S i≤N,0≤X i≤1,000,000,000,数据保证H i互不相同。