ImageVerifierCode 换一换
格式:DOCX , 页数:15 ,大小:35.48KB ,
资源ID:6509295      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/6509295.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(noip普及组复赛解题报告.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

noip普及组复赛解题报告.docx

1、noip普及组复赛解题报告N O I P 2 0 1 5 普 及 组 解 题 报 告南京师范大学附属中学树人学校 CT1.金币 (coin.cpp/c/pas)【问题描述】 国王将金币作为工资,发放给忠诚的骑士。第一天,骑士收到一枚金 币;之后两天 (第二天和第三天),每天收到两枚金币; 之后三天(第 四、五、六天),每天收到三枚金币;之后四天(第七、八、九、十 天),每天收到四枚金币 ;这种工资发放模式会一直这样延续下 去:当连续N天每天收到N枚金币后,骑士会在之后的连续N+1天里, 每天收到 N+1 枚金币。请计算在前 K 天里,骑士一共获得了多少金币。【输入格式】输入文件名为 coin.

2、in 。输入文件只有1行,包含一个正整数K,表示发放金币的天数。【输出格式】输出文件名为 coin.out 。输出文件只有 1 行,包含一个正整数,即骑士收到的金币数。【数据说明】对于 100%勺数据,1 K 10,000。【思路】模拟时空复杂度】O(k) ,O(1)2、扫雷游戏( mine.cpp/c/pas )【问题描述】扫雷游戏是一款十分经典的单机小游戏。 在n行m列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷 (称之为非地雷格) 玩家翻开一个非地雷格时, 该格将会出现一个数字提示周围格子 中有多少个是地雷格。游戏的目标是在不翻出任何地雷格的条件下, 找出所有的非地雷格。

3、现在给出n行m列的雷区中的地雷分布,要求计算出每个非地雷格周围 的地雷格数。注:一个格子的周围格子包括其上、 下、左、右、左上、右上、左下、 右下八个方向上与之直接相邻的格子。【输入格式】输入文件名为 mine.in 。输入文件第一行是用一个空格隔开的两个整数 n和m分别表示雷区的 行数和列数。接下来n行,每行m个字符,描述了雷区中的地雷分布情况。字符* 表示相应格子是地雷格,字符 ?表示相应格子是非地雷格。相邻 字符之间无分隔符。【输出格式】输出文件名为 mine.out 。输出文件包含n行,每行m个字符,描述整个雷区。用* 表示地雷 格,用周围的地雷个数表示非地雷格。相邻字符之间无分隔符。

4、【数据说明】对于 100%勺数据,1 nW 100, 1 me 100【思路】模拟【技巧】 可将数组多开一圈,省去边界条件勺判断。【时空复杂度】O(mn), O(mn)3.求和 (sum.cpp/c/pas)【问题描述】一条狭长的纸带被均匀划分出了 n个格子,格子编号从1到n。每个 格子上都染了一种颜色color i (用1,m当中的一个整数表示),并 且写了一个数字 numberi。定义一种特殊的三元组: (x,y,z) ,其中 x, y, z 都代表纸带上格子 的编号,这里的三元组要求满足以下两个条件:1.x,y,z 都是整数,xyz,y?x二z?y2.color x=color z满足上

5、述条件的三元组的分数规定为 (x+z)*(number x+numberz) 。整个 纸带的分数规定为所有满足条件的三元组的分数的和。 这个分数可能 会很大,你只要输出整个纸带的分数除以 10,007 所得的余数即可。 【输入格式】输入文件名为 sum.in 。第一行是用一个空格隔开的两个正整数 n 和 m, n 代表纸带上格子的个数,m代表纸带上颜色的种类数。第二行有n个用空格隔开的正整数,第i个数字number代表纸带上 编号为 i 的格子上面写的数字。第三行有m个用空格隔开的正整数,第i个数字color i代表纸带上编 号为 i 的格子染的颜色。【输出格式】输出文件名为 sum.out。

6、共一行,一个整数,表示所求的纸带分数除以 10,007 所得的余数。数据说明】对于第5组至第6组数据,1W nW 100000,1 W mW 100000,且不存在出现次数超过 20 的颜色;1WnW100000,1W mW100000,1Wcolor iWm,1 W numberiW100000。【思路】 先分析一下,我们的任务是什么。题目的要求是求分数和,我们就得 把所有符合条件的三元组“找”出来。至少需要枚举三元组(x,y,z)中的一个元素,这里枚举的是z (当然x 也可以,不过不要选y,因为y对分数没什么用)。1、 因为xyz,所以只需向前枚举x,y2、 因为 y-x=z-y ,所以

7、x+z=2y , x、 z 同奇偶,且分数与 y 无关,只 需枚举 z 和 x。3、 因为colour x=colour z,所以只需枚举z之前同奇偶且同色的X。 这样的话时间复杂度是 O(n2),能得40分。如何快速枚举x呢? 其实不是快速枚举X,是快速枚举分数和。观察三元组分数: (x+z) (numberx+ number)显然我们不方便处理多项式乘法,那就把它拆开(事实上很多人到这步都放弃了,其实试一试立刻就明白了) =x numbeix+x numbeiz+z numbeix+z numberz那么对于z的所有合法决策x1,x2, ,xk根据乘法分配率,分数二艺(xi*number力

8、)+艺(xi)*number z+艺 (nu mberxi)*z+ 艺(z* nu mberz)(1v=iv二k)由于z是枚举的,所以只需快速得到艺(xnumbeix),艺x,艺number 和k (注意最后一项被算了 k次,要乘k)这样我们就可以开 4 个累加器, 分别记录这四个量。 而对于不同奇偶性、不同颜色的z有不同的决策x,所以要开一个s2m4的累加 器。【时空复杂度】 0(n), 0(n+m)【注意】题目数据较大, 每次计算一定要模 10007,否则很容易出错 【样例程序】#include constintmaxn=100000;constintmaxm=100000;constin

9、tp=10007;intn,m,ans;intnumbermaxn+1,colourmaxn+1;ints2maxm+14;voidinit()freopen(sum.in,r,stdin);freopen(sum.out,w,stdout);scanf(%d%d,&n,&m); for(inti=1;i=n;i+) scanf(%d,&numberi);for(inti=1;i=n;i+)scanf(%d,&colouri);voidsolve()for(inti=1;i=n;i+)intz=i%p,numz=numberi%p,c=colouri,t=i%2;intcount=stc0%=

10、p,x=stc1%=p, numx=stc2%=p,x_numx=stc3%=p; ans=(ans+(count*z)%p*numz)%p)%p; ans=(ans+x_numx)%p; ans=(ans+x*numz)%p; ans=(ans+z*numx)%p;stc0+;stc1+=z;stc2+=numz;stc3+=z*numz;voidoutput()printf(%dn,ans);fclose(stdin);fclose(stdout);intmain()init();solve();output();return0;4.推销员 (salesman.cpp/c/pas)【问题描

