蓝桥杯python练习题-14

C-填空题

题意

对于一个日期,我们可以计算出年份的各个数位上的数字之和,也可以分别计算月和日的各位数字之和。请问从 1900 年 1 月 1 日至 9999 年 12 月 31 日,总共有多少天,年份的数位数字之和等于月的数位数字之和加日的数位数字之和。

例如,2022年11月13日满足要求,因为 2+0+2+2=(1+1)+(1+3) 。请提交满足条件的日期的总数量。

答案

70910

import os
import sys

# 请在此输入您的代码
def num_sum(n):#数字求和
    sum=0
    while n>0:
        sum=sum+n%10
        n=n//10
    return sum
count = 0
day = [0,31,28,31,30,31,30,31,31,30,31,30,31]

for y in range(1900,10000):
    for m in range(1,13):
        if (y%4==0 and y%100!=0 )or(y%400==0):#闰年2月单独考虑
            day[2]=29
        else:
            day[2]=28
        for d in range(1,day[m]+1):
            if num_sum(y)==num_sum(m)+num_sum(d):
                count+=1
print(count)

试题A:特殊日期   (5分)

【问题描述】

        记一个日期为 yy 年 mm 月 dd 日,统计从 2000 年 1 月 1 日到 2000000 年 1 月 1 日:有多少个日期满足年份 yy 是月份 mm 的倍数,同时也是 dd 的倍数。

【答案】

        35813063

count=1
day = [0,31,28,31,30,31,30,31,31,30,31,30,31]
for y in range(2000,2000000):
    for m in range(1,13):
        if (y % 4 == 0 and y % 100 != 0) or (y % 400 == 0):  # 闰年2月单独考虑
            day[2] = 29
        else:
            day[2] = 28
        for d in range(1,day[m]+1):
            if y%m==0 and y%d==0:
                count+=1

print(count)

试题B:分糖果     (5分)

【问题描述】

        两种糖果分别有9个和16个,要全部分给7个小朋友,每个小朋友得到的糖果总数最少为2个最多为5个,问有多少种不同的分法,糖果必须全部分完。
        如果有其中一个小朋友在两种方案中分到的糖果不完全相同,这两种方案就算作不同的方案。

【答案提交】

        5067671

a=[0,1,2,0,1,2,3,0,1,2,3,4,0,1,2,3,4,5]
b=[2,1,0,3,2,1,0,4,3,2,1,0,5,4,3,2,1,0]

def divide(t,n1,n2):#第几个小朋友,目前剩下的a糖果数,目前剩下的b糖果数
    global count
    if t==8:
        if n1==0 and n2==0:
            count+=1
        else:
            return
    else:
        for i in range(len(a)):
            if n1>=a[i] and n2>=b[i]:
                divide(t+1,n1-a[i],n2-b[i])
count=0
divide(1,9,16)
print(count)

试题C:三国游戏     (10分) 

【问题描述】

        小蓝正在玩一款游戏,游戏中魏(X)、蜀(Y)、吴(Z)三个国家各自拥有一定数量的士兵X、Y、Z(一开始可以认为都是0)。游戏有n个可能会发送的事件,每个事件之间相互独立且最多只发送一次,当第i个事件发送时会分别让X、Y、Z增加A_{i} B_{i} C_{i}.

        当游戏结束时(所以事件的发生与否已经确定),如果X,Y,Z的其中一个大于另外两个之和,我们认为其获胜。例如,当X>Y+Z时,我们认为魏国获胜,小蓝想知道游戏结束时,如果有其中一个国家获胜,最多发生了多少个事件?如果不存在任何一个让某个国家获胜的情况,请输出-1。

【输入格式】

        输入的第一行包含一个整数n。
        第二行包含n个整数表示A,相邻整数之间使用一个空格分隔
        第三行包含n个整数表示B,相整数之间使用一个空格分隔
        第四行包含n个整数表示C,相邻整数之间使用一个空格分隔

【输出格式】

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

n=int(input())

aa=list(map(int,input().split()))#每次的事件
bb=list(map(int,input().split()))
cc=list(map(int,input().split()))

all_a=sorted([aa[i]-bb[i]-cc[i] for i in range(n)],reverse=True)#每次事件中a获胜的差
all_b=sorted([bb[i]-aa[i]-cc[i] for i in range(n)],reverse=True)#每次事件中b获胜的差
all_c=sorted([cc[i]-bb[i]-aa[i] for i in range(n)],reverse=True)#每次事件中c获胜的差
suma,sumb,sumc,counta,countb,countc=0,0,0,0,0,0
for i in range(n):
    suma=suma+all_a[i]
    if suma<=0:
        break
    else:
        counta+=1
for i in range(n):
    sumb=sumb+all_b[i]
    if sumb<=0:
        break
    else:
        countb+=1
for i in range(n):
    sumc=sumc+all_c[i]
    if sumc<=0:
        break
    else:
        countc+=1
count=max(counta,countb,countc)
print(count if count else -1)

试题D:平均    (10分)

【问题描述】

        有一个长度为n的数组(n是10的倍数),每个数a都是区间[0, 9]中的整数。小明发现数组里每种数出现的次数不太平均,而更改第i个数的代价为bi,他想更改若干个数的值使得这10种数出现的次数相等(都等于n/10),请问代价和最少为多少。

