算法竞赛入门经典(算法实现)_第1页
算法竞赛入门经典(算法实现)_第2页
算法竞赛入门经典(算法实现)_第3页
算法竞赛入门经典(算法实现)_第4页
算法竞赛入门经典(算法实现)_第5页
已阅读5页,还剩575页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

(算法实现)第2章算法设计与优化2.1算法优化策略2.4动态规划算法3.4组合游戏3.6矩阵和线性方程组第4章数据结构4.1基础数据结构4.2区间信息维护4.3排序二叉树4.4树的经典问题与方法4.6离线算法4.7kd-Tree4.8可持久化数据结构4.9嵌套和分块数据结构第5章字符串5.1Trie、KMP以及AC自动机第6章计算几何6.1二维几何基础6.2与圆有关的计算问题6.3二维几何常用算法6.4三维几何基础6.5几何专题算法7.2最短路问题isthequestion".Tobeornottobe,''quoththe//陈锋EQ\*jc3\*hps20\o\al(\s\up13(ch),w)EQ\*jc3\*hps27\o\al(\s\up1(e),c)EQ\*jc3\*hps20\o\al(\s\up13("};),EO)1|算法分析请参考:《算法竞赛入门经典(第2版)》例题3-1大的顺序输出。usingnamespacestd;_for(i,a,b)for(inti=(a);i<(b);++intn,a,cnt[MAXN+4];fill_n(cnt,MAXNfor(i,0,n)scanf("td",for(i,0,MAXN)_for(jprintf("%dss",i,(i--MAXN-166j--cnt[i]-1)?""for(i,0,MAXN)_for(j}算法分析请参考:《算法竞赛入门经典——训练指南》升级版1.3节例题17注意:本题中的fill_n函数比memset更方便,性能更好【代码实现】如果还要精益求精,可以优化输入输出,进一步降低运行时间,程序如下。//刘汝佳EQ\*jc3\*hps30\o\al(\s\up5(charEQ\*jc3\*hps30\o\al(\s\up5(char),whil)EQ\*jc3\*hps30\o\al(\s\up3(c),e)EQ\*jc3\*hps30\o\al(\s\up2(g),s)EQ\*jc3\*hps30\o\al(\s\up3(a),t)//为了使用isdigit宏})buf[p++]=i810,i})//声明为全局变量可以减小开销p=0;if(i<0)putchar('-'),i=//特殊情况:i等于0时需要输出0,而不是什么也不输出j=p-1;j>=0;j--)putchar('O'+buf[j]);//逆序输出EQ\*jc3\*hps30\o\al(\s\up8(int),wh)EQ\*jc3\*hps30\o\al(\s\up8(,),n)EQ\*jc3\*hps30\o\al(\s\up8(1),r)EQ\*jc3\*hps30\o\al(\s\up8(0),e)EQ\*jc3\*hps30\o\al(\s\up8(;),i)EQ\*jc3\*hps19\o\al(\s\up11(,0,),st)EQ\*jc3\*hps30\o\al(\s\up5(=),0)EQ\*jc3\*hps30\o\al(\s\up5(1),;)EQ\*jc3\*hps19\o\al(\s\up6(if),f)EQ\*jc3\*hps19\o\al(\s\up6(fi),r)EQ\*jc3\*hps19\o\al(\s\up6(ha),0)}})输入一个字符串,判断它是否为回文串以及镜像串。输入字符串保证不含数字0。所谓和原串相同,如2S和3AIAE。注意,并不是每个字符在镜像之后都能得到一个合法字符。在本题中,每个字符的镜像如图1-1所示(空白项表示该字符镜像后不能得到一个合法字CharacterReverseCharacterReverseCharacterR输入的每行包含一个字符串(保证只有上述字符,不含空白字符),判断它是否为回文串和镜像串(共4种组合)。每组数据之后输出一个空行。【样例输入】【样例输出】NOTAPALINDROME--isnotapalISAPALINILAPASI--isaregularpalindrome.ATOYOTA-isamirroredpalindrome.EQ\*jc3\*hps19\o\al(\s\up10(",s),e)if(s[i]!=s[len-1-i])p=0;//不是回文串if(r(s[i])!=s[len-1-i])m=0;//不是镜像串)}算法分析请参考:《算法竞赛入门经典(第2版)》例题3-3注意:本题中输入字符串应该使用scanf而不是gets,以避免出现读入空行的问题长度为n的环状串有n种表示方法,分别为从某个位置开始顺时针得到的字母序列。例在这些表示法中,字典序最小的称为“最小表示”。样式对应该串所有表示方法中的一种表示法,你的任务是输出该环状串的最小表示。例如,【代码实现】//刘汝佳intless_than(conststringss,intintn=s.lengthcharcp=s[(P+i)8n]))ios::sync_with_stdio(false),)1例1-5【二进制;输入技巧;调试技巧】信息解码(MessageDecoding,ACM/ICPCWF考虑下面的01串序列:首先是长度为1的串,然后是长度为2的串,以此类推。如果看成二进制,相同长度的后一个串等于前一个串加1。注意,上述序列中不存在全为1的串。你的任务是编写一个解码程序。首先输入一个编码头(如AB#TANCnrtXc),则上述序列的每个串依次对应编码头的每个字符。例如,0对应A,00对应B,01对应#,…,110对应X,0000对应c。接下来是编码文本(可能由多行组成,你应当把它们拼成一个长长的01串)。编码文本由多个小节组成,每个小节的前3个数字代表小节中每个编码的长度(用二进制表示,例如010代表长度为2),然后是各个字符的编码,以全1结束(例如,编码长度为2的小节以11结束)。编码文本以编码长度为000的小节结束。例如,编码头为$#**\,编码文本为0100000101101100011100101000,应这样解码:010(编码长度为2)00(#)00(#)10(*)11(小节结束)011(编码长度为3)000(\)111(小节结束)001(编码长度为1)0($)1(小节结束)000(编码结束)。【代码实现】//此版本保留调试语句t11while(len--)v=v*2+readchar)memset(code,0,sizeof(c11EQ\*jc3\*hps22\o\al(\s\up7(o),o)EQ\*jc3\*hps22\o\al(\s\up7(i),r)EQ\*jc3\*hps22\o\al(\s\up7(i),e)EQ\*jc3\*hps22\o\al(\s\up7(nt),n)EQ\*jc3\*hps22\o\al(\s\up7(d),1)))intlenwread_bin_Inif(vm=(1<<len)-1)break;putchar(code[len][v]EQ\*jc3\*hps15\o\al(\s\up6(1),p)11算法分析请参考:《算法竞赛入门经典(第2版)》例题4-4例1-6【排序和查找】大理石在哪儿(WhereistheMarble?,UVa10474)现有N个大理石,每个大理石上写了一个非负整数。首先把各数从小到大排序,然后回答Q个问题。首先回答是否有一个大理石上写着某个整数x,如果是,还要回答哪个大理石上写着x。排序后的大理石从左到右编号为1~N(在样例中,为了节约篇幅,所有大理石上的数合并到一行,所有问题也合并到一行)。【样例输入】5【样例输出】【代码实现】EQ\*jc3\*hps25\o\al(\s\up11(int),fo)EQ\*jc3\*hps25\o\al(\s\up11(m),t)EQ\*jc3\*hps25\o\al(\s\up11(];),n)for(inti=0;i<n;i++)scanf(for(inti=0;i<n;i++)scanf(intp=lower_bound(a,a+n,x)-a;//在已排序数组a中寻找x))}算法分析请参考:《算法竞赛入门经典(第2版)》例题5-1注意:本题中lower_bound函数的使用,这里它返回的是指针,通过减法运算可以得到其在数组中的位置例1-7【stack;set实现集合操作】集合栈计算机(TheSetStackComputer,ACM/ICPCNWERC2006,U每次操作后,输出栈顶集合的大小(即元素个数)。例如,栈顶元素是A={{},{{}}},下一个元素是B={{},{{{}}}},则:UNION操作将得到{{},{{}},{{{}}}},输出3。ADD操作将得到{{},{{{}}},{{}typedefset<int>Set;//查找给定集合x的ID。如果找不到,分配一个新IDif(IDcache.count(x))returnIDcache[x];returnIDcache[x]-Setcache.size()-1;)//把集合映射成ID//添加新集合EQ\*jc3\*hps25\o\al(\s\up9(in),o)//题目中的栈if(op[01=='P')s.push(ID(empty));elseiftop[0]=='D')s.push(s.top());constSet6x1=SetcachelsconstSet6x2=SetcachelsEQ\*jc3\*hps29\o\al(\s\up10(l),o)set_union(x1.begin(),x1.end(),x2.begEQ\*jc3\*hps29\o\al(\s\up6(i),o)EQ\*jc3\*hps29\o\al(\s\up6(n),p)EQ\*jc3\*hps29\o\al(\s\up6(se),0])EQ\*jc3\*hps29\o\al(\s\up6(x),x)EQ\*jc3\*hps29\o\al(\s\up6(n),x)EQ\*jc3\*hps29\o\al(\s\up5(;),e))cout<<Setcache[s.top()].size()<<end1;)))算法分析请参考:《算法竞赛入门经典(第2版)》例题5-5注意:本题中对于set_unton以及set_intersection的使用#)while(cin>>s66s.front()!='#')words.pusfor(size_ti=0;1<worif(cnt[repr(words[1])]==1)ans.push_back(EQ\*jc3\*hps23\o\al(\s\up8(s),f)EQ\*jc3\*hps23\o\al(\s\up8(o),o)EQ\*jc3\*hps23\o\al(\s\up8(r),r)EQ\*jc3\*hps23\o\al(\s\up8(a),i)EQ\*jc3\*hps23\o\al(\s\up8(n),z)EQ\*jc3\*hps23\o\al(\s\up8(i),0)EQ\*jc3\*hps23\o\al(\s\up8(n),;)EQ\*jc3\*hps23\o\al(\s\up8(,ans.),<ans)EQ\*jc3\*hps23\o\al(\s\up8(en),si)EQ\*jc3\*hps23\o\al(\s\up8(d),z))例1-9【queue的使用】团体队列(TeamQueue,UVa540)有t个团队的人正在排一个长队。每次新来一个人时,如果他有队友在排队,那么这个新人会插队到最后一个队友的身后。如果没有任何一个队友排队,则他会排到长队的队尾。输入每个团队中所有队员的编号,要求支持如下3种指令(前两种指令可以穿插进行)。【代码实现】typedefqueue<int>IntQ;for(intt,kase-1;scanf("%d",6t)--165t;kase表示编号为x的人所在的团队编号while(n--)scanf("%d",6x),team[}IntQtq,qs[maxt];//tq是团队的队列,而qs[i]是团队i成员的队列for(intx;scanf("%s",cmd)=-1&5EQ\*jc3\*hps20\o\al(\s\up5(cmd[),Int)printf("%d\n",q.front()),q·pop(if(q.empty())tq.push(team[x]);//)}}算法分析请参考:《算法竞赛入门经典(第2版)》例题5-6注意:队列的出队操作由front()获取队头元素以及pop()组成图1-3数据库EQ\*jc3\*hps22\o\al(\s\up5(EQ\*jc3\*hps22\o\al(\s\up5(si),it)EQ\*jc3\*hps22\o\al(\s\up5(.f),g)EQ\*jc3\*hps22\o\al(\s\up5(i),:)EQ\*jc3\*hps22\o\al(\s\up3(n),:)EQ\*jc3\*hps22\o\al(\s\up4(,l),s)EQ\*jc3\*hps22\o\al(\s\up3(o),s)EQ\*jc3\*hps22\o\al(\s\up5(+),gt)/1本程序只是为了演示5TL各种用法,效率较低。实践中一般用c字符串和哈希表来实现typedefpair<int,int>PII;constintmaxr·10000+5,maxe-1intm,n,dh[maxr][maxc],cnt;)PIIp-make_pair(db[A][el],printf("sdtd\n",dtpl+1,1EQ\*jc3\*hps26\o\al(\s\up6(nt-),or)EQ\*jc3\*hps26\o\al(\s\up6(1),n)db[i](j】=ID(s,substr(lastpos+1,P-lastpos-1)111算法分析请参考:《算法竞赛入门经典(第2版)》例题5-9注意:本题中string的tind以及substr的使用BugHunt,ACM/IC例1-11【vector的使用】木块问题(TheBlocksProblem,UVa101)从左到右有n个木块,编号为0~n-1,要求模拟以下4种操作(a和b都是木块编号)。moveaontob:把a和b上方的木块全部归位,然后把a摞在b上方。moveaoverb:把a上方的木块全部归位,然后把a放在b所在木块堆的顶部。pileaontob:把b上方的木块全部归位,然后把a及其上方的木块整体摞在b上pileaoverb:把a及其上方的木块整体摞在b所在木块堆的顶部。所有操作结束后,输出每个位置的木块列表,按照从底部到顶部的顺序排列。【代码实现】usingnamespacestd;intN;//找木块a所在的pile和height,以引用的形式返EQ\*jc3\*hps30\o\al(\s\up3(intfi),intp)EQ\*jc3\*hps30\o\al(\s\up3(b),;)EQ\*jc3\*hps30\o\al(\s\up7(+),p)if(pile[p][h]==a)return}for(size_ti=h+1;i<s,s}//把木块b放回原位//pile只应保留下标0~h的元素EQ\*jc3\*hps30\o\al(\s\up8(void),vect)EQ\*jc3\*hps30\o\al(\s\up8(i),i)EQ\*jc3\*hps30\o\al(\s\up7(,i),p)EQ\*jc3\*hps30\o\al(\s\up6(n),];)}for(autox:pile[i])printf("%))for(inti-0;i<N;i++)pile[i].push_back(iEQ\*jc3\*hps30\o\al(\s\up4(p),a)EQ\*jc3\*hps30\o\al(\s\up4(n),p)EQ\*jc3\*hps30\o\al(\s\up4(d),b)EQ\*jc3\*hps30\o\al(\s\up4(ock),ntin)EQ\*jc3\*hps30\o\al(\s\up4(h),;)if(s1=="move")cle1输入一个文本,找出所有不同的单词(连续的字母序列),按字典序从小到大输出。单road.Thesignread:"Disneyl【样例输入】【样例输出(为了节约篇幅只保留前5行)】a【代码实现】//陈锋usingnamespacestd;for(size_ti=0;1<s.les[i]=isalpha(s[i])?tofor(set<string>::iteratorsit-dict.begin();sit!-d例1-13【priority_queue的使用】丑数(UglyNumbers,UVa136)丑数是指不能被2,3,5以外的其他素数整除的数。把丑数从小到大排列起来,结果如1,2,3,4,5,6,8,9,10,12,求第1500个丑数。【代码实现】//刘汝佳EQ\*jc3\*hps24\o\al(\s\up10(int),co)EQ\*jc3\*hps24\o\al(\s\up10(ain),int)for(inti=1;x=pq.top(),pq.if(!s.count(x2))s.insert(x2),pq)1例1-14【STL链表的使用】破损的键盘(又名“悲剧文本”)(BrokenKeyboard输入包含多组数据。每组数据占一行,包含不超过100000个字母、下画线、字符“[”【样例输入】【样例输出】#include<bits/stdc++.h>typedeflist<char>CL;EQ\*jc3\*hps19\o\al(\s\up13(i),')EQ\*jc3\*hps19\o\al(\s\up13(e.size),line)EQ\*jc3\*hps19\o\al(\s\up13(;),])EQ\*jc3\*hps19\o\al(\s\up13(1),;))))算法分析请参考:《算法竞赛入门经典(第2版)》例题6-4的使用注意:本题对STL中基于双向链表的容器list以及list::iterator的使用同类题目:士兵队列训练问题,HDU1276图1-4建筑俯视图与正视图输入每个建筑物左下角坐标(即x、y坐标的最小值)、宽度(即x方向的长度)、深度(即y方向的长度)和高度,以上数据均为实数,输出正视图中能看到的所有建筑物,按照左下角x坐标从小到大进行排序。左下角x坐标相同时,按y坐标从小到大排序。输入保证不同的x坐标不会很接近(即任意两个x坐标要么完全相同,要么差别足够大,不会引起精度问题)。【代码实现】//刘汝佳usingnamespacestd;)intN;boolcover(constBuildingsb,doboolvisible(conatBuildingab,doublemx)(//判断建筑物1在x=mx处是否可见if(!cover(b,mx))ret)EQ\*jc3\*hps27\o\al(\s\up4(r),v)EQ\*jc3\*hps27\o\al(\s\up4(n),c)EQ\*jc3\*hps27\o\al(\s\up4(t),t)EQ\*jc3\*hps27\o\al(\s\up4(k),u)EQ\*jc3\*hps27\o\al(\s\up4(ase),ble)EQ\*jc3\*hps27\o\al(\s\up4(1;),X)EQ\*jc3\*hps27\o\al(\s\up4(s),;)EQ\*jc3\*hps18\o\al(\s\up7(i),])scanf(“81f%1f%1F%1f%1f”,6b.x,6b.y,EQ\*jc3\*hps27\o\al(\s\up2(a),;)1sort(B,B+N),sort(X.beintm=unique(X.begin(),X.end())-X.begin();//x坐标排序去重printf("FormapMd,thefEQ\*jc3\*hps27\o\al(\s\up8(ka),or)nboolvis=false;EQ\*jc3\*hps18\o\al(\s\up9(;j),[)EQ\*jc3\*hps18\o\al(\s\up9(-),1))}}算法分析请参考:《算法竞赛入门经典(第2版)》例题5-12注意:引用变量的使用,在函数中传递引用类型参数可以节省内存复制时间,简化代码长度本章讲解的例题及其囊括的知识点,如表1-1所示。例1-1陈锋陈锋二进制:输入技巧:调试技巧陈锋stack;set实现集合操作map的使用qucue的使用陈锋map的妙用例1-11vector的使用set的使用陈锋priorityqueue的使用STL链表的使用陈锋第2章算法设计与优化有一些题目并不需要巧妙的思路和缜密的推理,就能找到一个解决方案,只是时间效率难以令人满意。降低时间复杂度的方法有很多,本小节的题目就覆盖了其中最常见的一些给出N(1≤N<10000且N为奇数)个大小不超过10的正整数,计算这些整数的中位【代码实现】//陈锋intN,A[NN];EQ\*jc3\*hps23\o\al(\s\up11(s),f)EQ\*jc3\*hps23\o\al(\s\up11(,),0)EQ\*jc3\*hps23\o\al(\s\up11(6),;)EQ\*jc3\*hps23\o\al(\s\up11(N),1)例2-2【线性扫描;前缀和;单调性】子序列(Subsequenc有n(10<n≤100000)个正整数组成一个序列,给定整数S(S<10),连续序列,使它们的和大于或等于S。【代码实现】求长度最短的//刘汝佳intA[maxn],B[maxn];n,S;scanf("&d8d",6n,8S)--2i=1;1<=n;i++)scanf(=n+1,i=1;i=1;i<=n;i++)B[i]-B[i-1]for(intj=1;j<=n;j++){EQ\*jc3\*hps19\o\al(\s\up8([),[)EQ\*jc3\*hps19\o\al(\s\up8(j),i)EQ\*jc3\*hps19\o\al(\s\up8(tin),B[)EQ\*jc3\*hps19\o\al(\s\up8(u),j)}//(1)没有满足条件的i,换下一个j//(2)求满足B[i-1]<=B[j]-s的最大iprintf("%d\n",ans==n算法分析请参考:《算法竞赛入门经典——训练指南》升级版1.3节例题21注意:本题中for嵌套while循环的时间复杂度是O(n),而不是0(n^2)//陈锋_for(i,a,b)for(int1=(a);1<(b);++EQ\*jc3\*hps28\o\al(\s\up8(f),n)EQ\*jc3\*hps28\o\al(\s\up7(o),t)EQ\*jc3\*hps28\o\al(\s\up7(,0,),m)EQ\*jc3\*hps28\o\al(\s\up8(anf),0],)EQ\*jc3\*hps28\o\al(\s\up8(&),ns)_for(i,1,n)ans=max(m-A[i],ans),m=m例2-4【Floyd判圈】计算器谜题(CalculatorConundrum,UVa11549)有一个老式计算器,只能显示n位数字。有一天,你无聊了,于是输入一个整数k(1≤n≤9,0≤k<10),然后反复平方,直到溢出。每次溢出时,计算器会显示结果的最高n位和一个错误标记。然后,清除错误标记,继续平方。如果一直这样做下去,能得到的最大数是多少?比如,当F1,k=6时,计算器将依次显示6、3(36的最高位),9、8(81的最高位),6(64的最高位),3,…【代码实现】#define_for(i,a,b)for(inttypedeflonglongLL;]EQ\*jc3\*hps25\o\al(\s\up9(M),f)EQ\*jc3\*hps25\o\al(\s\up9(1),r)EQ\*jc3\*hps25\o\al(\s\up11(e),x)EQ\*jc3\*hps25\o\al(\s\up11(s),s)EQ\*jc3\*hps25\o\al(\s\up11(ma),ax)EQ\*jc3\*hps25\o\al(\s\up11(a),n)EQ\*jc3\*hps25\o\al(\s\up11(n),s)EQ\*jc3\*hps25\o\al(\s\up11(s),,)EQ\*jc3\*hps25\o\al(\s\up11(;),;))」算法分析请参考:《算法竞赛入门经典——训练指南》升级版1.3节例题1910,-6},D={-16,30,77,-46,62,45},则有5种选法:(-45,-27,42,30),(26,30,-10,EQ\*jc3\*hps23\o\al(\s\up6(t),i)EQ\*jc3\*hps23\o\al(\s\up6(mai),T)EQ\*jc3\*hps23\o\al(\s\up6({),c)EQ\*jc3\*hps27\o\al(\s\up9(can),or)EQ\*jc3\*hps27\o\al(\s\up9(&),n)scanf("%did%d)d",6A[i],6B[iEQ\*jc3\*hps33\o\al(\s\up9(=0),or)for(intj=0;J<n;j++)EQ\*jc3\*hps23\o\al(\s\up8(lon),fo)EQ\*jc3\*hps23\o\al(\s\up8(g),r)EQ\*jc3\*hps23\o\al(\s\up8(lo),nt)EQ\*jc3\*hps23\o\al(\s\up8(t),1)EQ\*jc3\*hps23\o\al(\s\up8(fo),p)EQ\*jc3\*hps23\o\al(\s\up8(r),a)})EQ\*jc3\*hps17\o\al(\s\up12(/*),算)例2-6【滑动窗口】唯一的雪花(UniqueSnowflakes,UVa11572)输入一个长度为n(n≤10)的序列A,找到一个尽量长的连续子序列A~A,使得该序【代码实现】#define_for(i,a,b)for(inti=(a);1<(b);++i)typedeflonglongLL;scanf("8d",6T);iEQ\*jc3\*hps26\o\al(\s\up5(fo),nt)r(i,0,nEQ\*jc3\*hps26\o\al(\s\up5("),1)EQ\*jc3\*hps26\o\al(\s\up5(,),,);//【L,R),滑动窗口长度最大值set<int>s={A[L]);//当前窗口中的所有元素,C++11的容器初始化语法ws.count(A[R])66L<R)s.erase(A[)算法分析请参考:《算法竞赛入门经典(第2版)》例题8-7f(3),…,f(n-k+1)。例如,对于序列{5,2,6,8,10,7,4},k=4,则f(1)=2,EQ\*jc3\*hps27\o\al(\s\up12(usingn),#defin)EQ\*jc3\*hps27\o\al(\s\up12(a),e)ios::sync_with_stdio(falwhile(head<tail66Q[head]<=i-K)++head;EQ\*jc3\*hps27\o\al(\s\up8(ile),ta)EQ\*jc3\*hps27\o\al(\s\up7(a),;)4f(1>=K-1)cout<<A[Q[head]]<<(i==N-1//单调递增队列//删除过期元素//保持单调性//顶端是最小元素EQ\*jc3\*hps19\o\al(\s\up7(调递),Q[)EQ\*jc3\*hps19\o\al(\s\up7(减队列),head)EQ\*jc3\*hps19\o\al(\s\up7(端),i)EQ\*jc3\*hps19\o\al(\s\up7(最),K)EQ\*jc3\*hps19\o\al(\s\up7(素),h)EQ\*jc3\*hps27\o\al(\s\up8(ile),ta)EQ\*jc3\*hps27\o\al(\s\up7(a),;)if(i>=K-1)cout<<A[Q算法分析请参考:《算法竟赛入门经典(第2版)》8.5节滑动窗口部分注意:本题队列使用左闭右开区间,必须使用手写的队列而不是deque,才能够通过时限不会被照到,因为它们从来没有经过图中矩形的内部。图2-1流星相机的左下角为(0,0),右上角为(w,h)(1≤w;h≤100000)。每个流星用两个向量p比如,若p=(1,3),v=(-2,5),则t=0.5时该流星的位置为(1,3)+0.5×(-2,5)=(0,【代码实现】EQ\*jc3\*hps36\o\al(\s\up5(EQ\*jc3\*hps36\o\al(\s\up5(0an;),ty)EQ\*jc3\*hps36\o\al(\s\up5(s1),p)//刘汝佳voidupdate(intx,Inta,Intw,doublesEQ\*jc3\*hps15\o\al(\s\up5(el),L))))//先处理右端点scanf("*d",6T);EQ\*jc3\*hps22\o\al(\s\up4(d",),w)EQ\*jc3\*hps22\o\al(\s\up4(6),,)tdoubleL-0,R-le)))算法分析请参考:《算法竞赛入门经典——调练指南》升级版1.3节例题20另外,本题还可以完全避免实数运算,全部采用整数。只需要把代码中的double全部改成int,然后在update函数中把所有返回值乘以1cm(1,2,…,10)=2520即可(想一想,为什么)。EQ\*jc3\*hps38\o\al(\s\up2147483641(×),0)EQ\*jc3\*hps27\o\al(\s\up16(a,i),R)EQ\*jc3\*hps27\o\al(\s\up16(i),;)EQ\*jc3\*hps27\o\al(\s\up16({),无)L=max(L,-x*2520R=min(R,(w-x)*2520L=max(L,(w-x)*2520/a);R=min(R,-x)}例2-9【逆序对数计算】参谋(Brainman,POJ1804)给出长度为N的数组,计算通过多少次相邻元素的交换操作,可以将其变为升序。【代码实现】EQ\*jc3\*hps20\o\al(\s\up7(cop),int)EQ\*jc3\*hps20\o\al(\s\up7(+1),a)EQ\*jc3\*hps20\o\al(\s\up7(+),1)EQ\*jc3\*hps20\o\al(\s\up7(r),,)EQ\*jc3\*hps20\o\al(\s\up7(,B),b)//归并排序,求A(1,r)的逆序对数mid=(1+r)/2,ans-merge(1,mid)+merge(mif(]=B[a++];&6B[else//左边所有比B[b]大的数分别与B[b]构成逆序对EQ\*jc3\*hps28\o\al(\s\up8(sca),for)EQ\*jc3\*hps28\o\al(\s\up8(f),i)EQ\*jc3\*hps28\o\al(\s\up10(sca),for)EQ\*jc3\*hps28\o\al(\s\up10(f),i)EQ\*jc3\*hps28\o\al(\s\up10(6),1)printf("Scenario#%d:\n&d\n]*算法分析请参考:《算法竞赛入门经典(第2版)》8.2.1节归并排序、逆序对问题注意:本题中归并排序的合并部分仅仅使用了一个循环本节例题列表本节讲解的例题及其囊括的知识点,如表2-1所示。例2-1陈锋陈锋中途相遇陈锋滑动窗口滑动窗口:单调队列陈锋陈锋贪心算法是一种解决问题的策略。如果策略正确,那么贪心算法往往是易于描述和实现的。本节给出可以用贪心算法解决的若干经典问题的代码实现。例2-10【贪心】装箱(BinPacking,SWERC2005,UVa1149)给定N(N≤10)个物品的重量L,背包的容量M,要求每个背包最多装两个物品。求至【代码实现】#define_for(i,a,b)for(inti=(a);i<(int)(b);+intn,1,EQ\*jc3\*hps27\o\al(\s\up8(s),i)EQ\*jc3\*hps27\o\al(\s\up8(o),n)EQ\*jc3\*hps27\o\al(\s\up8(r),t)EQ\*jc3\*hps27\o\al(\s\up8(en,),an)EQ\*jc3\*hps27\o\al(\s\up8(rea),0,r)EQ\*jc3\*hps27\o\al(\s\up8(t),i)EQ\*jc3\*hps27\o\al(\s\up8(t>),n)EQ\*jc3\*hps33\o\al(\s\up8(s+),le)EQ\*jc3\*hps33\o\al(\s\up7(e),!)EQ\*jc3\*hps33\o\al(\s\up8(+),r)}})算法分析请参考:《算法竞赛入门经典——习题与解答》习题8-1注意:本题使用了双指针扫描法EQ\*jc3\*hps31\o\al(\s\up5(o),i)EQ\*jc3\*hps31\o\al(\s\up5(t),s)EQ\*jc3\*hps31\o\al(\s\up5(or),b)EQ\*jc3\*hps31\o\al(\s\up5(<),r)EQ\*jc3\*hps31\o\al(\s\up5(cons),turn)EQ\*jc3\*hps31\o\al(\s\up5(e),b)EQ\*jc3\*hps31\o\al(\s\up5(s),b)for(intn;scanf("8d",6n)==166n;)(for(inti-0;i<n;i++)scanf("&d)d"if(A[i].a>=cur_b)ans++,cur_b=A[i].b;}算法分析请参考:《算法竞赛入门经典(第2版)》8.4.2节选择不相交区间idefine_for(l,a,b)forstructPointfEQ\*jc3\*hps24\o\al(\s\up6(do),Po)EQ\*jc3\*hps24\o\al(\s\up6(x),u)EQ\*jc3\*hps24\o\al(\s\up6(,),b)EQ\*jc3\*hps24\o\al(\s\up6(;),e)return)douhlem-sqrt(D*D-p.Y*p.y)EQ\*jc3\*hps17\o\al(\s\up5(boo),do)EQ\*jc3\*hps17\o\al(\s\up5(l),u)EQ\*jc3\*hps17\o\al(\s\up5(s),e)EQ\*jc3\*hps17\o\al(\s\up5(gc),y)EQ\*jc3\*hps17\o\al(\s\up5(m),d)EQ\*jc3\*hps17\o\al(\s\up5(co),d)EQ\*jc3\*hps17\o\al(\s\up5(n),c)EQ\*jc3\*hps17\o\al(\s\up5(st),m)EQ\*jc3\*hps17\o\al(\s\up5(S),s)EQ\*jc3\*hps17\o\al(\s\up5(e),1)EQ\*jc3\*hps17\o\al(\s\up5(me),y)EQ\*jc3\*hps17\o\al(\s\up5(t),s)EQ\*jc3\*hps17\o\al(\s\up5(6),r))_for(i,0,N)segs,push_back(getInterseg(pointa(1)EQ\*jc3\*hps24\o\al(\s\up2(or),nt)EQ\*jc3\*hps24\o\al(\s\up2(q),;)doublep-segs[0].y;for(size_t1-1;1<segif(dcmp(cur.x-prev,x)<0)if(dcmp(cur.x-p)>0)P=cur.y11while(cin>>L>for(1,0,N)cin>>points[1].x>>points[1].y;1)EQ\*jc3\*hps13\o\al(\s\up10(/*),算)选点问题例2-13【贪心;区间覆盖】喷水装置(WateringGrass,UVa10382)有一块草坪,长为1,宽为w。在其中心线的不同位置处装有n(1≤n≤10000)个点状的喷水装置。每个喷水装置i可将以它为中心,半径为r的圆形区域喷湿(见图2-2)。请选择尽量少的喷水装置,把整个草坪全部喷湿。输出需要打开的喷水装置数目的最小值。图2-2喷水装置【代码实现】EQ\*jc3\*hps15\o\al(\s\up5(ub),1t)EQ\*jc3\*hps15\o\al(\s\up5(double),EPS)EQ\*jc3\*hps15\o\al(\s\up5(1),r)1inlinebooloperator<(cons1intsolve(constvector<Seg>6sdoublesif(dcmp(seg=[i].a-start)>0)return-1:while(1<segs.size()6ssegs[1].a<=staif(demp(sege[1].b-end)>0)end)tor(intn,1,w;scanf("%dsdld",6n,61,sw)--3;)tEQ\*jc3\*hps22\o\al(\s\up7(ect),or)EQ\*jc3\*hps22\o\al(\s\up7(<),n)EQ\*jc3\*hps22\o\al(\s\up7(s),,)EQ\*jc3\*hps15\o\al(\s\up8(if),d)EQ\*jc3\*hps15\o\al(\s\up8(·2),u)EQ\*jc3\*hps15\o\al(\s\up8(<-),b)continue;xw-sqrt({double)r·r-W2*w2),a-P-xw;EQ\*jc3\*hps15\o\al(\s\up9(」),s)ort(segs.begin(),segs.end(printf("\d\n",solve(segs,len1算法分析请参考:《算法竞赛入门经典(第2版)》8.4.2节区间覆盖问题EQ\*jc3\*hps15\o\al(\s\up6(注意),同类)EQ\*jc3\*hps15\o\al(\s\up6(使用dcmp),Cleanin)EQ\*jc3\*hps15\o\al(\s\up6(浮点数),Shifts)EQ\*jc3\*hps15\o\al(\s\up6(做),,P)EQ\*jc3\*hps15\o\al(\s\up6(比),O)EQ\*jc3\*hps15\o\al(\s\up6(较),J)2EQ\*jc3\*hps15\o\al(\s\up6(避免),376)了浮点误差returnj>x.j;//运算符重载,不要忘记const修饰符)ios::sync_with_stdio(falEQ\*jc3\*hps25\o\al(\s\up11(ect),or)EQ\*jc3\*hps25\o\al(\s\up11(<Jo),nt)EQ\*jc3\*hps25\o\al(\s\up4(sor),int)EQ\*jc3\*hps25\o\al(\s\up4(v.b),an)EQ\*jc3\*hps25\o\al(\s\up4(e),s)EQ\*jc3\*hps25\o\al(\s\up4(n),0)//当前任务的开始执行时间//任务执行完毕时的最晚时间)))算法分析请参考:《算法竞赛入门经典——训练指南》升级版1.1节例题2表2-2贪心算法例题归纳贪心陈锋例2-11贪心;选择不相交区间陈锋例2-12贪心:区间选点陈锋例2-13陈锋贪心法求最优排列陈锋2.3搜索算法(字典顺序)列出,如=3时,列出{1,2,3},{1,3,2},{2,1,3},{2,3,1},{3,1,2},例如,F3,k=2给出排列{2,3,1},则它的下一个排列为{3,1,2},下2个排列为//陈锋EQ\*jc3\*hps25\o\al(\s\up9(s),f)EQ\*jc3\*hps25\o\al(\s\up9(8),t)dEQ\*jc3\*hps25\o\al(\s\up9(8),1)EQ\*jc3\*hps25\o\al(\s\up9(n),1)EQ\*jc3\*hps25\o\al(\s\up9(K),n)for(inti=0;i<K;i++)next_perfor(inti=0;i<n;++i))}算法分析请参考:《算法竞赛入门经典(第2版)》7.2.1节生成1~n的排列//陈锋while(next_permutation(s.begin(),s.)【代码实现】例2-17【BFS搜索最短路径】Abbott的复仇(Abbott’sRevenge,ACM/ICPCWF有一个最多包含9×9个交叉点的迷宫。输入起点、离开起点时的朝向和终点,求一条最短路径(多解时任意输出一个即可)。这个迷宫的特殊之处在于:进入一个交叉点的方向(用N、E、W、S这4个字母分别表示北、东、西、南,即上、右、左、下)不同,允许出去的方向也不同。例如,“12WLFNRER*”表示交叉点(1,2)(上数第1行,左数第2列)有3个路标(字符“*”只是结束标志)。如果进入该交叉点时的朝向为W(即朝左),则可以左转(L)或者直行(F);如果进入时朝向为N或者E,则只能右转(R),如图2-3所示。图2-3迷宫及走向例如,图2-3中从交叉口(3,1)进入并到达目标交叉口(3,3)的一条最短路径为(3,1),intr,c,dir;//站在(r,c),面朝方向dir(0~3分别表示N,E,S,W)Node(intr=0,intc=0,intEQ\*jc3\*hps19\o\al(\s\up7(,0),旋)EQ\*jc3\*hps19\o\al(\s\up7(-1};),转)Nodep[NN][NN][4];intdir_id(charc)freturnstrchr(dirs,c)-dirs;)if(turn==1)dir=(dir+3)64;//逆时针if(turn==2)dir=(dir+1)84;//顺时针returnNode(u.r+dr[dir],u.c+dc[dir],dir);}boolboolr,intc)(returnr>=166r<=966c>=166c<=9;if(scanf("8s8d8d%s&did",s,6r0,6c0,s2,6r2,6c2)!-6)returnfalse;【代码实现】EQ\*jc3\*hps32\o\al(\s\up8(ri),ir)EQ\*jc3\*hps32\o\al(\s\up8(tf),d)EQ\*jc3\*hps32\o\al(\s\up8(n"),s2)EQ\*jc3\*hps32\o\al(\s\up6(s),0),r1=r0+dr[dir],cl-c0+dc[dir];memset(has_edge,0,sizeof(has_edge));EQ\*jc3\*hps26\o\al(\s\up7(whi),for)EQ\*jc3\*hps26\o\al(\s\up7(e),s)EQ\*jc3\*hps26\o\al(\s\up7(f),t)EQ\*jc3\*hps26\o\al(\s\up7(s),1)EQ\*jc3\*hps26\o\al(\s\up7(s),1)EQ\*jc3\*hps26\o\al(\s\up7(1),s)EQ\*jc3\*hps26\o\al(\s\up7(6s),trl)has_edge[r][e][dir_id(s[0])][turn_id(s[i])))//从目标结点逆序追溯到初始结点if(d[u.r][u.c][u.dir]=)nodes.push_back(Node(r0,c0,dEQ\*jc3\*hps26\o\al(\s\up5(f),i)EQ\*jc3\*hps26\o\al(\s\up5(-),f)EQ\*jc3\*hps26\o\al(\s\up5(o),")printf("(8d,td)",nodes[1],r,nodes[1].))EQ\*jc3\*hps18\o\al(\s\up9(N),d)EQ\*jc3\*hps18\o\al(\s\up9(de),u)EQ\*jc3\*hps18\o\al(\s\up9(u),u)EQ\*jc3\*hps18\o\al(\s\up9(1),r)ir);Nodeu-q,front();EQ\*jc3\*hps26\o\al(\s\up8(o),u)EQ\*jc3\*hps18\o\al(\s\up11(No),if)EQ\*jc3\*hps18\o\al(\s\up11(e),h)EQ\*jc3\*hps18\o\al(\s\up11(v),e)EQ\*jc3\*hps18\o\al(\s\up11(w),u)EQ\*jc3\*hps18\o\al(\s\up11(lk),r)EQ\*jc3\*hps34\o\al(\s\up4(d),p)EQ\*jc3\*hps34\o\al(\s\up4(v),v)EQ\*jc3\*hps34\o\al(\s\up4(.),.)EQ\*jc3\*hps34\o\al(\s\up4(r),r)EQ\*jc3\*hps34\o\al(\s\up4(v),v)EQ\*jc3\*hps34\o\al(\s\up4(.),.)EQ\*jc3\*hps34\o\al(\s\up4(c),c)EQ\*jc3\*hps34\o\al(\s\up4(v),v)EQ\*jc3\*hps34\o\al(\s\up4(.),.)EQ\*jc3\*hps34\o\al(\s\up4(d),d)EQ\*jc3\*hps34\o\al(\s\up4(i),i)EQ\*jc3\*hps34\o\al(\s\up4(r),r)EQ\*jc3\*hps34\o\al(\s\up4(d),u)EQ\*jc3\*hps34\o\al(\s\up4([),;)一)puts("NoSolutionPossible");1while(read_case())sol)算法分析请参考:《算法竞赛入门经典(第2版)》例题6-14注意:本题中通过对4个方向统一编码,减少了大量的分支判断代码例2-18【BFS;路径查找优化】万圣节后的早晨(TheMorningafterHalloween,图2-4题设局面图2-54种移动方式#define_for(1,a,b)for(inti=(a);1<(int)(b);++i)typedeflonglongLL;constintDX[]*{-1,1,0,0,0},DY[]-{0,0,-1,intW,H,N,V,ID[16][16],X[MAXV],Y[MAXV];intD[MAXV][MAXV][MAXV],Src[3],Dest[3];EQ\*jc3\*hps29\o\al(\s\up3(inli),ass)EQ

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论