数的分解
题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
把2019 分解成 3 个各不相同的正整数之和,并且要求每个正整数都不包含数字 2 和 4,一共有多少种不同的分解方法?
注意交换 3 个整数的顺序被视为同一种方法,例如 1000+1001+18 和 1001+1000+18 被视为同一种。
求解
判断正整数不包含数字2和4的方法见代码,下面说一下暴力破解遍历的范围划分。
题目要求三个正整数各不相同,且交换三个整数顺序方法为同种方法,那么我们可以把2019分为3份,每份大小为i、j、k,并令i<j<k。i的遍历范围上限为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(n−p) 这些方格 中的一个, 其中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])
浙公网安备 33010602011771号