杭电OJ2040-2049
杭电 OJ2040-2049
写在前面
本文记录了刷杭电 OJ2040-2049 的过程和一些想法,代码仅供参考!
2040 亲和数
Problem Description
古希腊数学家毕达哥拉斯在自然数研究中发现,220 的所有真约数 (即不是自身的约数) 之和为:
1+2+4+5+10+11+20+22+44+55+110 = 284。
而 284 的所有真约数为 1、2、4、71、 142,加起来恰好为 220。人们对这样的数感到很惊奇,并称之为亲和数。
一般地讲,如果两个数中任何一个数都是另一个数的真约数之和,则这两个数就是亲和数。
你的任务就编写一个程序,判断给定的两个数是否是亲和数
Input
输入数据第一行包含一个数 M,接下有 M 行,每行一个实例,包含两个整数 A,B; 其中 0 <= A,B <= 600000 ;
Output
对于每个测试实例,如果 A 和 B 是亲和数的话输出 YES,否则输出 NO。
Sample Input
2
220 284
100 200
Sample Output
YES
NO
解题思路
求所有公约数之和并相加,判断是否为亲和数
参考源码
1 | #include <iostream> |
2041 超级楼梯
Problem Description
有一楼梯共 M 级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第 M 级,共有多少种走法?
Input
输入数据首先包含一个整数
N,表示测试实例的个数,然后是 N 行数据,每行包含一个整数 M(1<=M<=40),
表示楼梯的级数。
Output
对于每个测试实例,请输出不同走法的数量
Sample Input
2
2
3
Sample Output
1
2
解题思路
递推题,简单写几项之后发现时斐波那契数列,之后就好办了
走上第 n 级,可以从第 n-1 级走一步上来,也可以从第 n-2 级走两步上来
f(1) = 1,f(2) = 1,f(3) = 2
f(n) = f(n - 1) + f(n - 2)
参考源码
1 | #include <iostream> |
2042 不容易系列之二
Problem Description
你活的不容易,我活的不容易,他活的也不容易。不过,如果你看了下面的故事,就会知道,有位老汉比你还不容易。重庆市郊黄泥板村的徐老汉(大号徐东海,简称 XDH)这两年辛辛苦苦养了不少羊,到了今年夏天,由于众所周知的高温干旱,实在没办法解决牲畜的饮水问题,就决定把这些羊都赶到集市去卖。从黄泥板村到交易地点要经过 N 个收费站,按说这收费站和徐老汉没什么关系,但是事实却令徐老汉欲哭无泪:
(镜头回放) 近景:老汉,一群羊 远景:公路,收费站
…
收费员(彬彬有礼 + 职业微笑):“老同志,请交过路费!”
徐老汉(愕然,反应迟钝状):“锅,锅,锅,锅 - 炉 - 费?我家不烧锅炉呀?”
收费员(职业微笑依然):“老同志,我说的是过 - 路 -费,就是你的羊要过这个路口必须交费,understand?”
徐老汉(近镜头 10 秒,嘴巴张开):“我 - 我 - 我知道汽车过路要收费,这羊也要收费呀?”
收费员(居高临下 +不解状):“老同志,你怎么就不明白呢,那么我问你,汽车几个轮子?”
徐老汉(稍放松):“这个我知道,今天在家里我孙子还问我这个问题,4 个!”
收费员(生气,站起):“嘿!老头,你还骂人不带脏字,既然知道汽车四个轮子,难道就不知道这羊有几条腿吗?!”
徐老汉(尴尬,依然不解状):“也,也,也是 4 个呀,这有关系吗?”
收费员(生气,站起):“怎么没关系!我们头说了,只要是 4 条腿的都要收费!”
…
(画外音)
由于徐老汉没钱,收费员就将他的羊拿走一半,看到老汉泪水涟涟,犹豫了一下,又还给老汉一只。
巧合的是,后面每过一个收费站,都是拿走当时羊的一半,然后退还一只,等到老汉到达市场,就只剩下 3 只羊了。
你,当代有良知的青年,能帮忙算一下老汉最初有多少只羊吗?
Input
输入数据第一行是一个整数 N,下面由 N
行组成,每行包含一个整数 a(0<a<=30),表示收费站的数量。
Output
对于每个测试实例,请输出最初的羊的数量,每个测试实例的输出占一行。
Sample Input
2
1
2
Sample Output
4
6
解题思路
简单题,可以直接 for 循环 sum = (sum - 1) * 2
同样可以用递推式: f(0) = 3,f(1) = 4 ,f(n) = [f(n-1) - 1] × 2
另外通过递推式也可以得到公式 f(n) = 2^n + 2
参考源码
1 | #include <iostream> |
2043 密码
Problem Description
网上流传一句话:“常在网上飘啊,哪能不挨刀啊~”。其实要想能安安心心地上网其实也不难,学点安全知识就可以。
首先,我们就要设置一个安全的密码。那什么样的密码才叫安全的呢?一般来说一个比较安全的密码至少应该满足下面两个条件:
(1). 密码长度大于等于 8,且不要超过 16。
(2). 密码中的字符应该来自下面 “字符类别” 中四组中的至少三组。
这四个字符类别分别为:
- 大写字母:A,B,C…Z;
- 小写字母:a,b,c…z;
- 数字:0,1,2…9;
- 特殊符号:~,!,@,#,$,%,^;
给你一个密码,你的任务就是判断它是不是一个安全的密码。
Input
输入数据第一行包含一个数 M,接下有 M 行,每行一个密码(长度最大可能为 50),密码仅包括上面的四类字符。
Output
对于每个测试实例,判断这个密码是不是一个安全的密码,是的话输出 YES,否则输出 NO。
Sample Input
3
a1b2c3d4
Linle@ACM
^~^@^@!%
Sample Output
NO
YES
NO
解题思路
根据要求判断即可,若满足条件,则设置 flag=1
参考源码
1 | #include <cstring> |
2044 一只小蜜蜂…
Problem Description
有一只经过训练的蜜蜂只能爬向右侧相邻的蜂房,不能反向爬行。请编程计算蜜蜂从蜂房 a 爬到蜂房 b 的可能路线数。 其中,蜂房的结构如下所示。
Input
输入数据的第一行是一个整数 N, 表示测试实例的个数,然后是 N 行数据,每行包含两个整数 a 和 b (0<a<b<50)。
Output
对于每个测试实例,请输出蜜蜂从蜂房 a 爬到蜂房 b 的可能路线数,每个实例的输出占一行。
Sample Input
2
1 2
3 6
Sample Output
1
3
解题思路
通过观察图片,蜜蜂只能爬向右侧相邻的蜂房,比如:蜜蜂在 1 格里,它可以往 2、3 两格里爬
所以第 n 格的蜜蜂,可以往第 n+1 格或者第 n+2 格移动
之后就可以写出递推式 f(n) = f(n - 1) + f(n - 2)
参考源码
1 | #include <iostream> |
2045 不容易系列之(3)——LELE 的 RPG 难题
Problem Description
人称 “AC 女之杀手” 的超级偶像 LELE 最近忽然玩起了深沉,这可急坏了众多“Cole”(LELE 的粉丝,即 “可乐”), 经过多方打探,某资深 Cole
终于知道了原因,原来,LELE 最近研究起了著名的 RPG 难题:
有排成一行的n个方格,用红 (Red)、粉 (Pink)、绿 (Green)三色涂每个格子,每格涂一色,要求任何相邻的方格不能同色,且首尾两格也不同色.求全部的满足要求的涂法.以上就是著名的 RPG 难题.
如果你是 Cole, 我想你一定会想尽办法帮助 LELE 解决这个问题的;如果不是,看在众多漂亮的痛不欲生的 Cole 女的面子上,你也不会袖手旁观吧?
Input
输入数据包含多个测试实例,每个测试实例占一行,由一个整数 N 组成,(0<n<=50)。
Output
对于每个测试实例,请输出全部的满足要求的涂法,每个实例的输出占一行。
Sample Input
1
2
Sample Output
3
6
解题思路
同样的也是递推问题,试着写几项
f(1) = 3, f(2) = 6, f(3) = 6
f(n) = f(n - 1) + 2 * f(n - 2)
参考源码
1 | #include <iostream> |
2046 骨牌铺方格
Problem Description
在 2×n 的一个长方形方格中,用一个 1× 2 的骨牌铺满方格,输入 n , 输出铺放方案的总数.
例如 n=3 时,为 2× 3 方格,骨牌的铺放方案有三种,如下图:
Input
输入数据由多行组成,每行包含一个整数 n, 表示该测试实例的长方形方格的规格是 2×n (0<n<=50)。
Output
对于每个测试实例,请输出铺放方案的总数,每个实例的输出占一行。
Sample Input
1
3
2
Sample Output
1
3
2
解题思路
第 N 张牌的排列可以在 N-1 张牌的排列再在末尾加上一张竖的牌
也可以在 N-2 张合法排列的牌后面加上两张横着放的牌
f(1) = 1, f(2) = 2, f(3) = 3
f(n) = f(n - 1) + f(n - 2)
参考源码
1 | #include <iostream> |
2047 阿牛的 EOF 牛肉串
Problem Description
今年的 ACM 暑期集训队一共有 18 人,分为 6 支队伍。其中有一个叫做 EOF 的队伍,由 04 级的阿牛、XC 以及 05 级的 COY 组成。在共同的集训生活中,大家建立了深厚的友谊,阿牛准备做点什么来纪念这段激情燃烧的岁月,想了一想,阿牛从家里拿来了一块上等的牛肉干,准备在上面刻下一个长度为 n 的只由 “E” “O” “F”
三种字符组成 的字符串(可以只有其中一种或两种字符,但绝对不能有其他字符), 阿牛同时禁止在串中出现 O 相邻的情况,他认为,“OO” 看起来就像发怒的眼睛,效果不好。 你,NEW ACMer,EOF 的崇拜者,能帮阿牛算一下一共有多少种满足要求的不同的字符串吗?
PS:阿牛还有一个小秘密,就是准备把这个刻有 EOF 的牛肉干,作为神秘礼物献给杭电五十周年校庆,可以想象,当校长接过这块牛肉干的时候该有多高兴!这里,请允许我代表杭电的 ACMer 向阿牛表示感谢!再次感谢!
Input
输入数据包含多个测试实例,每个测试实例占一行,由一个整数 n 组成,(0<n<40)。
Output
对于每个测试实例,请输出全部的满足要求的涂法,每个实例的输出占一行。
Sample Input
1
2
Sample Output
3
8
解题思路
f[n][0]表示以 O 结尾的合法字符串,f[n][1]表示不以 O 结尾的合法字符串
以 O 结尾的合法字符串之后可以跟 E 或者 F
不以 O 结尾的合法字符串之后可以跟 E、O、F
f[n][0] = f[n - 1][1];
f[n][1] = 2 * (f[n - 1][0] + f[n - 1][1])
参考源码
1 | #include <iostream> |
2048 神、上帝以及老天爷
Problem Description
HDU 2006’10 ACM contest 的颁奖晚会隆重开始了!
为了活跃气氛,组织者举行了一个别开生面、奖品丰厚的抽奖活动,这个活动的具体要求是这样的:
首先,所有参加晚会的人员都将一张写有自己名字的字条放入抽奖箱中;
然后,待所有字条加入完毕,每人从箱中取一个字条;
最后,如果取得的字条上写的就是自己的名字,那么 “恭喜你,中奖了!”
大家可以想象一下当时的气氛之热烈,毕竟中奖者的奖品是大家梦寐以求的 Twins 签名照呀!不过,正如所有试图设计的喜剧往往以悲剧结尾,这次抽奖活动最后竟然没有一个人中奖!我的神、上帝以及老天爷呀,怎么会这样呢?不过,先不要激动,现在问题来了,你能计算一下发生这种情况的概率吗?不会算?难道你也想以悲剧结尾?!
Input
输入数据的第一行是一个整数 C, 表示测试实例的个数,然后是 C 行数据,每行包含一个整数 n (1<n<=20),表示参加抽奖的人数。
Output
对于每个测试实例,请输出发生这种情况的百分比,每个实例的输出占一行,结果保留两位小数(四舍五入),具体格式请参照 sample output。
Sample Input
1
2
Sample Output
50.00%
解题思路
全错排问题
若前 n-1 个人拿到的都不是自己的名字,第 n 个人拿到的是自己的名字,只需要与前 n-1 个人中的任意一个交换即可满足,有 n-1 种可能
若前 N-1 个人不满足错排,第 n 个人只要与第 i 个人交换即可满足,这时 n-2 个人完全错排,有 f(n-2)种可能,若第 i 个人不与第 n 个人交换,则 n-1 个元素错排,有 f(n-1)种可能
递推公式:f[n]=(n-1)*(f[n-1]+f[n-2])
参考源码
1 | #include <iostream> |
2049 不容易系列之(4)——考新郎
Problem Description
国庆期间,省城 HZ
刚刚举行了一场盛大的集体婚礼,为了使婚礼进行的丰富一些,司仪临时想出了有一个有意思的节目,叫做"考新郎", 具体的操作是这样的: 首先,给每位新娘打扮得几乎一模一样,并盖上大大的红盖头随机坐成一排;然后,让各位新郎寻找自己的新娘。每人只准找一个,并且不允许多人找一个.最后,揭开盖头,如果找错了对象就要当众跪搓衣板…看来做新郎也不是容易的事情…
假设一共有 N 对新婚夫妇,其中有 M 个新郎找错了新娘,求发生这种情况一共有多少种可能.
Input
输入数据的第一行是一个整数 C, 表示测试实例的个数,然后是 C 行数据,每行包含两个整数 N 和 M(1<M<=N<=20)。
Output
对于每个测试实例,请输出一共有多少种发生这种情况的可能,每个实例的输出占一行。
Sample Input
2
2 2
3 2
Sample Output
1
3
解题思路
先是排列组合,从 N 个新郎中选出 M 个,之后是 M 的全错排
计算 C(n,m),可以通过定义计算,即:
我这里用了递推公式计算:
计算 m 的全错排,参见 oj2048
递推公式:f[n] = (n - 1) * (f[n - 1] + f[n - 2])
参考源码
1 | #include <iostream> |