11、述】 阿明是一名推销员, 他奉命到螺丝街推销他们公司的产品。 螺丝街是一 条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户。螺丝街一共有N家住户,第i家住户到入口的距离为 S米。由于同一 栋房子里可以有多家住户, 所以可能有多家住户与入口的距离相等。 阿 明会从入口进入,依次向螺丝街的X家住户推销产品,然后再原路走出 去。阿明每走 1 米就会积累 1 点疲劳值,向第 i 家住户推销产品会积累 Ai 点疲劳值。阿明是工作狂,他想知道,对于不同的 X,在不走多余的路 的前提下,他最多可以积累多少点疲劳值。【输入格式】输入文件名为 salesman.in 。第一行有一个正整数N,表示螺丝

12、街住户的数量。接下来的一行有N个正整数,其中第i个整数S表示第i家住户到入 口的距离。数据保证SWS2W-VS n108。接下来的一行有N个正整数,其中第i个整数A表示向第i户住户推 销产品会积累的疲劳值。数据保证 Ai103。【输出格式】输出文件名为 salesman.out 。输出N行,每行一个正整数,第i行整数表示当X=i时,阿明最多积累 的疲劳值。数据说明】 对于20%勺数据,1 N 20;对于40%勺数据,1 N 100;对于60%勺数据,1 N 1000;对于 100%勺数据,1 N 100000。【思路】题目要求每一个X的情况,显然不能每个X专门推一遍,要充分利用已 知的X的情况

