HNUCM-2022年秋季学期《算法分析与设计》练习5

还未用Python解决E题。

目录

问题 A: X星数列

问题 B: 北京天坛火了

问题 C: 字符识别?

问题 D: X星计数

问题 E: X星人的集会

问题 F: 递归求解I

问题 H: 数的划分 


问题 A: X星数列

题目描述:

爱冒险的X星人在一艘海底沉船上发现了一串神秘数列,这个数列的前8项如下:
5, 8, 18, 34, 70, 138, 278, 554
X星人对这串数列产生了浓厚的兴趣,他希望你能够帮他发现这个神秘数列中所蕴含的规律,并且编写一个程序输出该数列前N项的和。
当输入一个正整数N时,请输出这个神秘数列前N项的和。

思路:找规律,很容易发现,f(n) = 2 * f(n - 2) + f(n - 1)。

nums = [5, 8, 18, 34, 70, 138, 278, 554, 1110, 2218, 4438, 8874, 17750, 35498, 70998, 141994, 283990, 567978, 1135958, 2271914]
n = int(input())
print(sum(nums[:n]))

非递归:

nums = [5, 8, 18, 34, 70]
n = int(input())
if n > len(nums):
    for _ in range(len(nums), n):
        nums.append(nums[-1] + nums[-2] * 2)
print(sum(nums[:n]))

问题 B: 北京天坛火了

题目描述:

除了胡夫金字塔外,北京天坛同样出现在了2020高考卷上。小波同样在此基础上改编为了一道编程题。

北京天坛的圜丘坛为古代祭天的场所,分上、中、下三层,上层中心有一块圆形石板(称为天心石),环绕天心石砌m块扇面形石板构成第一环,向外每环依次增加m块。下一层的第一环比上一层的最后一环多m块,向外每环依次增加m块。已知每层环数相同。 

现给出每层的环数n和每一环比上一环增加的块数m,求总共有多少块扇面形石板?

思路:根据题意,易发现一共用3m个圆环,每个圆环比上一个圆环多m块石板,示意一个等差数列,第i个圆环有m*i个石板。

非递归:

n, m = map(int, input().split())
res = 0
for i in range(1, n * 3 + 1):
    res = res + m * i
print(res)

也可以直接推导等差数列和的公式。

问题 C: 字符识别?

题目描述:

你的任务是写一个程序进行字符识别。别担心,你只需要识别1, 2, 3,如下:

.*.  ***  ***

.*.  ..*  ..*

.*.  ***  ***

.*.  *..  ..*

.*.  ***  ***

思路:找三个字符不同的关键点,即可简化检测,1:第二行中间为*,2:第四行左侧为*,3:第四行右侧为*。

非递归:

while True:
    try:
        n = int(input())
        maze = [input() for _ in range(5)]
        # print(maze)
        for i in range(1, 4 * n + 1, 4):
            if maze[1][i] == '*':
                print(1, end='')
            elif maze[3][i - 1] == '*':
                print(2, end='')
            elif maze[3][i + 1] == '*':
                print(3, end='')
        print()
    except:
        break

问题 D: X星计数

题目描述:

热爱数学的X星人又发现了一个有趣的游戏,游戏名叫做:1的个数。
具体游戏规则为:给定一个十进制正整数,计算对应的二进制整数中有多少个1。

思路:转换成二进制,一位一位的判断,统计出现1的次数。

非递归:

def fun(x: int):
    res = 0
    while x > 0:
        res = res + 1 if x % 2 == 1 else res + 0
        x //= 2
    return res


t = int(input())
while t > 0:
    t -= 1
    try:
        n = int(input())
        print(fun(n))
    except:
        break

问题 E: X星人的集会

题目描述:

X星人每天集会时,热衷于以一个特定的顺序站队,将X星人编号为1∼N。
最初,X星人从左到右按照a1,a2,…,aN的顺序排列。最终,需要变成从左到右按照b1,b2,…,bN的顺序排列。
所以,需要对X星人队伍进行一系列的调整。
每次只能让一个X星人向左移动任意位置。
问,至少需要多少次操作,才能变成特定顺序的队伍。

c++:

#include<bits/stdc++.h>
using namespace std;
int n, og[100005], tg[100005], cnt=-1;
map<int, bool> my_map;
int main()
{
    scanf("%d", &n);
    for(int i=1;i<=n;i++)
        scanf("%d", &og[i]);
    for(int i=1;i<n;i++)
        scanf("%d", &tg[i]);
    int a=1, b=1;
    while(b<=n)
    {
        if(my_map[og[a]]){a++;continue;}
        if(og[a]==tg[b]){a++;b++;}
        else{my_map[tg[b]]=1;b++;cnt++;}
    }
    printf("%d\n", cnt);
}

问题 F: 递归求解I

题目描述:

使用递归编写一个程序求如下表达式前n项的计算结果:  (n<=100)
1+1/4+1/9 +1/16+1/25+......+1/n^2
输入n,输出表达式的计算结果。(四舍五入保留两位小数)

非递归:

while True:
    try:
        n, res = int(input()), 0
        for i in range(1, n + 1):
            res = res + 1 / i ** 2
        print("%.2f" % res)
    except:
        break

问题 H: 数的划分 

题目描述:

使用递归编写一个程序,求一个正整数n的所有划分个数。
例如,输入3,输出3;输入4,输出5。 

思路:利用二维列表存储数据,自底向上计算,f[n][m]表示整数n的加数最大不超过m的划分数。

非递归:

f = [[1]]
while True:
    try:
        n = int(input())
        if n >= len(f):
            for i in range(len(f), n + 1):
                for j in range(i + 1):
                    if j == 0:
                        f.append([0] * (i + 1))
                    else:
                        f[i][j] = f[i][j - 1] + f[i - j][min(i - j, j)]
        print(f[n][n])
    except:
        break
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值