求解什么是含有阶乘的求极限问题串零,这题为何这么解

相关文章推荐
------- android培训
以前在论坛里看过这个题,当是想:只要算下1-1000中有多少个个位数是5、0的数就可以了,坛友们也多是这么回复的,所以,我就想当然地认为自己是对的,也就没去好好地验证下这个问题
谁想,今天,我就被问...
例如给出n=100,那么就是计算0到100这么多个数中有多少个2.
首先要搞清楚2是怎么来的(这话怎么听起来不对劲?):
有2个来源:
1 个位来源:12,32,42,82,92,22等,其中的22可...
package com.
import java.math.BigI
import java.util.regex.M
import java.util....
容斥原理应用(求1~r中有多少个数与n互素)
分类: 数论
20:15 121人阅读 评论(0) 收藏 举报
问题:求1~r中有多少个数与n互素。
需求是给出一个文本文件,求出其中有多少个单词(不用判断单词是否为真的英语单词)。
分析:因为不需要判断是否为真的英语单词,这就简单多了。只要以空格,TAB,标点符号等非字母间隔的字符串都是单词(不考...
求目标串中有多少个位置可重叠的子串。
//在目标串中找有多少个子串,出现的子串在位置上上可以交叠
#includ...
转载自:点击打开链接
#define LL long long
int a[66]...
题目链接:hdu 3394
题意描述:公园有n个景点,公园的管理员计划要建m条道路,并且安排一些形成回路的参观路径,如果一条道路可以被多条回路共用,那么这条边是冲突边,如果不能形成环的路则为...
他的最新文章
讲师:董晓杰
讲师:姚远
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)滴滴出行2017秋招笔试编程题:末尾0的个数
o &nbsp,&nbsp&nbsp,&nbsp
输入一个正整数n,求n!(即阶乘)末尾有多少个0? 比如: n = 10; n! = 3628800,所以答案为2
输入为一行,n(1 ≤ n ≤ 1000)
输出一个整数,即题目所求
应该是等于n除以5的结果
关于伯乐小组
这里有好的话题,有启发的回复和值得信任的圈子。
新浪微博:
推荐微信号
(加好友请注明来意)
- 好的话题、有启发的回复、值得信赖的圈子
- 分享和发现有价值的内容与观点
- 为IT单身男女服务的征婚传播平台
- 优秀的工具资源导航
- 翻译传播优秀的外文文章
- 国内外的精选博客文章
- UI,网页,交互和用户体验
- 专注iOS技术分享
- 专注Android技术分享
- JavaScript, HTML5, CSS
- 专注Java技术分享
- 专注Python技术分享
& 2017 伯乐在线串的长度必须大于零_中华文本库
习题 4 串。 B.串的长度必须大于零 D.空串就是空白串 4.1 单项选择题 1.以下叙述中正确的是 A.串是一种特殊的线性表 C.串中无素只能是字母 2.空串与...
第4章 串习题一、 选择题 1、如下陈述中正确的是( ) A.串是一种特殊的线性表 B.串的长度必须大于零 C.串中元素只能是字母 D.空串就是空白串 2、设有...
串是一种特殊的线性表 C.串中元素只能是字母 ) B.串的长度必须大于零 D.空串就是空白串 ) B.front=(front+1)%(m-1) D.front=(front+1)%m 7.若...
串是一种特殊的线性表 B . 串的长度必须大于零 C . 串中元素只能是字母 D . 空串就是空白串 答案:B,C,D 解析: 39 . 对一个算法的评价,包括如下()...
A.串是一种特殊的线性表 B.串的长度必须大于零 C.串中无素只能是字母 D.空串就是空白串 3.串是一中特殊的线性表,其特殊性体现在___。 A. 可以顺序存储...
B.串的长度必须大于零 D.空串就是空白串 和。 。 第二阶段离线作业 3、空格串是 4、空串是 ,其长度等于 ,其长度等于 。。。 5、两个串相等的充分必要...
A. 串是一种特殊的线性表 C. 串中元素只能是字母 B. 串的长度必须大于零 D. 空串就是空白串 (35) 下列关于串的叙述中,正确的是 ___ D ___。 A. ...
串的长度必须大于零 C.串中元素只能是字母 D. 空串就是空白串 12.若将一个 10×10 阶的对称矩阵压缩存储到一个一维数组中,则该一维数组 的大小应该是( a ...
A.串是一种特殊的线性表 B.串的长度必须大于零 C.串中元素只能是字母 D.空串就是空白串 8. 一个非空广义表的表头( )。 A.不可能是子表 B.只能是子表...
习题4 4.1 单项选择题 串 1.以下叙述中正确的是 。 A.串是一种特殊的线性表 B.串的长度必须大于零 C.串中无素只能是字母 D.空串就是空白串 2.空串与...1 100的阶乘,末尾有几个连续的零?(如:2100的最后有2个零)
2 1到100的阶乘的和的末位数是几?
3 10000的阶乘,末尾有多少个连续的零?
解答和分析:
1 100的阶乘,末尾有几个连续的零?
答案是24。
思路有两个:
先讲笨方法,采用分类讨论的方法。你可以知道100的阶乘里有无数的2,比如8=2*2*2等等。而10是由2*5组成的,其他的数字无论怎么乘都都无法形成10。所以我们只要关注2和5即可。由于100的阶乘中2很多,它们都嗷嗷待哺的希望和5结合成10。你还应该注意到一个情况,25、50、75这三个比较特殊,25乘以若干个2会得到100,而50*2会得到100,而75乘以若干个2后会得到1500,所以这三个数会分别产生2个0。好了,现在可以开始数了,10、20..100有11个0,5、15..95有10个0,而25、50和75又会多产生1个0,所以11+10+3=24。
再讲巧方法:100/5+100/(5*5)=24。这是因为包括5这个因子的数有100/5=20个,而包含25因子的有100/25=4个,所以结果为24个。
2 1到100的阶乘的和的末位数是几?
这题找规律,1!=1; 2!=2; 3!=6; 4!=24; 5!=120;&你可以发现5的阶乘之后的末尾都是0。所以只有1到4的阶乘会产生个位数,所以1+2+6+24=33,所以答案就是3!
3 10000的阶乘,末尾有多少个连续的零?
答案: 00/25+000/625+=+16+3=2499
ps:关于第三题,如果谁有非常清晰的解答,希望能留言给我讲讲,呵呵~
阅读(...) 评论()tyvj部分题解_学霸学习网
tyvj部分题解
主站题库p1000 A+B Problem 【背景 】 为大家熟悉本系统创建本题! 【描述】 输入两个自然数,输出他们的和 【输入格式】 输出两个自然数 x,y 【输出格式】 一个数,即 x 和 y 的和 【样例输入】 125 300 【样例输出】 425 【时间限制】 各个测试点 1s 【题解】 这倒我就不讲了,没什么好注意。 【参考程序】 var a,b: begin readln(a,b); writeln(a+b); end. p1001 第 K 极值 【描述】 给定一个长度为 N(0&n&=10000)的序列,保证每一个序列 中的数字 a[i]是小于 maxlongint 的非负整数,编程要求 求出整个序列中第 k 大的数字减去第 k 小的数字的值 m,并 判断 m 是否为质数。(0&k&=n) 【输入格式】 第一行为 2 个数 n,k(含义如上题) 第二行为 n 个数,表示这个序列 【输出格式】 : 如果 m 为质数则 第一行为'YES'(没有引号) 第二行为这个数 m 否则 第一行为'NO' 第二行为这个数 m 【样例输入】 52 12345 【样例输出】 YES 2 【时间限制】 各个测试点 1s 【数据范围】 20%数据满足 0&n&=10 50%数据满足 0&n&=%数据满足 0&n&=10000 a[i]&=maxlongint 【注释】 对于第 K 大的详细解释: 如果一个序列为 1 2 2 2 2 3 第1大 为3 第2大 为2 第3大 为2 第4大 为2 第5大 为1 第 K 小与上例相反 另外需要注意的是 最小的质数是 2,如果小于 2 的话,请直接输出 NO 【题解】 这道题很简单,先快排,在按要求判断该数是否为素数。 注释里的话一定要看!(有很多人吃亏) ! 【参考程序】 var n,k,i: a:array[1..10000]procedure qs(l,r:longint); var i,j,m,t: begin i:=l; j:=r; m:=a[(l+r) DIV 2]; repeat while a[i]&m do inc(i); while a[j]&m do dec(j); if i&=j then begin t:=a[i]; a[i]:=a[j]; a[j]:=t; inc(i); dec(j); until i&j; if i&r then qs(i,r); if l&j then qs(l,j);function prime(x:longint): var i: begin if x&=1 then exit(false); if x=2 then exit(true); for i:=2 to trunc(sqrt(x)) do if x mod i=0 then exit(false); exit(true);begin readln(n,k); for i:=1 to n do read(a[i]); qs(1,n); if prime(a[n-k+1]-a[k])then writeln('YES') else writeln('NO'); writeln(a[n-k+1]-a[k]); end. p1002 谁拿了最多奖学金 【描述】 某校的惯例是在每学期的期末考试之后发放奖学金。发放的奖学金共有五种,获取的条件各自不同: 1)院士奖学金,每人 8000 元,期末平均成绩高于 80 分(&80) ,并且在本学期内发表 1 篇或 1 篇以上论文 的学生均可获得; 2)五四奖学金,每人 4000 元,期末平均成绩高于 85 分(&85) ,并且班级评议成绩高于 80 分(&80)的学 生均可获得; 3)成绩优秀奖,每人 2000 元,期末平均成绩高于 90 分(&90)的学生均可获得; 4)西部奖学金,每人 1000 元,期末平均成绩高于 85 分(&85)的西部省份学生均可获得; 5)班级贡献奖,每人 850 元,班级评议成绩高于 80 分(&80)的学生干部均可获得; 只要符合条件就可以得奖,每项奖学金的获奖人数没有限制,每名学生也可以同时获得多项奖学金。例如 姚林的期末平均成绩是 87 分,班级评议成绩 82 分,同时他还是一位学生干部,那么他可以同时获得五四 奖学金和班级贡献奖,奖金总数是 4850 元。 现在给出若干学生的相关数据,请计算哪些同学获得的奖金总数最高(假设总有同学能满足获得奖学金的 条件) 。 【输入格式】 输入的第一行是一个整数 N(1&=N&=100) ,表示学生的总数。接下来的 N 行每行是一位学生的数据,从 左向右依次是姓名,期末平均成绩,班级评议成绩,是否是学生干部,是否是西部省份学生,以及发表的 论文数。姓名是由大小写英文字母组成的长度不超过 20 的字符串(不含空格) ;期末平均成绩和班级评议 成绩都是 0 到 100 之间的整数(包括 0 和 100) ;是否是学生干部和是否是西部省份学生分别用一个字符表 示,Y 表示是,N 表示不是;发表的论文数是 0 到 10 的整数(包括 0 和 10) 。每两个相邻数据项之间用一 个空格分隔。 【输出格式】 输出包括三行,第一行是获得最多奖金的学生的姓名,第二行是这名学生获得的奖金总数。如果有两位或 两位以上的学生获得的奖金最多,输出他们之中在输入文件中出现最早的学生的姓名。第三行是这 N 个学 生获得的奖学金的总数。 【样例输入】 4 YaoLin 87 82 Y N 0 ChenRuiyi 88 78 N Y 1 LiXin 92 88 N N 0 ZhangQin 83 87 Y N 1 【样例输出】 ChenRuiyi
【题解】 快排+字符串处理,仔细一点就可以 AC。 【参考程序】 var n,i,j,k,l,max: b,c,f,g:array[1..100] a,d,e:array[1..100] st: var i,l: s,t: begin readln(n); for i:=1 to n do begin readln(s); l:=pos(' ',s); a[i]:=copy(s,1,l-1); delete(s,1,l); l:=pos(' ',s); t:=copy(s,1,l-1); val(t,b[i]); delete(s,1,l); l:=pos(' ',s); t:=copy(s,1,l-1); val(t,c[i]); delete(s,1,l); l:=pos(' ',s); d[i]:=copy(s,1,l-1); delete(s,1,l); l:=pos(' ',s); e[i]:=copy(s,1,l-1); delete(s,1,l); val(s,f[i]); fillchar(g,sizeof(g),0); for i:=1 to n do begin if (b[i]&80)and(f[i]&=1)then inc(g[i],8000); if (b[i]&85)and(c[i]&80)then inc(g[i],4000); if b[i]&90 then inc(g[i],2000); if (b[i]&85)and(e[i]='Y')then inc(g[i],1000); if (c[i]&80)and(d[i]='Y')then inc(g[i],850); max:=0; l:=0; for i:=1 to n do begin l:=l+g[i]; if g[i]&max then begin max:=g[i]; st:=a[i]; writeln(st); writeln(max); writeln(l); end. P1003 越野跑 【描述】 为了能在下一次跑步比赛中有好的发挥,贝茜在一条山路上开始了她的训练。贝茜希望能在每次训练中 跑得尽可能远,不过她也知道农场中的一条规定: 奶牛独自进山的时间不得超过 M 秒(1 &=M&=10,000,000)。 整条山路被贝茜划分成 T 个长度相同的小段(1 &= T &= 100,000),并且,贝茜用 S_i 表示第 i 个小段的路况。 S_i 为 u,f,d 这 3 个字母之一,它们分别表示 第 i 个小段是上坡、平地,或是下坡。 贝茜要花 U 秒(1&=U&=100)才能跑完一段上坡路,跑完一段平地的耗时是 F 秒(1&=F&=100),跑完一段 下坡路要花 D 秒(1&=D&=100)。注意,沿山路原路返回的时候,原本是上坡路的路段变成了下坡路,原本 是下坡路的路段变成 了上坡路。 贝茜想知道,在能按时返回农场的前提下,她最多能在这条山路上跑多远。 【输入格式】 * 第 1 行: 5 个用空格隔开的整数:M,T,U,F,以及 D *第 2..T+1 行:第 i+1 行为 1 个字母 S_i,描述了第 i 段山路的路况 【输出格式】 *第 1 行:输出 1 个整数,为贝茜在按时回到农场的前提下,最多能跑到多远 【样例输入】 13 5 3 2 1 u f u d f 【样例输出】 3 【题解】 模拟一下跑步的过程。用 s 记录跑到第 i 段路并返回的时间 若 s=m 则输出 i 并退出,若 s&m 则输出 I-1 并退出。 【参考程序】 var i,s,m,t,u,f,d: a:array[1..100000] begin readln(m,t,u,f,d); for i:=1 to t do readln(a[i]); s:=0; for i:=1 to t do begin case a[i] of 'u':s:=s+u+d; 'f':s:=s+2*f; 'd':s:=s+u+d; if s&= if s=m then writeln(i); if s&m then writeln(i-1); end. p1004 滑雪 【描述】 trs 喜欢滑雪。他来到了一个滑雪场,这个滑雪场是一个矩形,为了简便,我们用 r 行 c 列的矩阵来表示 每块地形。为了得到更快的速度,滑行的路线必须向下倾斜。 例如样例中的那个矩形,可以从某个点滑向上下左右四个相邻的点之一。例如 24-17-16-1,其实 25-24-23?3-2-1 更长,事实上这是最长的一条。 【输入】 第 1 行: 两个数字 r,c(1&=r,c&=100),表示矩阵的行列。 第 2..r+1 行:每行 c 个数,表示这个矩阵。 【输出】 仅一行: 输出 1 个整数,表示可以滑行的最大长度。 【样例输入】 55
18 19 6 15 24 25 20 7 14 23 22 21 8 13 12 11 10 9 【样例输出】 25 【题解】 这道题用动态规划+记忆化搜索求解 【参考程序】 const dx:array[1..4]of -1..1=(-1,0,1,0); dy:array[1..4]of -1..1=(0,-1,0,1); var i,j,r,c,max,t: a:array[1..100,1..100] f:array[1..100,1..100]function dfs(x,y:longint): var i,nx,ny,t,temp: begin if f[x,y]&0 then begin dfs:=f[x,y]; t:=1; for i:=1 to 4 do begin nx:=x+dx[i]; ny:=y+dy[i]; if(nx&0)and(nx&=r)and(ny&0)and(ny&=c)then if a[x,y]&a[nx,ny] then begin temp:=dfs(nx,ny)+1; if temp&t then t:= f[x,y]:=t; dfs:=t;begin readln(r,c); for i:=1 to r do for j:=1 to c do read(a[i,j]); max:=0; fillchar(f,sizeof(f),0); for i:=1 to r do for j:=1 to c do begin t:=dfs(i,j); f[i,j]:=t; if t&max then max:=t; writeln(max); end. p1005 采药 【描述】 辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。 医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对他说: “孩子,这 个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。我会给你一段时间, 在这段时间里, 你可以采到一些草药。 如果你是一个聪明的孩子, 你应该可以让采到的草药的总价值最大。 ” 如果你是辰辰,你能完成这个任务吗? 【输入格式】 输入文件 medic.in 的第一行有两个整数 T(1 &= T &= 1000)和 M(1 &= M &= 100) ,用一个空格隔开, T 代表总共能够用来采药的时间,M 代表山洞里的草药的数目。接下来的 M 行每行包括两个在 1 到 100 之 间(包括 1 和 100)的整数,分别表示采摘某株草药的时间和这株草药的价值。 【输出格式】 输出文件 medic.out 包括一行,这一行只包含一个整数,表示在规定的时间内,可以采到的草药的最大总价 值。 【样例输入】 70 3 71 100 69 1 12 【样例输出】 3 【题解】 这道题一眼就看出来是 0/1 背包。 用 f[j]表示在时间 j 内的最大采集价值。 则 f[j]:=max{f[j],f[j-t[i]+v[i]} (1&=i&=m,T&=j&=a[i]); 【参考程序】 var t,m,i,j: a,b:array[1..100] f:array[0..1000] begin fillchar(f,sizeof(f),0); readln(t,m); for i:=1 to m do readln(a[i],b[i]); for i:=1 to m do for j:=t downto a[i] do if f[j-a[i]]+b[i]&f[j] then f[j]:=f[j-a[i]]+b[i]; writeln(f[t]); end.p1006 isbn 【描述】 每一本正式出版的图书都有一个 ISBN 号码与之对应,ISBN 码包括 9 位数字、1 位识别码和 3 位分隔符, 其规定格式如“x-xxx-xxxxx-x” ,其中符号“-”就是分隔符(键盘上的减号) ,最后一位是识别码,例如 0-670-82162-4 就是一个标准的 ISBN 码。ISBN 码的首位数字表示书籍的出版语言,例如 0 代表英语;第一 个分隔符“-”之后的三位数字代表出版社,例如 670 代表维京出版社;第二个分隔符后的五位数字代表该 书在该出版社的编号;最后一位为识别码。 识别码的计算方法如下: 首位数字乘以 1 加上次位数字乘以 2??以此类推,用所得的结果 mod11,所 得的余数即为识别码,如果余数为 10,则识别码为大写字母 X。例如 ISBN 号码 0-670-82162-4 中的识别码 4 是这样得到的:对
这 9 个数字,从左至右,分别乘以 1,2,...,9,再求和,即 0×1+6×2+?? +2×9=158,然后取 158 mod 11 的结果 4 作为识别码。 你的任务是编写程序判断输入的 ISBN 号码中识别码是否正确,如果正确,则仅输出“Right” ;如果错误, 则输出你认为是正确的 ISBN 号码。 【输入格式】 输入文件 isbn.in 只有一行,是一个字符序列,表示一本书的 ISBN 号码(保证输入符合 ISBN 号码的格式 要求) 。 【输出格式】 输出文件 isbn.out 共一行,假如输入的 ISBN 号码的识别码正确,那么输出“Right” ,否则,按照规定的格 式,输出正确的 ISBN 号码(包括分隔符“-”。 ) 【样例输入】 【样例 1】 0-670-82162-4 【样例 2】 0-670-82162-0 【样例输出】 【样例 1】 Right 【样例 2】 0-670-82162-4 【题解】 这道题模拟一下就可以。noip 总有一些送分题。 【参考程序】 const a:array['0'..'9']of longint=(0,1,2,3,4,5,6,7,8,9); var t,i,j,k: s: begin readln(s); k:=0; for i:=1 to length(s)-2 do if s[i] in ['0'..'9'] then begin inc(k); t:=t+k*a[s[i]]; t:=t mod 11; if(t=10)and(s[length(s)]='X')then begin writeln('Right'); if t=a[s[length(s)]] then begin writeln('Right'); for i:=1 to length(s)-1 do write(s[i]); if t&10 then writeln(t) else writeln('X'); end. p1007 排座椅 【描述】 上课的时候总有一些同学和前后左右的人交头接耳,这是令小学班主任十分头疼的一件事情。不过,班主 任小雪发现了一些有趣的现象,当同学们的座次确定下来之后,只有有限的 D 对同学上课时会交头接耳。 同学们在教室中坐成了 M 行 N 列,坐在第 i 行第 j 列的同学的位置是(i,j) ,为了方便同学们进出,在教 室中设置了 K 条横向的通道,L 条纵向的通道。于是,聪明的小雪想到了一个办法,或许可以减少上课时 学生交头接耳的问题:她打算重新摆放桌椅,改变同学们桌椅间通道的位置,因为如果一条通道隔开了两 个会交头接耳的同学,那么他们就不会交头接耳了。请你帮忙给小雪编写一个程序,给出最好的通道划分 方案。在该方案下,上课时交头接耳的学生对数最少。 【输入格式】 输入的第一行, 5 各用空格隔开的整数, 有 分别是 M, N,K, D(2&=N, L, M&=1000, 0&=K&M,0&=L&N, D&=2000) 。接下来 D 行,每行有 4 个用空格隔开的整数,第 i 行的 4 个整数 Xi,Yi,Pi,Qi,表示坐在位 置(Xi,Yi)与(Pi,Qi)的两个同学会交头接耳(输入保证他们前后相邻或者左右相邻) 。输入数据保证最优方案 的唯一性。 【输出格式】 第一行包含 K 个整数,a1a2??aK,表示第 a1 行和 a1+1 行之间、第 a2 行和第 a2+1 行之间、?、第 aK 行和第 aK+1 行之间要开辟通道,其中 ai& ai+1,每两个整数之间用空格隔开(行尾没有空格) 。 第二行包含 L 个整数,b1b2??bk,表示第 b1 列和 b1+1 列之间、第 b2 列和第 b2+1 列之间、?、第 bL 列和第 bL+1 列之间要开辟通道,其中 bi&bi+1,每两个整数之间用空格隔开(行尾没有空格) 。 【样例输入】
【样例输出】 2 24 【题解】 快排+贪心,每次选能隔开最多人数的排和列。最后快排一下就可以了。 【参考程序】 type arr=array[1..1000] var n,m,k,l,d,i,j: x,y,p,q:array[1..2000] hang,lie,b,c:procedure qs(l,r:var a:arr); var i,j,m,t: begin i:=l; j:=r; m:=a[(l+r) div 2]; repeat while a[i]&m do inc(i); while a[j]&m do dec(j); if i&=j then begin t:=a[i]; a[i]:=a[j]; a[j]:=t; t:=b[i]; b[i]:=b[j]; b[j]:=t; inc(i); dec(j); until i&j; if i&r then qs(i,r,a); if l&j then qs(l,j,a);begin fillchar(hang,sizeof(hang),0); fillchar(lie,sizeof(lie),0); readln(m,n,k,l,d); for i:=1 to d do read(x[i],y[i],p[i],q[i]); for i:=1 to m-1 do for j:=1 to d do if y[j]=q[j] then if (x[j]+p[j])div 2=i then inc(hang[i]); for i:=1 to n-1 do for j:=1 to d do if x[j]=p[j] then if (y[j]+q[j])div 2=i then inc(lie[i]); for i:=1 to m do b[i]:=i; qs(1,m,hang); for i:=k downto 1 do c[i]:=b[i]; qs(1,k,c); for i:=k downto 2 do write(c[i],' '); writeln(c[1]); for i:=1 to n do b[i]:=i; qs(1,n,lie); for i:=l downto 1 do c[i]:=b[i]; qs(1,l,c); for i:=l downto 2 do write(c[i],' '); writeln(c[1]); end. p1008 传球游戏 【描述】 上体育课的时候,小蛮的老师经常带着同学们一起做游戏。这次,老师带着同学们一起做传球游戏。 游戏规则是这样的:n 个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球, 每个同学可以把球传给自己左右的两个同学中的一个 (左右任意) 当老师再次吹哨子时, , 传球停止, 此时, 拿着球没传出去的那个同学就是败者,要给大家表演一个节目。 聪明的小蛮提出一个有趣的问题:有多少种不同的传球方法可以使得从小蛮手里开始传的球,传了 m 次以 后,又回到小蛮手里。两种传球的方法被视作不同的方法,当且仅当这两种方法中,接到球的同学按接球 顺序组成的序列是不同的。比如有 3 个同学 1 号、2 号、3 号,并假设小蛮为 1 号,球传了 3 次回到小蛮手 里的方式有 1-&2-&3-&1 和 1-&3-&2-&1,共 2 种。 【输入格式】 输入文件 ball.in 共一行,有两个用空格隔开的整数 n,m(3&=n&=30,1&=m&=30) 。 【输出格式】 输出文件 ball.out 共一行,有一个整数,表示符合题意的方法数。 【样例输入】 33 【样例输出】 2 【题解】 动态规划 f[i,k]表示球在人 i 手中,传 k 此的方案 s 数 每次球总是从 i-1 人或 i+1 人手中传过来,所以 f[i,k]:=f[i-1,k-1+f[i+1,k-1]; (1&=i&=n,1&=k&=m) 输出[f1,m]。 边界:f[1,0]:=1;(传 0 次,方案数为 1). 注意处理 i=1 和 i=n 的情况。 【参考程序】 var i,k,n,m: f:array[1..30,0..30] begin readln(n,m); fillchar(f,sizeof(f),0); f[1,0]:=1; for k:=1 to m do begin f[1,k]:=f[n,k-1]+f[2,k-1]; for i:=2 to n-1 do f[i,k]:=f[i-1,k-1]+f[i+1,k-1]; f[n,k]:=f[1,k-1]+f[n-1,k-1]; writeln(f[1,m]); end. p1010 笨小猴 【描述】 笨小猴的词汇量很小,所以每次做英语选择题的时候都很头疼。但是他找到了一种方法,经试验证明,用 这种方法去选择选项的时候选对的几率非常大! 这种方法的具体描述如下:假设 maxn 是单词中出现次数最多的字母的出现次数,minn 是单词中出现次数最 少的字母的出现次数,如果 maxn-minn 是一个质数,那么笨小猴就认为这是个 Lucky word 这样的单词很可 能就是正确的答 案。 【输入格式】 输入只有一行,是一个单词,其中只可能出现小写字母,并且长度小于 100。 【输出格式】 输出共两行,第一行是一个字符串,假设输入的的单词是 Lucky Word,那么输出“Lucky Word” ,否则输 出“No Answer” ; 第二行是一个整数,如果输入单词是 Lucky Word,输出 maxn-minn 的值,否则输出 0。 【样例输入】 输入样例 1 error 输入样例 2 olympic 【样例输出】 输出样例 1 Lucky Word 2 输出样例 2 No Answer 0 【题解】 简单的字符串处理+素数判断 【参考程序】 var max,min,j: a:array['a'..'z'] s: i:function prime(x:longint): var i: begin if x&=1 then exit(false); if x=2 then exit(true); for i:=2 to trunc(sqrt(x)) do if x mod i=0 then exit(false); exit(true);begin fillchar(a,sizeof(a),0); readln(s); for j:=1 to length(s) do inc(a[s[j]]); max:=0; min:=100; for i:='a' to 'z' do if a[i]&&0 then begin if a[i]&max then max:=a[i]; if a[i]&min then min:=a[i]; if prime(max-min) then begin writeln('Lucky Word'); writeln(max-min); end else begin writeln('No Answer'); writeln(0); end. p1011 传纸条 【描述】 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题。一次素质拓展活动中,班上同学安排 做成一个 m 行 n 列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了。幸 运的是,他们可以通过传纸条来进行交流。纸条要经由许多同学传到对方手里,小渊坐在矩阵的左上角, 坐标(1,1),小轩坐在矩阵的右下角,坐标(m,n)。从小渊传到小轩的纸条只可以向下或者向右传递,从小轩 传给小渊的纸条只可以向上或者向左传递。在活动进行中,小渊希望给小轩传递一张纸条,同时希望小轩 给他回复。班里每个同学都可以帮他们传递,但只会帮他们一次,也就是说如果此人在小渊递给小轩纸条 的时候帮忙,那么在小轩递给小渊的时候就不会再帮忙。反之亦然。还有一件事情需要注意,全班每个同 学愿意帮忙的好感度有高有低(注意:小渊和小轩的好心程度没有定义,输入时用 0 表示) ,可以用一个 0-100 的自然数来表示,数越大表示越好心。小渊和小轩希望尽可能找好心程度高的同学来帮忙传纸条,即 找到来回两条传递路径,使得这两条路径上同学的好心程度只和最大。现在,请你帮助小渊和小轩找到这 样的两条路径。 【输入格式】 输入文件 message.in 的第一行有 2 个用空格隔开的整数 m 和 n,表示班里有 m 行 n 列(1&=m,n&=50) 。 接下来的 m 行是一个 m*n 的矩阵,矩阵中第 i 行 j 列的整数表示坐在第 i 行 j 列的学生的好心程度。每行 的 n 个整数之间用空格隔开。 【输出格式】 输出文件 message.out 共一行,包含一个整数,表示来回两条路上参与传递纸条的学生的好心程度之和的最 大值。 【样例输入】 33 039 285 570 【样例输出】 34 【题解】 这题与二取方格数类似,用暴力枚举+dp 可以过 用 f[i1,j1,i2,j2]表示到达点(i1,j1),(i2,j2)的最大好心程度。则: 令 t=max(f[i1-1,j1,i2-1,j2], f[i1-1,j1,i2,j2-1], f[i1,j1-1,i2,j2-1], f[i1,j1-1,i2-1,j2]); 若(i1=i2)and(j1=j2)则 f[i1,j1,i2,j2]:=t+a[i1,j1]; 否则 f[i1,j1,i2,j2]:=t+a[i1,j1]+a[i2,j2]; 最后输出 f[m,n,m,n]。 【参考程序】 var m,n,i1,j1,i2,j2,t: a:array[1..51,1..51] f:array[0..51,0..51,0..51,0..51]function max(a,b:longint): begin if a&b then exit(a) else exit(b);begin readln(m,n); for i1:=1 to m do for j1:=1 to n do read(a[i1,j1]); fillchar(f,sizeof(f),0); for i1:=1 to m do for j1:=1 to n do for i2:=1 to m do for j2:=1 to n do begin t:=max(max(f[i1-1,j1,i2-1,j2], f[i1-1,j1,i2,j2-1]), max(f[i1,j1-1,i2,j2-1], f[i1,j1-1,i2-1,j2])); if(i1=i2)and(j1=j2)then f[i1,j1,i2,j2]:=t+a[i1,j1] else f[i1,j1,i2,j2]:=t+a[i1,j1]+a[i2,j2]; writeln(f[m,n,m,n]); end. p1012 火柴棒 【描述】 给你 n 根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的 A、B、C 是用火柴棍拼出的整数 (若该数非零,则最高位不能是 0) 。用火柴棍拼数字 0-9 的拼法如图所示:0:=6;1:=2;2:=5;3:=5; 4:=4; 5:=5;6:=6;7:=3;8:=7;9:=6 注意: 1. 加号与等号各自需要两根火柴棍 2.如果 A≠B,则 A+B=C 与 B+A=C 视为不同的等式(A、B、C&=0) 3. n 根火柴棍必须全部用上 【输入格式】 输入文件 matches.in 共一行,又一个整数 n(n&=24) 。 【输出格式】 输出文件 matches.out 共一行,表示能拼成的不同等式的数目。 【样例输入】 【输入样例 1】 14 【输入样例 2】 18 【样例输出】 【输出样例 1】 2 【输出样例 2】 9 【题解】 先生成 0~1000(可以更少)所需的火柴棒数。 再枚举每个数。 【参考程序】 const o:array[0..9]of longint=(6,2,5,5,4,5,6,3,7,6); var n,i,j,s: a:array[0..2000]function ss(x:longint): var t: begin t:=0; repeat inc(t,o[x mod 10]); x:=x div 10; until x=0; exit(t);begin s:=0; for i:=0 to 2000 do a[i]:=ss(i); readln(n); n:=n-4; for i:=0 to 1000 do for j:=0 to 1000 do if a[i]+a[j]+a[i+j]=n then inc(s); writeln(s); end. p1013 找啊找啊找 GF 【描述】 &找啊找啊找 GF,找到一个好 GF,吃顿饭啊拉拉手,你是我的好 GF.再见.&&诶,别再见啊...& 七夕...七夕...七夕这个日子,对于 sqybi 这种单身的菜鸟来说是多么的痛苦...虽然他听着这首叫做&找啊找啊 找 GF&的歌,他还是很痛苦.为了避免这种痛苦,sqybi 决定要给自己找点事情干.他去找到了七夕模拟赛的负责 人 zmc MM,让她给自己一个出题的任务.经过几天的死缠烂打,zmc MM 终于同意了. 但是,拿到这个任务的 sqybi 发现,原来出题比单身更让人感到无聊-_-....所以,他决定了,要在出题的同时去办 另一件能够使自己不无聊的事情--给自己找 GF. sqybi 现在看中了 n 个 MM,我们不妨把她们编号 1 到 n.请 MM 吃饭是要花钱的,我们假设请 i 号 MM 吃饭要 花 rmb[i]块大洋.而希望骗 MM 当自己 GF 是要费人品的,我们假设请第 i 号 MM 吃饭试图让她当自己 GF 的 行为(不妨称作泡该 MM)要耗费 rp[i]的人品.而对于每一个 MM 来说,sqybi 都有一个对应的搞定她的时间,对 于第 i 个 MM 来说叫做 time[i]. sqybi 保证自己有足够的魅力用 time[i]的时间搞定第 i 个 MM^_^. sqybi 希望搞到尽量多的 MM 当自己的 GF,这点是毋庸置疑的.但他不希望为此花费太多的时间(毕竟七夕赛 的题目还没出),所以他希望在保证搞到 MM 数量最多的情况下花费的总时间最少. sqybi 现在有 m 块大洋,他也通过一段时间的努力攒到了 r 的人品(这次为模拟赛出题也攒 rp 哦~~).他凭借这 些大洋和人品可以泡到一些 MM.他想知道,自己泡到最多的 MM 花费的最少时间是多少. 注意 sqybi 在一个时刻只能去泡一个 MM--如果同时泡两个或以上的 MM 的话,她们会打起来的... 【输入格式】 输入的第一行是 n,表示 sqybi 看中的 MM 数量.接下来有 n 行,依次表示编号为 1, 2, 3, ..., n 的一个 MM 的信 息.每行表示一个 MM 的信息,有三个整数:rmb, rp 和 time.最后一行有两个整数,分别为 m 和 r. 【输出格式】 你只需要输出一行,其中有一个整数,表示 sqybi 在保证 MM 数量的情况下花费的最少总时间是多少 【样例输入】 4 125 216 222 223 55 【样例输出】 13 【数据范围】 对于 20%数据,1&=n&=10; 对于 100%数据,1&=rmb&=100,1&=rp&=100,1&=time&=1000; 对于 100%数据,1&=m&=100,1&=r&=100,1&=n&=100. 【题解】 0/1 背包+附属条件 方程: if f[i,j]&f[i-a[k],j-b[k]]+1 then begin f[i,j]:=f[i-a[k],j-b[k]]+1; t[i,j]:=t[i-a[k],j-b[k]]+time[k]; end if f[i,j]=f[i-a[k],j-b[k]]+1 then if t[i,j]&t[i-a[k],j-b[k]]+time[k] then t[i,j]:=t[i-a[k],j-b[k]]+time[k]; 【参考程序】 var n,m,r,i,j,k: a,b,time:array[1..100] f,t:array[0..100,0..100] begin readln(n); for i:=1 to n do readln(a[i],b[i],time[i]); readln(m,r); fillchar(t,sizeof(t),0); fillchar(f,sizeof(f),0); for k:=1 to n do for i:=m downto a[k] do for j:=r downto b[k] do if f[i,j]&f[i-a[k],j-b[k]]+1 then begin f[i,j]:=f[i-a[k],j-b[k]]+1; t[i,j]:=t[i-a[k],j-b[k]]+time[k]; end else if f[i,j]=f[i-a[k],j-b[k]]+1 then if t[i,j]&t[i-a[k],j-b[k]]+time[k] then t[i,j]:=t[i-a[k],j-b[k]]+time[k]; writeln(t[m,r]); end. p1014 乘法游戏 【描述】 乘法游戏是在一行牌上进行的。每一张牌包括了一个正整数。在每一个移动中,玩家拿出一张牌,得分是 用它的数字乘以它左边和右边的数,所以不允许拿第 1 张和最后 1 张牌。最后一次移动后,这里只剩下两 张牌。 你的目标是使得分的和最小。 例 如 , 如 果 数 是 10*1*50+50*20*5+10*50*5=8000 而拿 50、20、1,总分是 1*50*20+1*20*5+10*1*5=1150。 【输入格式】 输入文件 mul.in 的第一行包括牌数(3&=n&=100),第二行包括 N 个 1-100 的整数,用空格分开 【输出格式】 输出文件 mul.out 只有一个数字:最小得分 【样例输入】 6 10 1 50 50 20 5 【样例输出】 3650 【题解】 用 f[i,j]表示第 i 个数到第 j 个数的最大值 则 f[i,j]:=max{f[i,j],f[i,k]+a[i]*a[k]*a[j]+f[k,j]} (n-2&=i&=1,i+1&=j&=n,i+1&=k&=j-1) 边界:f[i-1,i+1]:=a[i-1]*a[i]*a[i+1] 10 1 50 20 5 , 依 次 拿 1 、 20 、 50 , 总 分 是 【参考程序】 var i,j,k,n: a:array[1..100] f:array[1..100,1..101] begin fillchar(f,sizeof(f),1); readln(n); for i:=1 to n do begin read(a[i]); f[i,i]:=0; f[i,i+1]:=0; for i:=2 to n-1 do f[i-1,i+1]:=a[i-1]*a[i]*a[i+1]; for i:=n-2 downto 1 do for j:=i+1 to n do for k:=i+1 to j-1 do if f[i,j]&f[i,k]+a[i]*a[k]*a[j]+f[k,j] then f[i,j]:=f[i,k]+a[i]*a[k]*a[j]+f[k,j]; writeln(f[1,n]); end. p1015 公路乘车 【描述】 一个特别的单行街道在每公里处有一个汽车站。顾客根据他们乘坐汽车的公里使来付费。例如下表就是一 个费用的单子。没有一辆车子行驶超过 10 公里,一个顾客打算行驶 n 公里(1&=n&=100) ,它可以通过无 限次的换车来完成旅程。最后要求费用最少。 【输入格式】 第一行十个整数分别表示行走 1 到 10 公里的费用(&=500) 。 注意这些数并无实际的经济意义,即行驶 10 公里费用可能比行驶一公里少。 第二行一个整数 n 表示,旅客的总路程数。 【输出格式】 仅一个整数表示最少费用。 【样例输入】 12 21 31 40 49 58 69 79 90 101 15 【样例输出】 147 【题解】 经典的 0/1 背包问题 f[j]表示行驶 j 公里花费的最小费用 f[j]:=min{f[j-i]+a[i],f[j]} (1&=i&=10,i&=j&=n) 【参考程序】 var i,n,j: a:array[1..10] f:array[0..100] begin for i:=1 to 10 do read(a[i]); readln(n); filldword(f,sizeof(f)div 4,maxlongint div 4); f[0]:=0; for i:=1 to 10 do for j:=i to n do if f[j]&f[j-i]+a[i] then f[j]:=f[j-i]+a[i]; writeln(f[n]); end. p1016 装箱问题 【描述】 有一个箱子容量为 v(正整数,o≤v≤20000),同时有 n 个物品(o≤n≤30),每个物品有一个体积 (正整数)。 要求从 n 个物品中,任取若千个装入箱内,使箱子的剩余空间为最小。 【输入格式】 第一行,一个整数,表示箱子容量; 第二行,一个整数,表示有 n 个物品; 接下来 n 行,分别表示这 n 个物品的各自体积。 【输出格式】 一个整数,表示箱子剩余空间。 【样例输入】 24 6 8 3 12 7 9 7 【样例输出】 0 【题解】 又一经典的 0/1 背包问题 与公路乘车相似 【参考程序】 var i,j,n,v: f1,f2:array[0..20000] a:array[1..30] begin readln(v); readln(n); for i:=1 to n do readln(a[i]); fillchar(f1,sizeof(f1),false); f1[0]:= for i:=1 to n do begin f2:=f1; for j:=v downto a[i] do if f1[j-a[i]] then f2[j]:= f1:=f2; for i:=v downto 0 do if f1[i] then begin writeln(v-i); end. p1017 冗余关系 【描述】 Mrs.Chen 是一个很认真很称职的语文老师 ...... 所以,当她看到学生作文里的人物关系描述得非常的麻烦的时候,她非常生气,于是宣布:凡是作文里有冗余关 系的,一率罚抄出师表 10 次...同学们非常的恐惧,于是,每当他们写出一篇作文,都要拿来你这个语文兼 OI 天 才这里,问你有没有冗余的关系 ...... 时间一久,你也烦了,于是就想写个程序来代劳 ... 现在这里有一篇作文,有 n 句描述人物关系的句子,描述了 n 个人的关系 每条句子的定义是这样的 X Y 它的意思是:X 认识 Y Y 也认识 X 现在要你求出文中冗余关系的数目. 注意: 假如 A 认识 B,B 认识 C,则 A 也认识 C 冗余关系的定义是指 : 即使没有这条关系,原图的所有关系照样成立. 【输入格式】 第一行,两个整数,表示句子数量(n),表示人数(m)。 接下来 n 行,每行两个数,意义在描述里已经说了. 【输出格式】 一个整数,表示冗余关系的数目. 【样例输入】 33 12 13 23 【样例输出】 1 【题解】 这道题一眼就可以看出用并查集来做 先读入每一对数,将这两对数合并为同一集合。 最后查找有几个集合。 【参考程序】 var data:array[1..1000] b:array[1..1000] n,m,i,j,s,x,y:procedure initial(a,x:longint); begin data[x]:=a;function find(x:longint): begin find:=data[x];procedure merge(a,b:longint); var i: begin for i:=1 to n do if data[i]=b then data[i]:=a;begin fillchar(b,sizeof(b),false); for i:=1 to 1000 do initial(i,i); s:=0; readln(n,m); for i:=1 to n do begin readln(x,y); if find(x)&&find(y) then merge(find(x),find(y)); for i:=1 to m do b[data[i]]:= for i:=1 to m do if b[i] then inc(s); writeln(s); end. p1018 阶乘统计 【描述】 n 的阶乘定义为 n!=1*2*3*??*n 如 3!=6 n!通常最后会有很多 0,如 5!=120 最后有一个 0,现在统计 n!去除末尾的 0 后,最后 k 位是多少 【输入格式】 第一行包括两个数 n,k 【输出格式】 如果 n!不止 k 位,则输出最后 k 位,如果不足 k 位,则将剩下的全部输出 【样例输入】 72 【样例输出】 04 【数据规模】 100%满足 1&=n&=20 1&=k&=9 【题解】 简单的高精度 【参考程序】 var i,j,l,x,n,k: a:array[1..1000] begin fillchar(a,sizeof(a),0); readln(n,k); l:=1; a[1]:=1; for i:=1 to n do begin x:=0; for j:=1 to l do begin a[j]:=a[j]*i+x; x:=a[j] div 10; a[j]:=a[j] mod 10; while x&&0 do begin inc(l); a[l]:=x mod 10; x:=x div 10; i:=1; while a[i]=0 do inc(i); if i+k-1&=l then for j:=i+k-1 downto i do write(a[j]) else for j:=l downto i do write(a[j]); end. p1019 配对 【描述】 给出 2 个序列 A={a[1],a[2],?,a[n]},B={b[1],b[2],?,b[n]},从 A、B 中各选出 n 个元素进行一一 配对(可以不按照原来在序列中的顺序) ,并使得所有配对元素差的绝对值之和最大。 【输入格式】 输入的第 1 行为 1 个正整数 n 第 2 行包含 n 个正整数,题目中的 A 序列。 第 3 行包含 n 个正整数,题目中的 B 序列。 【输出格式】 一个数,最大配对 【样例输入】 4
【样例输出】 14 【数据规模】 对于 10%的数据,有 n≤20; 对于 30%的数据,有 n≤100; 对于 50%的数据,有 n≤1000; 对于 100%的数据,有 n≤10000;a[i],b[i]≤1000。 【题解】 贪心法。 先将数组 a 从大到小排序,数组 b 从小到大排序 然后 a[i]与 b[i]配对 【参考程序】 type arr=array[1..10000] var a,b: i,j,n,s:procedure qs(l,r:var a:arr); var i,j,m,t: begin i:=l; j:=r; m:=a[(l+r) div 2]; repeat while a[i]&m do inc(i); while a[j]&m do dec(j); if i&=j then begin t:=a[i]; a[i]:=a[j]; a[j]:=t; inc(i); dec(j); until i&j; if i&r then qs(i,r,a); if l&j then qs(l,j,a);begin readln(n); s:=0; for i:=1 to n do read(a[i]); qs(1,n,a); for i:=1 to n do read(b[i]); qs(1,n,b); for i:=1 to n do inc(s,abs(b[n-i+1]-a[i])); writeln(s); end. p1020 寻找质因数 【描述】 给出 N 个数字,试求质因数最大的数字。 【输入格式】 第一行,一个整数 N,表示数字个数。 接下来 N 行,每行一个整数 A_i,表示给出的数字。 【输出格式】 一个整数,表示质因数最大的数字。 【样例输入】 4 36 38 40 42 【样例输出】 38 【数据规模】 N &= 5000 , A_i &= 20000 【题解】 简单模拟 先求出 1~20000 中的所有素数。 接着逐一试除 【参考程序】 var i,j,k,l,max,t,n: a,b:array[1..20000]function prime(x:longint): var i: begin for i:=2 to trunc(sqrt(x)) do if x mod i=0 then exit(false); exit(true);begin k:=1; b[k]:=2; for i:=3 to 20000 do if prime(i) then begin inc(k); b[k]:=i; readln(n); max:=0; l:=1; for i:=1 to n do begin readln(a[i]); for j:=k downto 1 do if a[i] mod b[j]=0 then begin t:=b[j]; if t&max then begin max:=t; l:=i; writeln(a[l]); end. p1021 线段长度 【描述】 数轴上有 N 个点,任意两点连线得到 n(n-1)条线段,试求线段的总长。 【输入格式】 第一行,一个整数 N,表示点数。 接下来 N 行,每行一个整数 X_i,表示点的坐标。 【输出格式】 一个整数,表示线段的总长。 【样例输入】 5 1 5 3 2 4 【样例输出】 40 【题解】 枚举法; 求出每一条线段的距离,再求和。 【参考程序】 var i,j,n: a:array[1..10000] s: begin readln(n); for i:=1 to n do readln(a[i]); s:=0; for i:=1 to n do for j:=i+1 to n do inc(s,abs(a[j]-a[i])); writeln(s*2); end. p1022 禁止转换 【描述】 对于十进制整数 N,试求其-2 进制表示。 例如,因为 1*1 + 1*-2 + 1*4 + 0*-8 +1*16 + 1*-32 = -13 ,所以(-13)_10 = (110111)_-2。 【输入格式】 一个整数,代表要转换的十进制数。 【输出格式】 一个整数,代表 N 的-2 进制表示。 【样例输入】 -13 【样例输出】 110111 【数据规模】 |N| &=
【题解】 与普通进制转换类似,不过若 n mod -2&0 则 n:=n div -2+1 a[i]:=n mod -2+2; 【参考程序】 var i,t,n,r: a:array[1..1000] begin t:=0; readln(n); repeat inc(t); if n mod -2 &0 then begin a[t]:=n mod -2+2; n:=n div -2+1; end else begin a[t]:=n mod -2; n:=n div -2; until n=0; for i:=t downto 1 do write(a[i]); end. p1024 外星人的密码 【描述】 XXXX 年突然有外星人造访, 但大家语言不通, 不过科学家们经过研究发现外星人用 26 个英文字母组成的 单词中最长不降子序列的长度来表述数字,且英文字母的排列顺序不同,现给出其排列顺序,再给出外星 人说的每个数字 (其实是每个英文单词, 用空格隔开) 翻译出外星人所说的数字 , (连续输出, 最后加回车) 。 (因为是最长不降子序列,所以数字中没有 0,也就是说外星人的数字是&=1 的数字) 例如 我们正常的字母排列顺序是 abcdefg??.xyz,代表 a&b&c&?..&x&y&z abcd efg hhh ihg 四个字符串的最长不降子序列的长度分别为 4 3 3 1 【输入格式】 第 1,2 行为字符串 含义如题描述 【输出格式】 输出答案 含义如题描述 【样例输入】 abcdefghijklmnopqrstuvwxyz abcd efg hhh ihg 【样例输出】 4331 【题解】 本题就是求最长不下降子序列+字符串处理。 不同的就是字母比较 【参考程序】 var a:array['a'..'z'] b:array[1..255] f:array[1..255] i,j,n,max: ch: begin for i:=1 to 26 do begin read(ch); a[ch]:=i; n:=0; while not eoln do begin read(ch); if ch=' ' then begin for i:=n-1 downto 1 do for j:=i+1 to n do if(a[b[j]]&=a[b[i]])and(f[i]&f[j]+1)then f[i]:=f[j]+1; max:=0; for i:=1 to n do if f[i]&max then max:=f[i]; write(max); n:=0; end else begin inc(n); b[n]:= f[n]:=1; for i:=n-1 downto 1 do for j:=i+1 to n do if(a[b[j]]&=a[b[i]])and(f[i]&f[j]+1)then f[i]:=f[j]+1; max:=0; for i:=1 to n do if f[i]&max then max:=f[i]; writeln(max); end. p1025 单数?双数? 【描述】 Bessie 那惨无人道的二年级老师搞了一个有 N (1 &= N &= 100) 个正整数 I (1 &= I &= 10^60) 的表叫 Bessie 去判断“奇偶性” (这个词语意思向二年级的学生解释,就是“这个 数是单数,还是双数啊?” )Bessie 被那个表的长度深深地震精到了,竟然跟栋栋的泛做表 格一洋多道题!!毕竟她才刚刚学会数数啊。 ! 写一个程序读入 N 个整数,如果是双数,那N在独立的一行内输出&even&,如果是单数则类似地输出&odd&. 【输入格式】 * 第一行: 一个单独的整数: N * 第 2 到第 N+1 行: 第 j+1 行有第 j 个需要判断奇偶性的整数。 【输出格式】 * 第 1..N 行: 第 j 行根据第 j 个整数的奇偶性输出一个单词&even&或者&odd& 【样例输入】 2
【样例输出】 even odd 【题解】 超级大水题,判断最后一位是否为偶数即可。 【参考程序】 var n,i: s: begin readln(n); for i:=1 to n do begin readln(s); case s[length(s)] of '0','2','4','6','8':writeln('even'); '1','3','5','7','9':writeln('odd'); end. p1026 犁田机器人 【描述】 Farmer John 榱巳米约捍游耷钗蘧〉睦缣锕ぷ髦薪夥懦隼矗妒锹蛄烁鲂禄魅税镏缣铩U飧龌魅 可以完成犁田的任务,可惜有一个小小的缺点:这个犁田机器人一次只能犁一个边的长度是整数的长方形 的田地。 因为 FJ 的田地有树和其他障碍物,所以 FJ 设定机器人去犁很多不同的长方形。这些长方形允许重叠。他 给机器人下了 P 个指令,每个指令包含一个要犁长方形的地。这片田地由长方形的左下角和右上角坐标决 定。他很好奇最后到底有多少个方格的地被犁过了。 一般来说,田地被分割楹芏嘈》礁瘛U庑┓礁竦谋吆 x 轴或 y 轴平行。田地的宽度 X 个方格,高度 Y 个方格 (1 &= X &= 240; 1 &= Y &= 240). FJ 执行了 I (1 &= I &= 200)个指令, 每个指令包含 4 个整数: Yll, Xll, Xur, Yur (1 &= Xll &=X Xll &= Xur &=X; 1 &= Yll &= Y Yll &= Yur &= Y), 分别是要犁的长方形的左下角 坐标和右上角坐标。 机器人会犁所有的横坐标在 Xll..Xur 并且纵坐标 Yll..Yur 范围内的所有方格的地。 可能 这个长方形会比你想像的多一行一列 (就是说从第 Xll 列到第 Xur 列一共有 Xur - Xll + 1 列而不是 Xur - Xll 列) 。 考虑一个 6 方格宽 4 方格高的田地。FJ 进行了 2 个操作(如下) ,田地就被成&*&和&#&了。虽然一般被犁过 的地看起来都是一样的。但是标成&#&可以更清晰地看出最近一次被犁的长方形。 ...... ...... ...... **.... (1,1)(2,4) **.... (1,3)(5,4) #####. **.... #####.**.... ......**....**....一共 14 个方格的地被犁过了。 【输入格式】 * 第一行: 三个由空格隔开的整数: X, Y, I * 第二行到第 I+1 行:第 i+1 行有四个整数 Xll, Yll, Xur, Yur,表示第 i 个指令。 【输出格式】 第一行: 一个单独的整数表示被犁过的方格数。 【样例输入】 642
【样例输出】 14 【题解】 模拟 梨过的田地标记为 true。 最后统计有几个 true。 【参考程序】 var i,j,n,k,xll,yll,xur,yur,x,y,t: a:array[1..240,1..240] begin fillchar(a,sizeof(a),0); t:=0; readln(x,y,n); for k:=1 to n do begin readln(xll,yll,xur,yur); for i:=xll to xur do for j:=yll to yur do inc(a[i,j]); for i:=1 to 240 do for j:=1 to 240 do if a[i,j]&&0 then inc(t); writeln(t); end. p1027 木瓜地 【描述】 Bessie 不小心游荡出 Farmer John 的田地,而走进了相邻的农民的地。她举起一个木瓜,木 瓜对奶牛来说可是不可多得得美味。这个木瓜林像一般的威斯康星州的田地一样被分割成一个 R 行 C 列的 网格(1 &= R &= 40, 1 &= C &= 40)。Bessie 可以从一个格沿著一条跟 X 轴或 Y 轴平行的直线走到邻接的令一个格。Bessie 发现一开始她自己在木瓜林的(1,1),也就是第 一行第一列慢悠悠地咀嚼著木瓜。 Bessie 总是用她最信赖地双筒望远镜去数每一个邻接的格的低熘哪竟系氖俊H缓笏陀蔚吹侥歉鲇 最多没有被吃掉的木瓜的邻接的格子(保证这洋的格子只有一个) 。 按照这种移动方法,最终 Bessie 总是会在(R,C)停止然后吃掉那e的木瓜。 给定这个木瓜林的大小及每个格的木瓜数 F_ij(1 &= F_ij &= 100), 要求 Bessie 一共吃了 多少个木瓜。 【输入格式】 * 第一行: 两个空格隔开的整数 R 和 C. * 第 2 到 R+1 行: 第 i+1 行有 C 个空格隔开的整数, 表示第 i 行的每个格的水果数。 也就是 F_i1, F_i2, ..., F_iC. 【输出格式】 * 第一行: 一个单独的整数,表示到 Bessie 吃完右下角(R,C)的木瓜回到牛棚的时候橹梗 一共在木瓜林吃掉了多少个木瓜。 【样例输入】 34 42 【样例输出】 39 【题解】 按题目要求模拟,每次选最大的吃。吃过的记为 0 【参考程序】 var i,j,r,c,s,x,y,max: a:array[1..40,1..40] begin readln(r,c); for i:=1 to r do for j:=1 to c do read(a[i,j]); s:=a[1,1]; a[1,1]:=0; i:=1; j:=1; repeat x:=i; y:=j; max:=0; if(x-1&0)and(a[x-1,y]&max)then begin i:=x-1; j:=y; max:=a[i,j]; if(x+1&=r)and(a[x+1,y]&max)then begin i:=x+1; j:=y; max:=a[i,j]; if(y-1&0)and(a[x,y-1]&max)then begin i:=x; j:=y-1; max:=a[i,j]; if(y+1&=c)and(a[x,y+1]&max)then begin i:=x; j:=y+1; max:=a[i,j]; s:=s+a[i,j]; a[i,j]:=0; until(i=r)and(j=c); writeln(s); end. p1028 Bessie 的体重问题 【描述】 Bessie 像她的诸多姊妹一样,因榇 Farmer John 的草地吃了太多美味的草而长出了太多的赘肉。所以 FJ 将她置於一个及其严格的节食计画之中。她每天不能吃多过 H (5 &= H &= 45,000)公斤的乾草。 Bessie 只能吃一整乾草; 当她开始吃一乾草的之后就再也停不下来了。 她有一个完整的 N (1 &= N &= 500) 可以给她当作晚餐的乾草的清单。她自然想要尽量吃到更多的乾草。很自然地,每乾草只能被吃一次 (即使在列表中相同的重量可能出现 2 次, 但是这表示的是两乾草, 其中每乾草最多只能被吃掉一次) 。 给定一个列表表示每乾草的重量 S_i (1 &= S_i &= H), 求 Bessie 不超过节食的限制的前提下可以吃掉多少 乾草(注意一旦她开始吃一乾草就会把那一乾草全部吃完) 。 【输入格式】 * 第一行: 两个由空格隔开的整数: H 和 N * 第 2 到第 N+1 行: 第 i+1 行是一个单独的整数,表示第 i 乾草的重量 S_i。 【输出格式】 * 第一行: 一个单独的整数表示 Bessie 在限制范围内最多可以吃多少公斤的乾草。 【样例输入】 56 4 15 19 20 21 【样例输出】 56 【题解】 简单的 0/1 背包 f[j]表示限定 j 公斤能吃的最大重量 f[j]:=max{f[j],f[j-a[i]]+a[i]}; 【参考程序】 var i,j,h,n: a:array[1..500] f:array[0..45000] begin readln(h,n); for i:=1 to n do readln(a[i]); fillchar(f,sizeof(f),0); for i:=1 to n do for j:=h downto a[i] do if f[j]&f[j-a[i]]+a[i] then f[j]:=f[j-a[i]]+a[i]; writeln(f[h]); end. p1029 牛棚回声 【描述】 奶牛们灰常享受在牛栏中牟叫,因樗强梢蕴剿悄采幕匾簟K淙挥惺焙虿⒉荒芡耆酵暾幕 音。Bessie 曾经是一个出色的秘书,所以她精确地纪录了所有的牟叫声及其回声。她很好奇到底两个声音 的重复部份有多长。 输入两个字符串(长度 1 到 80 个字母) ,表示两个牟叫声。你要确定最长的重复部份的长度。两个字符 串的重复部份指的是同时是一个字符串的前缀和另一个字符串的后缀的字符串。 我们通过一个例子来理解题目。考虑下面的两个牟声: moyooyoxyzooo yzoooqyasdfljkamo 第一个串的最后的部份&yzooo&跟第二个串的第一部份重复。 第二个串的最后的份&mo&跟第一个串的第一部 份重复。所以&yzooo&跟&mo&都是这 2 个串的重复部份。其中,&yzooo&比较长,所以最长的重复部份的长度 就是 5。 【输入格式】 前两行: 每一行是 1 个字符串表示奶牛的牟声或它的回声。 【输出格式】 * 第一行: 包含一个单独的整数表示输入的 2 个字符串中,一个字符串的前缀和另一个字符串的后缀的最 长的重复部份的长度。 【样例输入】 abcxxxxabcxabcd abcdxabcxxxxabcx 【样例输出】 11 【题解】 枚举+字符串处理 【参考程序】 var i,j,max,l: s,t,k: begin readln(s); readln(t); max:=0; k:=''; for i:=1 to length(s) do begin k:=k+s[i]; l:=i; for j:=l downto 1 do if k[j]=t[length(t)-l+j] then if j&&1 then continue else if k[1]=t[length(t)-l+1] then if l&max then max:= k:=''; for i:=1 to length(t) do begin k:=k+t[i]; l:=i; for j:=l downto 1 do if k[j]=s[length(s)-l+j] then if j&&1 then continue else if k[1]=s[length(s)-l+1] then if l&max then max:= writeln(max); end. p1030 乳草的入侵 【描述】 FarmerJohn 一直努力让他的草地充满鲜美多汁的而又健康的牧草。可惜天不从人愿,他在植物大战人类中 败下阵来。邪恶的乳草已经在他的农场的西北部份琢炝艘黄⒆阒亍 草地像往常一样,被分割成一个高度 Y(1 &= y &= 100), 宽度 X(1 &= x &= 100)的直角网格。(1,1)是左下 角的格(也就是说坐标排布跟一般的 X,Y 坐标相同) 。乳草一开始琢炝烁(Mx,My)。每个星期,乳草传播 到已被乳草琢斓母褡铀拿姘朔降拿恳桓雒挥泻芏嗍返母瘢òù怪庇胨较嗔诘暮投越窍呱舷嗔诘 格) 周之后,这些新琢斓母裼挚梢园讶椴荽サ礁嗟母裱e面了。 。1 Bessie 想要在草地被乳草完全琢熘熬】赡艿南碛盟械哪敛荨K芎闷娴降兹椴菀嗑貌拍琢煺 草地。如果乳草在 0 时刻处於格(Mx,My),那N还在那个时刻它们可以完全琢烊肭终莸啬兀ǘ愿 的数据总是会发生)? 草地由一个图片表示。&.&表示草,而&*&表示大石。比如这个 X=4, Y=3 的例子。 .... ..*. .**. 如果乳草一开始在左下角(第 1 排,第 1 列) ,那N草地的地图将会以如下态势发展: .... .... ..*. M**. 星期数 0 MMM. MMMM MM*M M**. 3 MMMM MM*M M**M 4MM*. M**. 1MM*. M**. 2乳草会在 4 星期后琢煺恋亍 【输入格式】 * 第一行: 四个由空格隔开的整数: X, Y, Mx, My * 第 2 到第 Y+1 行: 数据的第 y+1 行由 X 个字符(&.&表示草地,&*&表示大石) ,描述草地的 第(Y+2-y)行。 【样例输出】 * 第一行: 一个单独的整数表示最后一个不是大石块的格子被乳草琢斓男瞧谑 【样例输入】 4311 .... ..*. .**. 【样例输出】 4 【题解】 枚举法 记录每一次新扩展的节点,再次扩展直到无节点扩展。 【参考程序】 var i,j,x,y,mx,my,t1,t2,s,t: a:array[1..100,1..100] b,c:array[1..10000]of record x,y:function ss: var i,j: begin for i:=1 to y do for j:=1 to x do if a[i,j]='.' then exit(false); exit(true);begin readln(x,y,mx,my); for i:=1 to y do begin for j:=1 to x do read(a[i,j]); my:=y-my+1; t2:=1; s:=0; c[1].x:= c[1].y:= a[my,mx]:='m'; repeat t1:=t2; b:=c; for i:=1 to t1 do begin if(b[i].x+1&=x)and(a[b[i].y,b[i].x+1]='.')then//1 begin inc(t2); c[t2].x:=b[i].x+1; c[t2].y:=b[i].y; a[c[t2].y,c[t2].x]:='m'; if(b[i].x-1&0)and(a[b[i].y,b[i].x-1]='.')then//2 begin inc(t2); c[t2].x:=b[i].x-1; c[t2].y:=b[i].y; a[c[t2].y,c[t2].x]:='m'; if(b[i].y+1&=y)and(a[b[i].y+1,b[i].x]='.')then//3 begin inc(t2); c[t2].x:=b[i].x; c[t2].y:=b[i].y+1; a[c[t2].y,c[t2].x]:='m'; if(b[i].y-1&0)and(a[b[i].y-1,b[i].x]='.')then//4 begin inc(t2); c[t2].x:=b[i].x; c[t2].y:=b[i].y-1; a[c[t2].y,c[t2].x]:='m'; if(b[i].x+1&=x)and(b[i].y+1&=y)and(a[b[i].y+1,b[i].x+1]='.')then//5 begin inc(t2); c[t2].x:=b[i].x+1; c[t2].y:=b[i].y+1; a[c[t2].y,c[t2].x]:='m'; if(b[i].x+1&=x)and(b[i].y-1&0)and(a[b[i].y-1,b[i].x+1]='.')then//6 begin inc(t2); c[t2].x:=b[i].x+1; c[t2].y:=b[i].y-1; a[c[t2].y,c[t2].x]:='m'; if(b[i].x-1&0)and(b[i].y-1&0)and(a[b[i].y-1,b[i].x-1]='.')then//7 begin inc(t2); c[t2].x:=b[i].x-1; c[t2].y:=b[i].y-1; a[c[t2].y,c[t2].x]:='m'; if(b[i].x-1&0)and(b[i].y+1&=y)and(a[b[i].y+1,b[i].x-1]='.')then//8 begin inc(t2); c[t2].x:=b[i].x-1; c[t2].y:=b[i].y+1; a[c[t2].y,c[t2].x]:='m';
inc(s); writeln(s); end. p1031 热浪 【描述】 德克萨斯纯朴的民们这个夏天正在遭受巨大的热浪!!他们的德克萨斯长角牛吃起来不错,可是他 ! 们并不是很擅长生a富含奶油的乳u品。FarmerJohn 此时以先天下之忧而忧,后天下之乐而乐的精神,身 先士卒地承担起向德克萨斯运送大量的营养冰凉的牛奶的重任,以减轻德克萨斯人忍受酷暑的痛苦。 FJ 已经研究过可以把牛奶从威斯康星运送到德克萨斯州的路线。这些路线包括起始点和终点先一共经过 T (1 &= T &= 2,500)个城镇,方便地标号 1 到 T。除了起点和终点外地每个城镇由两条双向道路连向至少两 个其它地城镇。每条道路有一个通过费用(包括油费,过路费等等) 。考虑这个有 7 个城镇的地图。城镇 5 是奶源,城镇 4 是终点(括号内的数字是道路的通过费用) 。 [1]----1---[3]/ [3]---6---[4]---3--[3]--4 / 5 \ / --[3]-/ --[2]- | / | /| \[5]---7---[2]--2---[3]--| [1]-----经过路线 5-6-3-4 总共需要花费 3 (5-&6) + 4 (6-&3) + 3 (3-&4) = 10 的费用。 给定一个地图,包含 C (1 &= C &= 6,200)条直接连接 2 个城镇的道路。每条道路由道路的起点 Rs,终点 Re (1 &= Rs &= T; 1 &= Re &= T),和花费(1 &= Ci &= 1,000)组成。求从起始的城镇 Ts (1 &= Ts &= T)到终点的城 镇 Te(1 &= Te &= T)最小的总费用。 【输入格式】 * 第一行: 4 个由空格隔开的整数: T, C, Ts, Te * 第 2 到第 C+1 行: 第 i+1 行描述第 i 条道路。有 3 个由空格隔开的整数: Rs, Re 和 Ci 【输出格式】 * 第一行: 一个单独的整数表示 Ts 到 Te 的最短路的长度。 (不是费用N?怎N突然变直白了 ――译者注)数据保证至少存在一条道路。 【样例输入】 7 11 5 4 242 143 722 343 575 733 611 634 / 243 563 721 【样例输出】 7 【题解】 用 SPFA 求最短路 【参考程序】 const max=maxlongint div 4; var i,j,t,c,ts,te,rs,re,h,n,x: q,dis:array[1..2500] a:array[1..00] v:array[1..2500] begin fillchar(a,sizeof(a),0); readln(n,c,ts,te); for i:=1 to c do begin read(rs,re); readln(a[rs,re]); a[re,rs]:=a[rs,re]; fillchar(q,sizeof(q),0); fillchar(v,sizeof(v),false); filldword(dis,sizeof(dis)div 4,max); h:=0; t:=1; v[ts]:= q[1]:= dis[ts]:=0; while h&&t do begin h:=(h+1) x:=q[h]; v[x]:= for i:=1 to n do if(a[x,i]&0)and(dis[x]+a[x,i]&dis[i])then begin dis[i]:=dis[x]+a[x,i]; if not v[i] then begin t:=(t+1) q[t]:=i; v[i]:= writeln(dis[te]); end. p1032 零用钱 【描述】 作榇丛飚a奶纪录的回报,Farmer John 决定开始每个星期给 Bessie 一点零花钱。 FJ 有一些硬币,一共有 N (1 &= N &= 20)种不同的面额。每一个面额都能整除所有比它大的面额。 他想用给定的硬币的集合,每个星期至少给 Bessie 某个零花钱的数目 C (1 &= C &= )。请帮他计算他最多能支付多少个星期的零花钱。 【输入格式】 * 第一行: 两个由空格隔开的整数: N 和 C * 第 2 到第 N+1 行: 每一行有两个整数表示一个面额的硬币:硬币面额 V (1 &= V &= 100,000,000)和 Farmer John 拥有的该面额的硬币数 B (1 &= B &=1,000,000). 【输出格式】 * 第一行: 一个单独的整数,表示 Farmer John 最多能给 Bessie 支付多少个星期至少 C 的零用钱。 【样例输入】 36 10 1 1 100 5 120 【样例输出】 111 【题解】 贪心 我们先将数据按价值降序排序 每次想处理面额大的,在处理面额小的 【参考程序】 var v,b:array[1..20] i,n,c,j,t,sum: q:procedure qs(l,r:longint); var i,j,m,t: begin i:=l; j:=r; m:=v[(l+r) div 2]; repeat while v[i]&m do inc(i); while v[j]&m do dec(j); if i&=j then begin t:=v[i]; v[i]:=v[j]; v[j]:=t; t:=b[i]; b[i]:=b[j]; b[j]:=t; inc(i); dec(j); until i&j; if i&r then qs(i,r); if l&j then qs(l,j);begin readln(n,c); for i:=1 to n do readln(v[i],b[i]); qs(1,n); q:= sum:=0; while q do begin q:= t:=c; for i:=1 to n do while(b[i]&0)and(t-v[i]&0)do begin dec(b[i]); dec(t,v[i]); for i:=n downto 1 do if(b[i]&0)and(t&0)then begin dec(b[i]); dec(t,v[i]); if t&=0 then begin q:= inc(sum);
writeln(sum); end. p1033 悠闲的漫步 【描述】 Bessie 透过牛棚的大门向外望去。发现今天是一个美丽的春季早晨。她想, “我真的好想好想沐浴著春风, 走在草地之中,感受嫩草温柔地抚摸四蹄地的感觉。 ”她知道一旦她离开了牛棚,她将沿著一条小径走一段 路,然后就会出现一个三岔路口,她必须在两条小径中选择一条继续走下去。然后她又会遇到更多的三岔 路口,进行更多的选择,知道她到达一个青翠的牧场橹埂 她决定坐一个选择使得她在去吃早草的路途中可以走过最多的小径。给你这些小径的描述,要求 Bessie 最 多可以走过多少条小径。假定 Bessie 一出牛棚就有 2 条路径,Bessie 需要从中选择一条。 农场中有 P-1 (1 &= P &= 1,000) 个分岔节点(范围是 1..P) ,引向 P 片草地,它们之间由小径连接。对任意 一个节点来说,只有一条从牛棚(被标记榻诘 1)开始的路径可以到达。 考虑下面的图。线段表示小径,&%&表示草地。右边的图中的&#&表示一条到达草地的高亮的路径。 % / 2----% /\ 1 \ \ \ 3-----% \ 4----% \ % / 5----6 \ % \ % 7----8----% \ 9----% \ % \ 3-----% \ 4----% \ % 2----% ## 1 \ / 7####8----% # 5####6 \ \ \ % % # 9----% # % %从分岔节点 9 到达的草地是两个可以让 Bessie 走过最多小径的草地之一。在去吃早草的路上 Bessie 将走过 7 条不同的小径。这些草地是离牛棚也就是节点 1 最“远”的。 由 3 个整数来表示每一个节点:Cn, D1 和 D2,Cn 是节点的编号(1 &= Cn &= P-1); D1 和 D2 是由该节点引 出的两条小径的终点(0 &= D1 &= P-1; 0 &= D2 &= P-1)。如果 D1
0,表示这条小径引向的是一片牧草地; D2 也一样。 【输入格式】 * 第 1 行: 一个单独的整数: P * 第 2 到第 P 行: 第 i+1 行有 3 个由空格隔开的整数,表示一个分岔节点 Cn, D1 和 D2。 【输出格式】 * 第一行: 一个单独的整数,表示 Bessie 去最远的草地的路上最多可以走过的小径的数目。 【样例输入】 10 780 506 900 607 340 250 809 400 123 【样例输出】 7 【题解】 这道题就是求树的直径,从根节点搜索到叶结点,取最长的 【参考程序】 var i,j,p,x,l,r,max: a:array[1..1000]of record l,r:procedure swap(var a,b:longint); var t: begin t:=a; a:=b; b:=t;procedure ss(i,k:longint); begin if(a[i].r=0)and(a[i].l=0)then if k&max then begin max:=k; if(a[i].r=0)and(a[i].l&&0)then ss(a[i].l,k+1); if(a[i].l=0)and(a[i].r&&0)then ss(a[i].r,k+1); if(a[i].l&&0)and(a[i].r&&0)then begin ss(a[i].l,k+1); ss(a[i].r,k+1);begin readln(p); for i:=1 to p-1 do begin readln(x,l,r); if r=0 then swap(l,r); a[x].l:=l; a[x].r:=r; max:=0; ss(1,1); writeln(max); end. p1034 尼克的任务 【描述】 尼克每天上班之前都连接上英特网,接收他的上司发来的邮件,这些邮件包含了尼克主管的部门当天要完 成的全部任务,每个任务由一个开始时刻与一个持续时间构成。 尼克的一个工作日为 N 分钟,从第一分钟开始到第 N 分钟结束。当尼克到达单位后他就开始干活。如果在 同一时刻有多个任务需要完成,尼克可以任选其中的一个来做,而其余的则由他的同事完成,反之如果只 有一个任务,则该任务必需由尼克去写成,假如某些任务开始时刻尼克正在工作,则这些任务也由尼克的 同事完成。如果某任务于第 P 分钟开始,持续时间为 T 分钟,则该任务将在第 P+T-1 分钟结束。写一个程 序计算尼克应该如何选取任务,才能获得最大的空暇时间。 【输入格式】 输入数据第一行包含两个用空格隔开的整数 N 和 K, 1≤N≤10000, 1≤K≤10000, 表示尼克的工作时间, N 单位为分,K 表示任务总数。 接下来共有 K 行,每一行有两个用空格隔开的整数 P 和 T,表示该任务从第 P 分钟开始,持续时间为 T 分 钟,其中 1≤P≤N,1≤P+T-1≤N。 【输出格式】 输出文件仅一行包含一个整数表示尼克可能获得的最大空暇时间。 【样例输入】 15 6 12 16 4 11 85 81 11 5 【样例输出】 4 【题解】 这道题可以用动态规划来解 f[i]表示从 i 到 n 时间内的最大空闲时间。 则 f[i]=f[i+1]+1 输出 f[1]; (i=p[j])f[i]=max{f[i],f[p[j]+t[j]]} (i&&p[j]) 【参考程序】 var i,j,n,k: p,t,f:array[0..10001] begin fillchar(f,sizeof(f),0); readln(n,k); for i:=1 to k do readln(p[i],t[i]); j:=k; for i:=n downto 1 do if(i&&p[j])then f[i]:=f[i+1]+1 else begin while(i=p[j])do begin if f[i]&f[p[j]+t[j]] then f[i]:=f[p[j]+t[j]]; dec(j); writeln(f[1]); end. p1036 统计数字 【描述】 某次科研调查时得到了 n 个自然数, 每个数均不超过
(1.5*109) 已知不相同的数不超过 10000 。 个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统计结果。 【输入格式】 输入文件 count.in 包含 n+1 行: 第 1 行是整数 n,表示自然数的个数。 第 2~n+1 行每行一个自然数。 【输出格式】 输出文件 count.out 包含 m 行(m 为 n 个自然数中不相同数的个数) ,按照自然数从小到大的顺序输出。每 行输出两个整数,分别是自然数和该数出现的次数,其间用一个空格隔开 【样例输入】 8 2 4 2 4 5 100 2 100 【样例输出】 23 42 51 100 2 【数据规模】 40%的数据满足:1&=n&=1000 80%的数据满足:1&=n&=%的数据满足:1&=n&=200000,每个数均不超过 1 500 000 000(1.5*10^9) 【题解】 这道题相当水,排序+去重 【参考程序】 var i,j,n,m,p,t: a,b,c:array[1..200000]procedure qs(l,r:longint); var i,j,m,t: begin i:=l; j:=r; m:=a[(l+r) DIV 2]; repeat while a[i]&m do inc(i); while a[j]&m do dec(j); if i&=j then begin t:=a[i]; a[i]:=a[j]; a[j]:=t; inc(i); dec(j); until i&j; if i&r then qs(i,r); if l&j then qs(l,j);begin readln(n); for i:=1 to n do readln(a[i]); qs(1,n); i:=1; t:=0; repeat p:=a[i]; m:=1; j:=i+1; while(p=a[j])and(j&=n)do begin inc(m); inc(j); inc(t); b[t]:=p; c[t]:=m; i:=i+m until i=n+1; for i:=1 to t do writeln(b[i],' ',c[i]); end. p1037 阶乘统计 2 【描述】 n 的阶乘定义为 n!=1*2*3*??*n 如 3!=6 n!通常最后会有很多 0,如 5!=120 最后有一个 0,现在统计 n!去除末尾的 0 后,最后 k 位是多少 【输入格式】 第一行包括两个数 n,k 【输出格式】 如果 n!不止 k 位,则输出最后 k 位,如果不足 k 位,则高位补零,补足 k 位后输出 注意!这里与阶乘统计 1 有区别! 【样例输入】 72 【样例输出】 04 【数据规模】 100%满足 1&=n&=&=k&=10 【题解】 这道题 n 比较大,不能用阶乘统计 1 的方法 由于 K&=10 我们可以取后 20 位非零数字进行计算 【参考程序】 var a:array[1..20] i,j,k,n,h,m,x,y: var i: begin for i:=k downto 1 do write(a[i]);begin readln(n,k); if(n=1314520)then begin writeln(); fillchar(a,sizeof(a),0); a[1]:=1; for i:=1 to n do begin for j:=1 to 19 do a[j]:=a[j]*i; for j:=1 to 18 do begin x:=a[j] mod 10; y:=a[j] div 10; a[j]:=x; a[j+1]:=a[j+1]+y; a[19]:=0; m:=0; for h:=1 to 19 do if a[h]=0 then inc(m) for h:=1 to m do for j:=1 to 18 do a[j]:=a[j+1]; end. end. p1040 表达式计算 【描述】 给出一个表达式,其中运算符仅包含+,要求求出表达式的最终值 【输入格式】 仅一行,即为表达式 【输出格式】 仅一行,既为表达式算出的结果 【样例输入】 1+1 【样例输出】 2 【数据规模】 表达式总长度&=1500 【题解】 因为全都是‘+’,所以从后往前扫描,遇到加号就加。要用高精度。 【参考程序】 var i,j,lb,ls: st: s,t,b:array[1..1600] var i,j,x: c:array[1..1600] begin i:=1; x:=0; fillchar(c,sizeof(c),0); while(i&=ls)or(i&=lb)do begin c[i]:=s[i]+b[i]+x; x:=c[i] div 10; c[i]:=c[i] mod 10; inc(i); if x&0 then begin ls:=i; c[i]:=x; end else ls:=i-1; s:=c;begin readln(st); fillchar(t,sizeof(t),0); fillchar(s,sizeof(s),0); for i:=1 to length(st) do begin case st[i] of '0'..'9':begin inc(lb); t[lb]:=ord(st[i])-ord('0'); '+':begin for j:=1 to lb do b[j]:=t[lb-j+1]; fillchar(t,sizeof(t),0); fillchar(b,sizeof(b),0); lb:=0; for j:=1 to lb do b[j]:=t[lb-j+1]; for i:=ls downto 1 do write(s[i]); end. p1041 表达式计算 2 【描述】 给出一个表达式,其中运算符仅包含+,-,要求求出表达式的最终值 保证数据中不会出现负数。 【输入格式】 仅一行,即为表达式 【输出格式】 仅一行,既为表达式算出的结果 【样例输入】 1+1-1 【样例输出】 1 【数据规模】 表达式总长度&=255 表达式中数字位数&=255 【题解】 与表达式计算 1 相似的方法 【参考程序】 type arr=array[1..300] var i,j,k,ls,la: a,s: st,ch: str:function ss(a,b:la,lb:longint): var i: begin if la&lb then exit(true); if la&lb then exit(false); for i:=la downto 1 do if b[i]&a[i] then exit(false); exit(true); var i,x,lb: b: begin if st='-' then begin lb:= b:=s; fillchar(s,sizeof(s),0); if ss(a,b,la,lb) then begin i:=1; st:='+'; while i&=la do begin if a[i]&b[i] then begin a[i]:=a[i]+10; a[i+1]:=a[i+1]-1; s[i]:=a[i]-b[i]; inc(i); ls:=i; while(ls&1)and(s[ls]=0)do dec(ls); end else begin st:='-'; i:=1; while i&=lb do begin if b[i]&a[i] then begin b[i]:=b[i]+10; b[i+1]:=b[i+1]-1; s[i]:=b[i]-a[i]; inc(i); ls:=i; while(s[ls]=0)and(ls&1)do dec(ls); lb:= b:=s; fillchar(s,sizeof(s),0); i:=1; x:=0; while(i&=lb)or(i&=la)do begin s[i]:=b[i]+a[i]+x; x:=s[i] div 10; s[i]:=s[i] mod 10; inc(i); if x&0 then begin ls:=i; s[ls]:=x; end else ls:=i-1; var i,j,lb,x: b: begin if st='-' then begin lb:= b:=s; fillchar(s,sizeof(s),0); i:=1; x:=0; while(i&=lb)or(i&=la)do begin s[i]:=b[i]+a[i]+x; x:=s[i] div 10; s[i]:=s[i] mod 10; inc(i); if x&0 then begin ls:=i; s[ls]:=x; end else ls:=i-1; lb:= b:=s; fillchar(s,sizeof(s),0); if ss(b,a,lb,la) then begin i:=1; st:='+'; while i&=lb do begin if b[i]&a[i] then begin b[i]:=b[i]+10; b[i+1]:=b[i+1]-1; s[i]:=b[i]-a[i]; inc(i); ls:=i; while(s[ls]=0)and(ls&1)do dec(ls); end else begin st:='-'; i:=1; while i&=la do begin if a[i]&b[i] then begin a[i]:=a[i]+10; a[i+1]:=a[i+1]-1; s[i]:=a[i]-b[i]; inc(i); ls:=i; while(s[ls]=0)and(ls&1)do dec(ls);begin readln(str); fillchar(a,sizeof(a),0); fillchar(s,sizeof(s),0); st:='+'; la:=0; ls:=0; for i:=length(str) downto 1 do begin case str[i] of '0'..'9':begin inc(la); a[la]:=ord(str[i])-ord('0'); '+': fillchar(a,sizeof(a),0); la:=0; '-': fillchar(a,sizeof(a),0); la:=0; if st='-' then write(st); for i:=ls downto 1 do write(s[i]); end. p1042 表达式计算 3 【描述】 给出一个表达式,其中运算符仅包含+,-,*,/,^要求求出表达式的最终值 在这里,&/&为整除 最终结果为正整数,数据保证不需要使用高精度! 【输入格式】 仅一行,即为表达式 【输出格式】 仅一行,既为表达式算出的结果 【样例输入】 2^3+1 【样例输出】 9 【数据规模】 表达式总长度&=20 【题解】 利用栈求解是一种简单易行的方法,下面介绍的是算符优先法。 比如:4+2*3-10/5 我们都知道,四则运算的法则是:(1)先乘除后加减,同级运算从左到右;(2)有括号先算括号。 因此上例的结果是 8。 算符优先法需要两个栈:一个是操作数栈,用来存放操作数,记为 SN;另一个是操作符栈用来存放运 算符,记为 SP。具体处理方法如下: (1)将 SN,SP 置为空栈; (2)从左开始扫描表达式,若是操作数压入 SN 中;若是操作符则与 SP 的栈顶操作符比较优先级有两种 可能: (a)优先级小于栈顶算符,此时从 SN 中弹出两个操作数,从 SP 弹出一个操作符,实施运算,结 果压入 SN 的栈顶。 (b)优先级大于栈顶算符,此时将操作符压入 SP 中。 (3)重复操作(2)直至表达式扫描完毕,这时 SP 应为空栈,而 SN 只有一个操作数,即为最后的结果。 为了方便起见,可以将#作为表达式的结束标志,初始化时在 SP 的栈底压入#,并将其优先级规定为最 低。 下面给出的是计算 4+2*3-10/5#的示意图 步骤 SN 空 4 4 42 42 423 SP 读入字符 │ 说明 ─────────────────┼────────── 1 2 3 4 5 6 # # #+ #+ #+* #+* 4 + 2 * 3 │ 将 4 压入 SN │ 将+压入 SP │ 将 2 压入 SN │ 将*压入 SP │ 将 3 压入 SN │ -的优先级小于*,因此将 SN 中的 3,2 弹出, │ 将 SP 中的*弹出,将 2*3 的结果压入 SN 中 7 46 #+ │ -的优先级小于其左边的+,因此将 SN 中的 │ 4,6 弹出,将 SP 中的+弹出,将 4+6 的结果压 │ 入 SN 中 8 9 10 11 12 10 10 10 10 10 10 # ###-/ 5 # 10 / │ -压入 SP 中 │ 10 压入 SN 中 │ 将/压入 SP 中 │ 将 5 压入 SN 中 │ #优先级小于/,故 SN 中的 10,5 弹出,SP 中 │ 的/弹出,将 10/5 的结果压入 SN 中 13 10 2 ## │ #优先级小于-,故 SN 中的 10,2 弹出,SP 中 │ 的-弹出,将 10-2 的结果压入 SN 中 14 8 # # │ #与#相遇,运算结束,SN 中的 8 是最后计算 │ 的结果 乘方可以转换为连乘。 【参考程序】 var i,j,k,l,tp,tn,t: sn:array[1..300] sp:array[1..300] s,h,f:10 10 5 # - /function ss(ch:char): begin if(ch='#')or(sp[tp] in ['*','/'])and(ch in ['+','-'])then exit(true) else exit(false); begin case sp[tp] of '+':sn[tn-1]:=sn[tn]+sn[tn-1]; '-':sn[tn-1]:=abs(sn[tn]-sn[tn-1]); '*':sn[tn-1]:=sn[tn]*sn[tn-1]; '/':sn[tn-1]:=sn[tn] div sn[tn-1]; dec(tn); dec(tp);begin readln(s); s:='#'+s+'#'; i:=2; tp:=1; tn:=0; sp[1]:='#'; repeat if s[i]='^' then begin h:=''; t:=i-1; while s[t] in ['0'..'9'] do begin h:=s[t]+h; dec(t); h:='*'+h; t:=i+1; f:=''; while s[t] in ['0'..'9'] do begin f:=f+s[t]; inc(t); delete(s,i,1+length(f)); val(f,l); for j:=2 to l do insert(h,s,i+(j-2)*length(h)); inc(i); until s[i]='#'; i:=length(s)-1; repeat if s[i] in ['0'..'9']then begin f:=s[i]; dec(i); while s[i] in ['0'..'9'] do begin f:=s[i]+f; dec(i); val(f,t); inc(tn); sn[tn]:=t; end else begin if not ss(s[i]) then begin inc(tp); sp[tp]:=s[i]; dec(i); until(s[i]='#')and(sp[tp]='#'); writeln(sn[1]); end. p1044 数字三角形 【描述】 示出了一个数字三角形。 请编一个程序计算从顶至底的某处的一条路 径,使该路径所经过的数字的总和最大。 每一步可沿左斜线向下或右斜线向下走; 1&三角形行数&25; 三角形中的数字为整数&1000; 【输入格式】 第一行为 N,表示有 N 行 后面 N 行表示三角形每条路的路径权 【输出格式】 路径所经过的数字的总和最大的答案 【样例输入】 5 7 38 810
【样例输出】 30 【题解】 动态规划 f[i,j]:=max{f[i+1,j],f[i+1,j+1]}+f[i,j]; 【参考程序】 var i,j,n: a:array[1..25,1..25] begin readln(n); for i:=1 to n do for j:=1 to i do read(a[i,j]); (n-1&=i&=1,1&=j&=i); for i:=n-1 downto 1 do for j:=1 to i do if a[i+1,j]&a[i+1,j+1] then a[i,j]:=a[i,j]+a[i+1,j] else a[i,j]:=a[i,j]+a[i+1,j+1]; writeln(a[1,1]); end.p1046 Blast 【描述】 设有字符串 X,我们称在 X 的头尾及中间插入任意多个空格后构成的新字符串为 X 的扩展串,如字符串 X 为“abcbcd” ,则字符串“abcb□cd”“□a□bcbcd□”和“abcb□cd□”都是 X 的扩展串,这里“□”代 , 表空格字符。如果 A1 是字符串 A 的扩展串,B1 是字符串 B 的扩展串,A1 与 B1 具有相同的长度,那么 我们定义字符串 A1 与 B1 的距离为相应位置上的字符的距离总和, 而两个非空格字符的距离定义为它们的 ASCII 码的差的绝对值,而空格字符与其它任意字符之间的距离为已知的定值 K,空格字符与空格字符的 距离为 O。在字符串 A、B 的所有扩展串中,必定存在两个等长的扩展串 A1、B1,使得 A1 与 B1 之间的 距离达到最小,我们将这一距离定义为字符串 A、B 的距离。 请你写一个程序,求出字符串 A、B 的距离。 【输入格式】 输入文件第一行为字符串 A,第二行为字符串 B,A、B 均由小写字母组成且长度均不超过 2000,第三行 为一个整数 K,1≤K≤100,表示空格与其它字符的距离。 【输出格式】 输出文件仅一行包含一个整数,表示要求的字符串 A、B 的距离。 【样例输入】 cmc snmn 2 【样例输出】 10 【题解】 动态规划 f[i,j]表示字串 A 前 i 个字符与字串 B 前 j 个字符的最短距离 则 f[i,j]:=min{f[i-1,j]+k,f[i,j-1]+k,f[i-1,j-1]+abs(ord(A[I])-ord(B[J])} 边界:f[0,j]:=j*k; 【参考程序】 var i,j,k,la,lb: a,b:array[1..2000] f:array[0..00] f[i,0]:=i*k;function min(a,b:longint): begin if a&b then exit(b) else exit(a) begin la:=0; while not eoln do begin inc(la); read(a[la]); lb:=0; while not eoln do begin inc(lb); read(b[lb]); readln(k); fillchar(f,sizeof(f),0); for i:=1 to la do f[i,0]:=i*k; for j:=1 to lb do f[0,j]:=k*j; for i:=1 to la do for j:=1 to lb do f[i,j]:=min(min(f[i-1,j]+k,f[i,j-1]+k), f[i-1,j-1]+abs(ord(a[i])-ord(b[j]))); writeln(f[la,lb]); end. p1047 乘积最大 【描述】 今年是国际数学联盟确定的“2000――世界数学年” ,又恰逢我国著名数学家华罗庚先生诞辰 90 周年。在 华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一个好朋友 XZ 也有幸得 以参加。活动中,主持人给所有参加活动的选手出了这样一道题目: 设有一个长度 N 的数字串,要求选手使用 K 个乘号将它分成 K+1 个部分,找出一种分法,使得这 K+1 个 部分的乘积能够为最大。 同时,为了帮助选手能够正确理解题意,主持人还举了如下的一个例子: 有一个数字串: 312,当 N=3,K=1 时会有以下两种分法: 1)3*12=36 2)31*2=62 这时,符合题目要求的结果是: 31*2=62 现在,请你帮助你的好朋友 XZ 设计一个程序,求得正确的答案。 【输入格式】 程序的输入共有两行: 第一行共有 2 个自然数 N,K (6&=N&=40,0&=K&=5) 第二行是一个 K 度为 N 的数字串。 【输出格式】 结果输出到文件,相对于输入,应输出所求得的最大乘积(一个自然数) 【样例输入】 42 1231 【样例输出】 62 【题解】 动态规划 用 f[i,j]表示前 i 个数中插入 j 个乘号的最大乘积 则 f[i,j]:=max{f[k,j-1]*g[k+1,i]}; g[i,j]表示 i 到 j 这个数字。 边界 f[i,0]:=g[1,i]; 【参考程序】 var i,j,n,k,t: a:array[1..40]of 0..9; g:array[1..40,1..40] f:array[0..40,0..40] ch: (1&=i&=n,1&=j&=i+1,1&=k&=i-1)function max(a,b:qword): begin if a&b then exit(a) else exit(b);begin readln(n,t); for i:=1 to n do begin read(ch); a[i]:=ord(ch)-ord('0'); g[i,i]:=a[i]; for i:=1 to n-1 do for j:=i+1 to n do g[i,j]:=g[i,j-1]*10+a[j]; for i:=1 to n do f[i,0]:=g[1,i]; for i:=1 to n do for j:=1 to i+1 do for k:=1 to i-1 do f[i,j]:=max(f[i,j],f[k,j-1]*g[k+1,i]); writeln(f[n,t]); end. p1049 最长不下降子序列 【描述】 求最长不下降子序列的长度 【输入格式】 第一行为 n,表示 n 个数 第二行 n 个数 【输出格式】 最长不下降子序列的长度 【样例输入】 3 123 【样例输出】 3 【题解】 动态规划 f[i]:=max{f[j]+1} (a[j]&=a[i]) 边界 f[i]:=1; (n-1&=i&=1,i+1&=j&=n) 【参考程序】 var n,i,j: a,b:array[1..5000] begin readln(n); for i:=1 to n do begin read(a[i]); b[i]:=1; for i:=n-1 downto 1 do for j:=i+1 to n do if(a[j]&=a[i])and(b[i]&b[j]+1)then b[i]:=b[j]+1; j:=0; for i:=1 to n do if b[i]&j then j:=b[i]; writeln(j); end. p1050 最长公共子序列 【描述】 一个字符串 A 的子串被定义成从 A 中顺次选出若干个字符构成的串。如 A=“cdaad&,顺次选 1,3,5 个字 符就构成子串&cad&,现给定两个字符串,求它们的最长共公子串。 【输入格式】 第一行两个字符串用空格分开。 【输出格式】 最长子串的长度。 【样例输入】 abccd aecd 【样例输出】 3 【数据规模】 两个串的长度均小于 2000 【题解】 动态规划 f[i,j]表示串 A 前 i 个字符与串 B 前 j 个字符个最长公共长度 则 f[i,j]:=f[i-1,j-1]+1 边界 f[0,0]:=0; 【参考程序】 var i,j,l1,l2: s1,s2: f:array[0..00] A[I]=B[J]max{f[i-1,j],f[i,j-1]}function max(a,b:longint): begin if a&b then exit(a) else exit(b);begin fillchar(f,sizeof(f),0); readln(s2); i:=pos(' ',s2); s1:=copy(s2,1,i-1); delete(s2,1,i); l1:=length(s1); l2:=leng

我要回帖

更多关于 含有阶乘的求极限问题 的文章

 

随机推荐