安徽省年度“达内杯”程序设计大赛解题报告58.docx
n更多企业业学院:中小企企业管理理全能版版183套套讲座+897700份份资料总经理理、高层层管理49套讲讲座+1163888份资料中层管管理学院院46套讲讲座+660200份资料 国学智智慧、易易经46套讲讲座人力资资源学院院56套讲讲座+2271223份资料各阶段段员工培培训学院院77套讲讲座+ 3244份资料员工管管理企业业学院67套讲讲座+ 87220份资料工厂生生产管理理学院52套讲讲座+ 139920份份资料财务管管理学院院53套讲讲座+ 179945份份资料 销售经经理学院院56套讲讲座+ 143350份份资料销售人人员培训训学院72套讲讲座+ 48779份资料安徽省220111“达内内杯”程程序设计计大赛解解题报告告A-幸运运数字此题只需需题目描描述解即即可,没没有任何何算法和和triick.#inccludde <<iosstreeam>>usinng nnameespaace stdd;int maiin() intt n; whiile (sccanff("%d", &nn) != EEOF) innt tt = n, s = 0; whhilee (tt) ss += t % 110; tt /= 100; iff (nn % s = 00) pprinntf("yeesnn"); ellse priintff("nnonn"); retturnn 0;B-转换换二叉树树首先根根据先序序序列和和中序序序列建立立二叉树树,然后后按要求求先序遍遍历一遍遍二叉树树即可。当然,由由于建树树过程实实际也是是在先序序遍历二二叉树,所所以可以以不用实实际建树树,只是是模拟那那个过程程,然后后再过程程中输出出即可。建树过过程简单单的说就就是以先先序序列列定根节节点,以以中序序序列和和和根节点点定左右右子树。#inccludde <<iosstreeam>>#inccludde <<strringg.h>>usinng nnameespaace stdd;consst iint maxxn = 277;int N;charr PrreOrrderrmaaxn, IInOrrderrmaaxn;voidd DFFS(iint PreeStaart, innt PPreEEnd, innt IInSttartt, iint InEEnd) intt poos; forr (ppos = IInSttartt; PPreOOrdeerPPreSStarrt != InOOrdeerppos; ppos+) if (poos != IInSttartt) prrinttf(""("); DFFS(PPreSStarrt + 1, PrreSttartt + poss - InSStarrt, InSStarrt, poss - 1); prrinttf("")"); priintff("%c", PrreOrrderrPrreSttartt); if (poos != IInEnnd) prrinttf(""("); DFFS(PPreSStarrt + poos - InnStaart + 11, PPreEEnd, poos + 1, InnEndd); prrinttf("")"); int maiin() intt i, leen; scaanf("%dd", &N); gettchaar(); forr (ii = 0; i << N; i+) sccanff("%s %s", PrreOrrderr, IInOrrderr); leen = sttrleen(PPreOOrdeer); DFFS(00, llen - 11, 00, llen - 11); prrinttf(""n""); retturnn 0;C-取石石子首先给给出必胜胜结论,只只要n != 2xx,则先先手必胜胜。证明明:假设设n = 122,将它它转换为为二进制制则为''11000'。先手手第一次次取只需需把二进进制中从从低位数数起第一一个'1'取走即即可。在在这个例例子中,先先手留给给后手石石子数的的二进制制为'110000'。这这样后手手能取的的石子数数的二进进制范围围为'000011'-''01000',无无论后手手怎么取取,它都都不可能能把所有有数字都都取完,而而且取了了之后剩剩下的石石子数的的二进制制后3位位肯定有有一个''1'。先手只只需再次次将从低低位数起起的第一一个'11'取走走即可重重复上述述过程直直至游戏戏结束。而如果果先手第第一次面面对的石石子数是是2xx个,由由于他第第一次不不能把石石子都取取完,所所以他无无论如何何取都会会把上述述必胜状状态留给给对手。同样根根据上述述证明方方法可以以证明如如果先手手必胜,那那么他第第一次取取的最少少石子数数就是石石子数的的二进制制中,从从低位数数起的第第一个''1'。#inccludde <<iosstreeam>>usinng nnameespaace stdd;int maiin() intt n, t; whiile (sccanff("%d", &nn) != EEOF) t = 11; whhilee (!(n & 11) nn >>>= 11; tt <<<= 11; iff (nn = 1) prrinttf(""lossenn"); ellse priintff("wwin %dn", t); retturnn 0;D-关键键词统计计这题最最佳解法法是先建建立单词词的字典典树,然然后再把把文章中中的单词词一个一一个抠出出来进行行匹配,时时间复杂杂度是OO(m+n)。m是文文章长度度,n是是单词总总长度。但是省省赛时我我们数据据放得比比较松,只只要是把把单词一一个一个个抠出来来比较的的都能过过。#inccludde <<iosstreeam>>usinng nnameespaace stdd;consst iint maxxn = 1001622;consst iint maxxm = 20000005;struuct Nodde intt neext26; intt inndexx; voiid iinitt() meemseet(nnextt, -1, sizzeoff(neext); inndexx = -1; tiiremaxxn*55;charr sttrmmaxmm, worrd550;int cunntmmaxnn, nxttmaaxn, ssz, idxx;voidd innserrt(ccharr *ss) intt p = 00; whiile (*ss) innt vv = *s - ''a' iff (ttireep.neextv = -1) ttireep.neextv = +szz; ttireeszz.iinitt(); p = ttireep.neextv; s+; nxttiddx = ttireep.inndexx; tirrepp.iindeex = iddx+;voidd fiind(chaar *s) intt p = 00; whiile (*ss) innt vv = *s - ''a' iff (ttireep.neextv = -1) rretuurn; p = ttireep.neextv; s+; forr (pp = tirrepp.iindeex; p != -1; p = nxxtpp) cuuntp+;booll loowerrcasse(cconsst ccharr &cc) retturnn 'aa' <<= cc &&& c <= 'z''booll uppperrcasse(cconsst ccharr &cc) retturnn 'AA' <<= cc &&& c <= 'Z''int maiin() intt n, i, t; getts(sstr); scaanf("%dd%*cc", &n); memmsett(cuunt, 0, 4 * nn); tirre00.iinitt(); forr (ii = 0; i << n; i+) sccanff("%s", woord); innserrt(wwordd); forr (ii = t = 0; ; i+) iff (lloweercaase(strri) wworddt+ = sstri; ellse if (uppperrcasse(sstri) wworddt+ = sstri + 332; ellse if (t) wworddt = '00' ffindd(woord); tt = 0; iff (!strri) bbreaak; forr (ii = 0; i << n; i+) prrinttf(""%dn", cuunti); retturnn 0;E-搬书书这题很很多人可可能想复复杂了,比比赛中有有的队是是用DPP过的。但其实实只要对对体积进进行二分分,然后后暴力法法测试即即可。二二分体积积时间复复杂度OO(loogd),测试试时间复复杂度OO(n+m)。所以总总的时间间复杂度度是O(n+m)llogdd),其其中d是是箱子体体积最大大可能值值和最小小可能值值之差,nn是书的的数量,mm是箱子子的数量量。#inccludde <<iosstreeam>>usinng nnameespaace stdd;consst iint maxxn = 10000;int vmmaxnn;int maiin() intt n, m; intt maaxv, miinv; intt leeft, riightt, mmid, cuunt, pttr, leaave; whiile (sccanff("%d %d", &nn, &&m) != EOFF) maaxv = mminvv = 0; foor (intt i = 00; ii < n; i+) sscannf(""%d"", vv + i); mmaxvv += vi; iif (vii >> miinv) minnv = vi; leeft = mminvv, rrighht = maaxv; whhilee (lleftt < rigght) mmid = (lefft + riightt) / 2; ccuntt = 0; lleavve = 0; ffor (pttr = 0; pttr << n && cunnt <<= mm; pptr+) if (leeavee >= vptrr) leeavee -= vptrr; elsse leeavee = midd - vpptr; cuunt+; iif (cunnt <<= mm) rigght = mmid; eelsee lefft = miid + 1; prrinttf(""%dn", leeft); retturnn 0;F-水晶晶球假设少少女的相相貌、智智慧和财财富分别别是x、y和zz。首先先按x从从大到小小排序处处理掉一一维,然然后建立立一个mmap,它它的keey值是是y,vvaluue值是是z。然然后从头头到尾扫扫描所有有少女。每扫描描一个少少女时,在在mapp里找其其y值的的上界,如如果它的的上界对对应的zz要大于于少女的的z,则则说明有有少女无无论x、y还是是z都大大于她。否则将将这个少少女的yy值和zz值插入入到maap里,并并且将mmap里里的无用用数据删删去,无无论是yy还是zz都比少少女小的的值。当当然这样样粗略的的讲,还还有很多多问题是是被忽略略过去的的,比如如说边界界问题,两两个值相相同的问问题,如如何删去去mapp中的无无用数据据等,这这个大家家可以参参考标程程。#inccludde <<iosstreeam>>#inccludde <<csttdioo>#inccludde <<alggoriithmm>#inccludde <<mapp>usinng nnameespaace stdd;consst iint maxxn = 5000055;consst iint inff = 1000000000005;struuct Datta intt x, y, z; / 按x从从大到小小排,如如果x相相同,则则按y从从小到大大排,如如果y也也相同,则则按z从从小到大大排 boool ooperratoor << (cconsst DDataa &ooth) coonstt iff (xx != otth.xx) rretuurn x >> otth.xx; iff (yy != otth.yy) rretuurn y << otth.yy; reeturrn zz < othh.z; daatamaxxn;int n, anss;map<<intt, iint>> v;typeedeff maap<iint, innt>:itteraatorr ittr;int maiin() intt i; whiile (sccanff("%d", &nn) != EEOF) foor (i = 0; i < nn; ii+) sscannf(""%d"", &&dattaii.xx); foor (i = 0; i < nn; ii+) sscannf(""%d"", &&dattaii.yy); foor (i = 0; i < nn; ii+) sscannf(""%d"", &&dattaii.zz);v.ccleaar(); soort(datta, datta + n); vinff = -iinf; v-innf = iinf; foor (i = 0, anns = 0; i < nn; ii+) iitr x = v.uppper_bouund(dattaii.yy); iif (dattaii.zz < x->>seccondd) anss+; eelsee if (!vv.coountt(daatai.y) | vddataai.y < dattaii.zz) vdattaii.yy = daatai.z; foor (x = -v.lloweer_bbounnd(ddataai.y); xx->ssecoond <= dattaii.zz; ) vv.errasee(x-); prrinttf(""%dn", anns); retturnn 0;G-星际际航行这题是后后3题中中唯一有有队伍过过的题,其其实不算算很难。只要把把圆的向向量和长长方形的的向量合合并,然然后把题题目转换换成圆在在动,长长方形静静止或者者长方形形在动,圆圆静止这这样的模模型。然然后问题题就蜕化化为圆与与线段(长长方形的的边)相相撞的问问题。#inccludde <<iosstreeam>>#inccludde <<cmaath>>usinng nnameespaace stdd;#deffinee epps (1e-8)#deffinee zeero(x) (faabs(x)<<epss)struuct poiint douublee x, y; poiint() poiint(douublee a, dooublle bb) x=a; y=bb; poiint(poiint p1, poointt p22) x=p2.x-pp1.xx; yy=p22.y-p1.y; poiint opeerattor +(ppoinnt pp) reeturrn ppoinnt( x+pp.x, y+p.yy); ;doubble xmuult(poiint p1 ,poointt p22) retturnn p11.x*p2.y-pp2.xx*p11.y;doubble xmuult(poiint p1 ,poointt p22, ppoinnt pp0) retturnn (pp1.xx-p00.x)*(pp2.yy-p00.y)-(pp2.xx-p00.x)*(pp1.yy-p00.y);doubble dmuult(poiint p1, poointt p22)retturnn p11.x*p2.x+pp1.yy*p22.y;doubble disst(ppoinnt aa, ppoinnt bb) retturnn sqqrt(a.x-bb.x)*(aa.x-b.xx)+(a.yy-b.y)*(a.y-bb.y);doubble dissptoolinne(ppoinnt pp, ppoinnt ll1, poiint l2) retturnn faabs( xmmultt(p,l1,l2) ) / ddistt(l11,l22);booll crrossslinne(ppoinnt oo, ddoubble r, poiint v, poiint a, poiint b) if( zeero(v.xx) &&& zzeroo(v.y) ) rretuurn fallse; douublee d = xxmullt( v, poiint(a,bb) ); if( d<<=-eeps ) rretuurn fallse; if( d>>=epps ) dooublle dda = xmmultt( vv, ppoinnt(oo,a) ); dooublle ddb = xmmultt( vv, ppoinnt(oo,b) ); iff( (da>>=epps) (db>>=epps) ) rretuurn truue; poointt o11 = o+vv; iff( ddispptollinee(a, o, o11)-rr <=-epps ) reeturrn ttruee; iff( ddispptollinee(b, o, o11)-rr <=-epps ) reeturrn ttruee; reeturrn ffalsse; if( diispttoliine(o, a, b)-r>-epss ) retturnn faalsee; retturnn dmmultt(v, poointt(o,a) >= epps;booll crrosssfulll(ppoinnt aa, ppoinnt bb, ppoinnt cc, ppoinnt vv, ppoinnt oo, ddoubble r, poiint vo) poiint d = a+poiint(b,cc); poiint vs(v,vvo); retturnn crrossslinne(oo, rr, vvs, a, c) | croossllinee(o, r, vss, bb, dd);int maiin() poiint a, b, c, v, o, vo; douublee r; whiile(cinn>>aa.x>>>a.y>>>b.xx>>bb.y>>>c.x>>>c.yy>>vv.x>>>v.y>>>o.xx>>oo.y>>>r>>>voo.x>>>voo.y) coout<<<(ccrosssfuull(a,bb,c,v,oo,r,vo)?"YYES"":"NNO")<<eendll; retturnn 0;H-技术术员BaangFFu这题是是状态DDP,ddp状态态定为ddp11<<110107。第一一维是二二进制标标记走过过哪些节节点,第第二维是是最后到到达哪个个节点,第第三维是是时间是是星期几几,而数数组本身身的值为为最少花花费了多多少钱。最后用用Spffa递推推出所有有状态即即可。#inccludde <<iosstreeam>>#inccludde <<vecctorr>#inccludde <<queeue>>usinng nnameespaace stdd;consst iint N = 155;consst iint D = 7;consst iint INFF = 1000000000000;struuct Edgge intt y, p, t;struuct Nodde intt s, x, d;int n, m;int dp1<<<NND, mkk1<<<NND;vecttor<<Edgge> vNN;queuue<NNodee> qq;voidd Innit() intt i, j, k, x; Edgge ttmp; forr (ii = 0; i << n; i+) vi.cleear(); forr (ii = 0; i << m; i+) sccanff("%d %d %d %d", &xx, &&tmpp.y, &ttmp.p, &tmmp.tt); vx.pussh_bbackk(tmmp); forr (ii = 0; i << (11 <<< n); ii+) foor (j = 0; j < nn; jj+) ffor (k = 00; kk < D; k+) dpijk = IINF, mkkijk = 0; voidd Soolvee() Nodde nnow, nxxt; noww.s = 11, nnow.x = 0, noow.dd = 0; dpnoww.snoow.xxnnow.d = 00; mknoww.xnoow.xxnnow.d = 11; q.ppushh(noow); whiile (!qq.emmptyy() noow = q.froont(); q.popp(); innt &&x = noow.xx; innt &&p = dppnoow.ssnnow.xnoww.d; foor (intt i = 00; ii < vxx.ssizee(); i+) iint &y = vvxi.y; iif (!(nnow.s && (11 <<< y) nxtt.s = (noww.s | (1 <<< yy); nxtt.x = yy; nxtt.d = (noww.d + vvxi.t + 11) % 7; intt tpp = p + vxi.p; if (tpp < dpnxtt.snxxt.xxnnxt.d) dppnxxt.ssnnxt.xnxtt.d = tp; iff (!mknxtt.snxxt.xxnnxt.d) mmknnxt.snxtt.xnxxt.dd = 1; qq.puush(nxtt); voidd Chheckk() intt x, d, i; intt s = (1 <<< nn) - 1; intt miinp = IINF; boool fflagg1 = faalsee, fflagg2 = faalsee; forr (xx = 1; x << n; x+) foor (i = 0; i < vvx.siize(); i+) iif (vxxii.yy = 0) forr (dd = 0; d << D; d+) iff (ddpssxxdd << INNF) fflagg1 = trrue; iif (d + vvxi.t) % 7 >>= 55 &&& miinp > ddpssxxdd + vxi.p) minnp = dppsxd + vxxii.pp; flaag2 = ttruee;