13、,那么很可能会是 DP定义 fi 为 X=i 时勺最大疲劳值。关键是怎么建立状态转移方程呢?考试时观察了两组样例数据, 直觉告 诉我 fi+1 勺决策应该会包含 fi 勺决策(此处勺决策指住户下标) 。 事实上也确实如此。证明:设fi的决策为k,k2,ki(k1k2kj , fi+1的决策将fi决策中的ks换成j并增加了一个决策ki+1, fi+1的决策k中最大的为 maxk。fi=2*sk i+ 艺 akt(1=t=i)fi+1=2*smaxk+ 艺 akt(1=t=s-1)+ 艺ak t(s+1=t=i)+aj+ak i+1 v 2*smaxk+ 艺 akt(1=t=s-1)+ 艺 akt

14、(s+1=t=i)+aj 是 X=i 时 的一种决策的疲劳值(即决策为 k1,k2,ks-1,ks+1,ki,kj时)2*smaxk+ 艺 akt(1=t=s-1)+ 艺 akt(s+1=t=i)+aj=fi2*smaxk+ 艺 akt(1=t=s-1)+ 艺 akt(s+1=t=i)+aj+ak i+1 =fi+ak i+1(即决策为k1,k2,ks,ki,ki+1时的疲劳值)若小于,说明保留 ks 更优;若等于,对于两个目前疲劳值相等的决策序列 k,maxk 越小越好(就是说目前走的路程越短越好) ,因为在 maxk 左边的决策 l 只能增加 al 的 疲 劳 值 , 而 对 于 maxk

15、 右 边 的 决 策 r 则 可 以 增 加 2*(sr-smaxk)+ar ,对于左边,maxk没有影响,而对于右边,maxk 越小,后面的 f 增加疲劳值的空间越大。根据以上原则,虽然决策 ki,k2,ks,ki与决策ki,k2,ks-i ,ks+i, ki,k j疲劳值相等,但fi选择了前者,说明前者更优。综上,无论小于或等于,决策ki,k2, ,k s, ,k i都比决策ki,k2, ks-1 ,k s+1, ki ,k j 更优。 fi+1的最优决策一定包含了 fi的最优决策,证毕.也就是说,对于 fi ,只需在 fi-1 的基础上加一个最优决策就可以了。易得出状态转移方程:fi=f

16、i-1+maxmaxak|1=kmaxi,max2*(sk-smaxi)+ak|maxik=n其中 k 表示待选决策(已经选过的不能再选) , maxi 表示 fi-1 的决策序列 中最大的一个决策。解释一下:因为maxi左边的决策k不会增加距离,只增加推销的疲劳值ak; 而 maxi 右边的决策 k 不仅会增加疲劳值, 还会使距离从 smaxi 增加到 sk , 来回还要x 2,也就是增加了 2*(sk-smaxi)+ak枚举k的话时间复杂度是O(n2)的,只能得60分。做到这里,优化已经很明显了。对于 maxi 的左边,我们需要动态求区间 ak最值,无论是堆、线段树、优先级队列、集合,时间

17、复杂度都是 log 2n 级别的;而对于 maxi 右边,由于所有决策疲劳值都要减去 smaxi ,所以我们只要求区 间 2*sk+ak 的最值,而且可用决策必然是不断减少的,可以预处理排个递 减序,每次找第一个合法决策。当然,左边的方法对于右边同样适用。同时, 如果选择了右边的决策k,还需要将maxi到k之间的决策加入到左边的待选决 策中。(因为它们的身份已经从右边的点变成了左边的点) 。 由于每个决策最多从右边出一次,从左边进一次、出一次,均摊时间复杂度是 O(nlog 2n) , 能得 100 分。(可惜考试时多写了一个“ ”,编译错误, 400变成了 300) 【时空复杂度】O(nlo

18、g 2n), O(n) (取决于使用的数据结构)【样例程序】heap:#include#include usingnamespacestd;constintmaxn=100000;intn;intsmaxn+1,amaxn+1,fmaxn+1; intleftmaxn+1,rightmaxn+1,l,r=1,maxi;boolcmpl(constinti,constintj)if(ai!=aj)returnaij;boolcmpr(constinti,constintj)if(2*si+ai!=2*sj+aj)return2*si+ai2*sj+aj;elsereturnij;voidinit

19、()freopen(salesman.in,r,stdin);freopen(salesman.out,w,stdout);scanf(%d,&n);for(inti=1;i=n;i+)scanf(%d,&si);for(inti=1;i=n;i+)scanf(%d,&ai);righti=i;sort(right+1,right+n+1,cmpr);voidchoose_left(constinti)fi=fi-1+aleft1;pop_heap(left+1,left+l-+1,cmpl);voidchoose_right(constinti)fi=fi-1+2*(srightr-smax

20、i)+arightr;for(inti=maxi+1;irightr;i+)left+l=i;push_heap(left+1,left+l+1,cmpl);maxi=rightr+;while(r=n&rightr=maxi)r+;voidsolve()for(inti=1;in)choose_left(i);elseif(aleftl=2*(srightr-smaxi)+arightr)choose_left(i);elsechoose_right(i);voidoutput()for(inti=1;i=n;i+)printf(%dn,fi);fclose(stdin);fclose(st

21、dout);intmain()init();solve();output();return0;set:#include#includeusingnamespacestd;constintmaxn=100000;intn;intsmaxn+1,amaxn+1,fmaxn+1; intleftmaxn+1,rightmaxn+1,l,r=1,maxi; boolcmpl(constinti,constintj)if(ai!=aj)returnaij;boolcmpr(constinti,constintj)if(2*si+ai!=2*sj+aj) return2*si+ai2*sj+aj;else

22、returnij;voidinit()freopen(salesman.in,r,stdin);freopen(salesman.out,w,stdout);scanf(%d,&n);for(inti=1;i=n;i+)scanf(%d,&si);for(inti=1;i=n;i+)scanf(%d,&ai);righti=i;sort(right+1,right+n+1,cmpr); voidchoose_left(constinti)fi=fi-1+aleft1;pop_heap(left+1,left+l-+1,cmpl); voidchoose_right(constinti)fi=f

23、i-1+2*(srightr-smaxi)+arightr;for(inti=maxi+1;irightr;i+)left+l=i; push_heap(left+1,left+l+1,cmpl);maxi=rightr+;while(r=n&rightr=maxi)r+;voidsolve()for(inti=1;in) choose_left(i);elseif(aleftl=2*(srightr-smaxi)+arightr) choose_left(i);elsechoose_right(i);voidoutput()for(inti=1;i=n;i+)printf(%dn,fi);f

24、close(stdin);fclose(stdout);intmain()init();solve();output();return0;priority_queue:#include#include constintmaxn=100000;usingnamespacestd;intn;intsmaxn+1,amaxn+1,fmaxn+1,maxi; classcmplpublic:booloperator()(constinti,constintj)returnaiaj;classcmprpublic:booloperator()(constinti,constintj)if(2*si+ai

25、!=2*sj+aj) return2*si+aij;priority_queueint,vector,cmplleft; priority_queueint,vector,cmprright; voidinit()freopen(salesman.in,r,stdin); freopen(salesman.out,w,stdout); scanf(%d,&n);for(inti=1;i=n;i+)scanf(%d,&si);for(inti=1;i=n;i+)scanf(%d,&ai);right.push(i);voidchoose_left(constinti)fi=fi-1+aleft.

26、top();left.pop(); voidchoose_right(constinti)intr=right.top();fi=fi-1+2*(sr-smaxi)+ar;for(inti=maxi+1;ir;i+)left.push(i);maxi=r;while(!right.empty()&right.top()=maxi)right.pop();voidsolve()for(inti=1;i=2*(sr-smaxi)+ar)choose_left(i);elsechoose_right(i);voidoutput()for(inti=1;i=n;i+) printf(%dn,fi);fclose(stdin);fclose(stdout);intmain()init();solve();output();return0;鉴于set和priority_queue 属于C+STL实现起来可能较宏观、容易,但效率会略比 heap 低一些。自测时 heap 约 0.43s ,set 约 0.7s ,priority_queue 约 0.94s 。

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1