数的分解

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

把2019 分解成 3 个各不相同的正整数之和,并且要求每个正整数都不包含数字 2 和 4,一共有多少种不同的分解方法?

注意交换 3 个整数的顺序被视为同一种方法,例如 1000+1001+18 和 1001+1000+18 被视为同一种。

求解

判断正整数不包含数字2和4的方法见代码,下面说一下暴力破解遍历的范围划分。

题目要求三个正整数各不相同,且交换三个整数顺序方法为同种方法,那么我们可以把2019分为3份,每份大小为i、j、k,并令i<j<ki的遍历范围上限为2019除以3后的结果,是因为i至少遍历要达到这个数,定这个数而不定2019可以减少循环次数,j同理。

cnt=0
for i in range(1,673+1):
    for j in range(i+1,1346+1):
        k=2019-i-j
        if('2' not in str(i) and '4' not in str(i) and\
                '2' not in str(j) and '4' not in str(j) and\
                '2' not in str(k) and '4' not in str(k) and k>j):
            cnt+=1
print(cnt)

猜生日

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

今年的植树节(2012 年 3 月 12 日),小明和他的叔叔还有小伙伴们一起去植树。休息的时候,小明的同学问他叔叔多大年纪,他叔叔说:“我说个题目,看你们谁先猜出来!”

“把我出生的年月日连起来拼成一个 8 位数(月、日不足两位前补 0)正好可以被今天的年、月、日整除!”

他想了想,又补充到:“再给个提示,我是 6 月出生的。”

根据这些信息,请你帮小明算一下,他叔叔的出生年月日。

格式是年月日连成的 88 位数。例如,如果是 1948 年66 月12 日,就写:19480612。

求解

如果找不到结果,输出-1,调整遍历范围。

y=2012
m=3
d=12
flag=0
for i in range(2012,1900,-1):
    for j in range(1,31):
        bir=str(i)+'06'+(str(j) if len(str(j))==2 else '0'+str(j))
        if (int(bir)%y==0) and (int(bir)%m==0) and (int(bir)%d==0):
            print(bir)
            flag=1
            break
    if(flag==1):
        break
if flag==0:
    print(-1)

成绩统计

题目描述

小蓝给学生们组织了一场考试,卷面总分为 100 分,每个学生的得分都是一个 0 到 100 的整数。

如果得分至少是 60 分,则称为及格。如果得分至少为 85 分,则称为优秀。

请计算及格率和优秀率,用百分数表示,百分号前的部分四舍五入保留整 数。

输入描述

输入的第一行包含一个整数 (1≤n≤104),表示考试人数。

接下来 n 行,每行包含一个 0 至 100 的整数,表示一个学生的得分。

输出描述

输出两行,每行一个百分数,分别表示及格率和优秀率。百分号前的部分 四舍五入保留整数。

输入输出样例

示例
输入
7
80
92
56
74
88
100
0
输出
71%
43%

运行限制

求解

注意python输出“%”不用转义符号。而且这个“%”,还有全角和半角之分,为了保险可直接复制题给输出的百分号。

n=int(input())
jige=0
youxiu=0
sum_=0
for i in range(n):
    score=int(input())
    sum_+=1
    if score>=60:
        jige+=1
    if score>=85:
        youxiu+=1
print(round(jige/sum_*100),'%',sep='')
print(round(youxiu/sum_*100),'%',sep='')

最大和

问题描述

小蓝在玩一个寻宝游戏, 游戏在一条笔直的道路上进行, 道路被分成了 n 个方格, 依次编号 1 至 n, 每个方格上都有一个宝物, 宝物的分值是一个整数 (包括正数、负数和零), 当进入一个方格时即获得方格中宝物的分值。小蓝可 以获得的总分值是他从方格中获得的分值之和。

小蓝开始时站在方格 1 上并获得了方格 1 上宝物的分值, 他要经过若干步 到达方格 n

当小蓝站在方格 p 上时, 他可以选择跳到 p+1,p+D(np) 这些方格 中的一个, 其中D(1)=1,D(x)(x>1) 定义为 x 的最小质因数。

给定每个方格中宝物的分值, 请问小蓝能获得的最大总分值是多少。

输入格式

输入的第一行包含一个正整数 n

第二行包含 n 个整数, 依次表示每个方格中宝物的分值。

输出格式

输出一行包含一个整数, 表示答案。

样例输入

这个样例输入的示意多了两个换行符,但是实际检测是没有的。


5

1 -2 -1 3 5

样例输出


8

最优的跳跃方案为: 1→3→4→51→3→4→5 。

评测用例规模与约定

对于 40% 的评测用例,1≤n≤100 。

对于 80% 的评测用例, 1≤n≤1000 。

对于所有评测用例, 1≤n≤10000, 每个宝物的分值为绝对值不超过 105 的整数。

求解

题目可分解成两个问题,一是最小质因数的求解,二是线性动态规划问题。

最小质因数求解使用欧拉筛,可参考

python代码:

欧拉筛(线性筛)超级详解 - Python3实现_python欧拉筛_ZengXincs的博客-CSDN博客

理论知识:

算法学习笔记(17): 素数筛 - 知乎 (zhihu.com)

线性动态规划,设dp[i]为走到第i个格子得到的最大得分。在动归状态转移大循环开始前,需要先把dp的所有元素赋一个绝对值很大的负数(-9999能过80%案例,剩下20%超时;-999有答案错误),然后根据欧拉筛得出的最大步数进行状态转移。

dp[i]=max(dp[i],dp[j]),dp[j]为转移之前符合要求的格子的最大得分。

# input()
n=int(input())
# input()
scores=[0]+list(map(int,input().split()))
st,cnt,primer,skip_num,dp=[False]*(n+1),0,[0]*(n+1),[0]*(n+1),[-9999]*(n+1)
skip_num[n-1]=1
skip_num[1]=1
dp[1]=scores[1]
for i in range(2,n):
    if st[i]==False:
        primer[cnt]=i
        cnt+=1
        skip_num[n-i]=i
    for j in range(cnt):
        if primer[j]*i>n: break
        st[i*primer[j]]=True
        skip_num[n-i*primer[j]]=primer[j]
        if i%primer[j]==0:
            skip_num[n-i]=primer[j]
            break

for i in range(1,n+1):
    flag=0
    for j in range(1,i):
        if i-j<=skip_num[j] or (i-j)==1:
            dp[i]=max(dp[i],dp[j])
            flag=1
    if flag==0:
        dp[i]=scores[i]
    else:
        dp[i]+=scores[i]
print(dp[n])

posted on 2023-03-08 18:43  快乐的乙炔  阅读(0)  评论(0)    收藏  举报  来源