【输入格式】

        输入的第一行包括一个正整数n。
        接下来n行,第i行包括两个整数ai,bi,用一个空格分隔。

【输出格式】

        输出包括一个正整数表示答案。

n=int(input())
a=[[] for i in range(10)]

for i in range(n):
    aa,bb=map(int,input().split())
    a[aa].append(bb)

ave=n//10
count=0

for i in range(10):
    if len(a[i])>ave:
        a[i].sort(reverse=True)
        for j in a[i][ave:]:
            count=count+j

print(count)

试题E:翻转     (15分)

【问题描述】

        小蓝用黑白棋的n个棋子排成了一行,他在脑海里想象出了一个长度为 n的01串T,他发现如果把黑棋当做1,白棋当做0,这一行棋子也是一个长度为n的01串S。
        小蓝决定,如果在S中发现一个棋子和它两边的棋子都不一样,就可以将其翻转变成另一个颜色。也就是说,如果S中存在子串 101或者010,就可以选择将其分别变为111和000,这样的操作可以无限重复。
        小蓝想知道最少翻转多少次可以把S变成和一模一样

【输入格式】

        输入包含多组数据
        输入的第一行包含一个正整数 D表示数据组数
        后面2D行每行包含一个01串,每两行为一组数据,第 2i-1行为第i组数据的Ti,第2i行为第i组数据的Si,Si和Ti度均为n。

【输出格式】

        对于每组数据,输出一行包含一个整数,表示答案,如果答案不存在请输出-1。

d=int(input())

for i in range(d):
    t=list(input())
    s = list(input())
    count=0
    flag=1
    for j in range(len(s)):
        if s[j]!=t[j]:
            if j-1>=0 and j+1<len(s) and s[j]!=s[j-1] and s[j]!=s[j+1]:
                s[j]=s[j-1]
                count+=1
            else:
                flag=0
                break
    print(count if flag else -1)

 注意:这道题最后if flag判断中,flag=0时才为false,flag=-1时为true!!!flag=-1表明flag有值不为空,所以是true

试题G:阶乘的和     (20分)

【问题描述】

        给定n个数A_{i},问能满足m!为\sum_{i=1}^{m}(A_{i}!)的因数的最大的m是多少,其中m!表示m的阶乘,即1x2x3x···xm。

【输入格式】

        输入的第一行包含一个整数n。
        第二行包含n个整数,分别表示A_{i},相邻整数之间使用一个空格分隔。

【输出格式】

        给出一行包括一个整数表示答案。

n=int(input())
a=list(map(int,input().split()))
a.sort()
st,i,cnt = a[0],0,0#st是当前数,i是循环次数
while i<n:
  while i<n and a[i]==st:#count是当前的个数
    cnt += 1
    i += 1
  if cnt and cnt%(st+1)==0:#可以向上转换
    cnt,st = cnt//(st+1),st+1#上一级数st+1从cnt=1开始计数
  else:#不能向上转换,当前数就是“m”
    break
print(st)

思路:如果所有数都只出现一次,则m为min(Ai)。有(min(Ai)+1)个min(Ai)!,m才能变为min(Ai)+1,具体来说,有:3!+3!+3!+3!=4*3!==4!

print("方法二,但是没跑出来,可以掠过不看")
n=int(input())
a=list(map(int,input().split()))
l=dict()#字典储存
for i in a:
    if i not in l:
        l[i]=0#如果字典里没有i,创建一个i作为key
    l[i]+=1#统计每个数的个数
flag=1
for i in sorted(l.keys()):#从小到大排
    m=l[i]//(i+1)
    n=l[i]%(i+1)
    if n==0:#这个数可以向上转化一个阶乘
        if i+1 not in l:
            l[i+1]=0
        l[i+1]+=m
        del l[i]
    else:#不能转换,这个数就是最大的“m”
        flag=0
        break
if flag==0:#不能转换情况下,直接输出i
    print(i)
else:#可以转换情况下,此时key中只剩一个数
    p=i+1#key
    q=l[p]#value
    while q>=p+1:
        m = l[p] // (p + 1)
        n = l[p] % (p + 1)
        if n != 0: 
            break
        l[p + 1] += m
        del l[p]
    for i in l.keys():
        print(i)

试题I:子树的大小     (25分)

【问题描述】

        给定一棵包含n个结点的完全m又树,结点按从根到叶、从左到右的顺序依次编号。例如下图是一个拥有 11个结点的完全3又树。

        你需要求出第k个结点的子树的结点数。 

【输入格式】

        输入包含多组询问。
        输入的第一行包含一个整数T,表示询问次数。
        接下来行,每行包含三个整数 n,m,k,表示一组询问。

【输出格式】

        输出T行,每行包含一个整数表示对应询问的答案。

t=int(input())
for i in range(t):
    n,m,k=map(int,input().split())
    count=0#结点数
    l=k#左指针
    r=k#右指针
    res=1#子树中的节点数
    while True:
        count+=res#先加上自己的节点数
        if r*m+1>n:#超出节点范围
            if (l-1)*m+2<=n:#最后一个节点在在k中
                count+=n-((l-1)*m+1)#加上子树中的节点树
            break
        res*=m#每一层多3个节点
        r=r*m+1#右侧的节点总数
        l=(l-1)*m+2#左侧的节点总数
    print(count)

注意:子树中自己也算一个节点,所以对于图中的k=4时,节点数为2 

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值