NOIP题解.ppt
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_05.gif)
《NOIP题解.ppt》由会员分享,可在线阅读,更多相关《NOIP题解.ppt(34页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、 首先,第一题是四道题中最简单的,直接写代码,注意一些细节就可以了,一百分也是一定要拿到手的,因为后面的分都不是很好拿。 然后是第二题,第二题就要用动态规划了,可以用最朴素的BFS来过那30%的比较弱的数据,用最朴素的动态规划只能拿到50%左右的分,需要对动态规划的状态进行优化,方可拿到一百分。 对于第三题,用搜索很快可拿30,代码复杂度也极低,看到规律的枚举+BFS(floodfill)拿80分,会优化的二分(二分枚举)+BFS拿满分,只是代码稍微麻烦些,或者有思路的用贪心+并查集也可拿满分,代码也要比二分+BFS简单一点。 然后关于本题,数据的反复查找与读取很耗时,想不超时的一些同学需要考
2、虑图论中无向联通图的存储方式,邻接矩阵和完善的静态邻接表直接爆内存零分,所以只能用动态邻接表或者双链表,笔者偷懒,用的不完善静态链表+直接查找数据所以,学学动态邻接表和双链表存储图看来迫在眉睫 最后是第四题,思路比较难,搜索的可以稳拿拿到30分,没有思路就搜索吧。分析过后可以发现最后一题就是一个搜索+“线段覆盖”问题,对于搜索,本体其实用DFS会比BFS快很多,对于“线段覆盖”,用动规解决就好了。 四道题的分值都是100,总分400,而分数线是200,这就意味着只要拿到半数的分就可以达到我们的目的。 回头看看这四道题,首先第一题的100分果断拿到手无疑问,剩下还有三道题,只要再凑100分就行了
3、。 对于这三题都用搜索的算法就可以拿到90分,离分数线还差那么10分,所以,明显不能够这么做在上考场前也应该清楚,既然大家都会搜,就不能想着只用搜索去过联赛,而要对其中的某一偏难题用非搜索的更先进的方式进行解答,这次的分数线就最能作为一个例子。 后两题暂且不说,题都不简单,就暂且用搜索的方法吧,这就可以拿到60分,那剩下的就在第二题了,第二题比其后两题简单得多,其实用足够优化的搜索就可以多拿20分,但是,这是不保险的,正如上段所分析,所以,绞尽脑汁去想这个明显要用动态规划去做的题吧,相信其实过线并不难。 下面,让我们来看看去年我省的过线情况吧:按照选手成绩由高到低排列,“*”为往届获奖选手或初
4、中选手 河南省一共过线43人,其中省实验过线人数为14人。 两个的数字告诉我们,实验的信息学奥赛是全省教的最棒的,我们所处的地方正是学习信息学奥赛最佳的场所,由水平全省领先的老师亲自领导,加上历届NOIP选手经验的支持,再加上是最后一届有保送考试资格的学生,条件可谓空前绝后,我们再不努力过联赛,真就说不过去了,Isnt it? 好了,不多说了,下面就来看一下每道题详细的分析吧: 小晨的电脑上安装了一个机器翻译软件,他经常用这个软件来翻译英语文章。 这个翻译软件的原理很简单,它只是从头到尾,依次将每个英文单词用对应的中文含义来替换。对于每个英文单词,软件会先在内存中查找这个单词的中文含义,如果内
5、存中有,软件就会用它进行翻译;如果内存中没有,软件就会在外存中的词典内查找,查出单词的中文含义然后翻译,并将这个单词和译义放入内存,以备后续的查找和翻译。 假设内存中有M 个单元,每单元能存放一个单词和译义。每当软件将一个新单词存入内存前,如果当前内存中已存入的单词数不超过M1,软件会将新单词存入一个未使用的内存单元;若内存中已存入M 个单词,软件会清空最早进入内存的那个单词,腾出单元来,存放新单词。 假设一篇英语文章的长度为N 个单词。给定这篇待译文章,翻译软件需要去外存查找多少次词典?假设在翻译开始前,内存中没有任何单词。【数据范围】对于10%的数据有M=1,N 5。对于100%的数据有0
6、M 100,0N 1000。 看过题后也许大家都不禁感慨,这不就是队列的基本操作么?没错,没有想错,对于这道题,这样的数据规模,最一般的方法就行了。基本方法应该已经在大家的心里定了形了,开一个一维数组作为队列,实现题中要求的“先进先出”的操作,再在每次入队时判重并计数就可以了。输入文件:translate.in 输入文件共2 行。每行中两个数之间用一个空格隔开。 第一行为两个正整数M 和N,代表内存容量和文章的长度。 第二行为N 个非负整数,按照文章的顺序,每个数(大小不超过1000)代表一个英文 单词。文章中两个单词是同一个单词,当且仅当它们对应的非负整数相同。输出文件:translate.
7、out 共1 行,包含一个整数,为软件需要查词典的次数。 这里其实又给定了一个重要的条件:“每个数(大小不超过1000)代表一个英文”。对此,很快头脑中便会闪出一个对程序“查询内存”(即判重)优化的念头:哈希。【输入输出样例1】 3 7 1 2 1 5 4 4 1【输入输出样例1】 5【输入输出样例2】 2 10 8 824 11 78 11 78 11 78 8 264【输入输出样例2】 6#include using namespace std;int main(void) ifstream input(translate.in); ofstream output(translate.ou
8、t);int i,maxmemory,wordnumber,newword,tail=0,head=-1,que1000; bool existed1001=false; /记录单词是否已经存在(哈希)inputmaxmemorywordnumber;for (i=1;inewword; /读入新单词if (!existednewword) /判断单词是否存在head+; /existednewword=true; /quehead=newword;/若单词不存在,入队并标记为已存在(若存在,不入队)if (head-tail=maxmemory) /判断队列是否已满existedquetai
9、l=false; /tail+;/若已满,删除队尾元素,标记删除了的队尾元素为不存在 outputhead+1endl;input.close(); output.close(); return(0); 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物。 乌龟棋的棋盘是一行N 个格子,每个格子上一个分数(非负整数)。棋盘第1 格是唯一的起点,第N 格是终点,游戏要求玩家控制一个乌龟棋子从起点出发走到终点。1 2 3 4 5 N 乌龟棋中M 张爬行卡片,分成4 种不同的类型(M 张卡片中不一定包含所有4 种类型的卡片,见样例),每种类型的卡片上分别标有1、2、3、4 四个数字之一,表示使用这种卡片
10、后,乌龟棋子将向前爬行相应的格子数。游戏中,玩家每次需要从所有的爬行卡片中选择一张之前没有使用过的爬行卡片,控制乌龟棋子前进相应的格子数,每张卡片只能使用一次。 游戏中,乌龟棋子自动获得起点格子的分数,并且在后续的爬行中每到达一个格子,就得到该格子相应的分数。玩家最终游戏得分就是乌龟棋子从起点到终点过程中到过的所有格子的分数总和。 很明显,用不同的爬行卡片使用顺序会使得最终游戏的得分不同,小明想要找到一种卡片使用顺序使得最终游戏得分最多。 现在,告诉你棋盘上每个格子的分数和所有的爬行卡片,你能告诉小明,他最多能得到多少分吗?【输入】输入文件名tortoise.in。输入文件的每行中两个数之间用
11、一个空格隔开。第1 行2 个正整数N 和M,分别表示棋盘格子数和爬行卡片数。第2 行N 个非负整数,a1, a2, , aN,其中ai 表示棋盘第i 个格子上的分数。第3 行M 个整数,b1,b2, , bM,表示M 张爬行卡片上的数字。输入数据保证到达终点时刚好用光M 张爬行卡片。【输出】输出文件名tortoise.out。输出只有1 行,1 个整数,表示小明最多能得到的分数。【数据范围】对于30%的数据有1 N 30,1 M 12。对于50%的数据有1 N 120,1 M 50,且4 种爬行卡片,每种卡片的张数不会超过20。对于100%的数据有1 N 350,1 M 120,且4 种爬行卡
12、片,每种卡片的张数不会超过40;0 ai 100,1 i N;1 _bi 4,1 i M。【输入输出样例1】9 56 10 14 2 8 8 18 5 171 3 1 2 173【输入输出样例 1 说明】小明使用爬行卡片顺序为1,1,3,1,2,得到的分数为6+10+14+8+18+17=73。注意,由于起点是1,所以自动获得第1 格的分数6。【输入输出样例2】13 84 96 10 64 55 13 94 53 5 24 89 8 301 1 1 1 1 2 4 1455 拿到这道题,首先想到排列组合问题,因此可以直接用最简单的思路,用搜索的方法把所有可能的排列枚举出来,再求其最优。 不过,
13、明显的看出,这样只能过那30%的简单数据,见到另外70%的数据,12个以上的卡片,估计就要超时了。 判断出是排列问题,那这道题似乎就显得简单一些了,根据这个思路再进一步,因为只有四种类型的卡片,且不需要输出具体的步骤,可以想到,其实用动态规划解决这道题是可行的。 在我的动规算法中,状态之一是每种卡片使用的情况,状态之二是当前状态可以所得的最大分数。 开数组card 来存储四种卡片的个数,其下标表示卡片的使用效果,即用一张该种卡片可以走几格。 开数组step 来存储每一格的分数情况,其下标表示该格是第几格,以step 1 为第一格。 开数组a i j k l 来存储用某种方式所得的最大分数,其中
14、i,j,k,l分别表示当前第一,二,三,四种卡片的使用张数,则其初始状态为a 0 0 0 0 (= step 1 ),目标状态为a card 1 card 2 card 3 card 4 。中间的状态转移规则为(在不越界的情况下):a i j k l = step i*4+k*3+j*2+i+1 +max a i-1 j k l , a i j-1 k l , a i j k-1 l , a i j k l-1 在这里,因为四种卡片的张数、当前走到底几格五个量中“知四求一”,所以还用另外一种动态规划的方法。 开数组f i , a , b , c ,其中i表示前i格,a表示第一种卡片剩余数量,b
15、表示第二种,c表示第三种,可用计算公式 ( i-1-a-2b-3c )div 4 得出第四种卡片剩余数量。 于是dp( 动态规划 )求解 f i , a , b , c = step i +max f i-1 , a+1 , b , c , f i-2 , a , b+1 , c , f i-3 , a , b , c+1 , f i-4 , a , b , c ; 最后输出f n , 0 , 0 , 0 即可#include using namespace std;long long a41414141;int fm(int maxnum,int a,int b,int c) /函数fm(f
16、indmax)为找四个数中最大值并返回最大值的函数if (maxnuma)maxnum=a;if (maxnumb)maxnum=b;if (maxnumstepnumcardnum;for (i=1;istepi;for (i=1;item; cardtem+;a 0 0 0 0 =step 1 ;for (i=0;i=card1;i+)for (j=0;j=card2;j+)for (k=0;k=card3;k+)for (l=0;l=card4;l+) if (i=j&j=k&k=l&l=0) continue;if (i != 0) tem = a i-1 j k l + step l
17、*4+k*3+j*2+i+1 ;else tem = 0;if (j != 0) tem2 = a i j-1 k l + step l*4+k*3+j*2+i+1 ;else tem2 = 0;if (k != 0) tem3 = a i j k-1 l + step l*4+k*3+j*2+i+1 ;else tem3 = 0;if (l != 0) tem4 = a i j k l-1 + step l*4+k*3+j*2+i+1 ;else tem4 = 0;a i j k l = fm( tem , tem2 , tem3 , tem4 ); outputa card1 card2
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- NOIP 题解
![提示](https://www.taowenge.com/images/bang_tan.gif)
限制150内