【思特奇杯·云上蓝桥-算法集中营】结课作业

目录

一、门牌制作

题干

解答

二、既约分数

题干

解答

三、蛇形填数

题干

解答

四、跑步锻炼

题干

解答

五、七段码

题干

解答

六、成绩统计

题干

解答

七、回文日期

题干

解答

八、字串分值和

题干

解答

九、平面切分

题干

解答

十、字串排序

题干

解答


一、门牌制作

题干

【问题描述】

小蓝要为一条街的住户制作门牌号。

这条街一共有 2020 位住户,门牌号从 1 到 2020 编号。

小蓝制作门牌的方法是先制作 0 到 9 这几个数字字符,最后根据需要将字符粘贴到门牌上,例如门牌 1017 需要依次粘贴字符 1、0、1、7,即需要 1 个字符 0,2 个字符 1,1 个字符 7。

请问要制作所有的 1 到 2020 号门牌,总共需要多少个字符 2?

【答案提交】

这是一道结果填空的题,你只需要算出结果后提交即可。 本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

解答

num=0

for i in range(1,2021):
    while (i>0):
        if i%10 ==2:
            num=num+1
        i=i//10

print(num)     #624

二、既约分数

题干

【问题描述】

如果一个分数的分子和分母的最大公约数是1,这个分数称为既约分数。例如,3/4,5/2,1/8,7/1都是既约分数。请问,有多少个既约分数,分子和分母都是1到2020之间的整数(包括1和2020)?

【答案提交】

这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

解答

def f(x,y):
    if y!= 0:
        return f(y,x%y)
    else:
        return x

num=1
for i in range(1,2020):
    for j in range(i+1,2021):
        if f(j,i)==1:
            num=num+2

print(num)       #2481215

三、蛇形填数

题干

【问题描述】

如下图所示,小明用从 1 开始的正整数“蛇形”填充无限大的矩阵。 1 2 6 7 15 … 3 5 8 14 … 4 9 13 … 10 12 … 11 … … 容易看出矩阵第二行第二列中的数是 5。请你计算矩阵中第 20 行第 20 列的数是多少?

解答

不难发现对角线上的元素都是奇数行,且都在最中间

设第2行有3个元素,第2-1行有4个元素;第3行有5个元素,第3-1行有6个元素。故而,第19行有37个元素,第19-1行有38个元素。

num=0

for i in range(1,39):   
    num=num+i
print(num+20)      #761

四、跑步锻炼

题干

小蓝每天都锻炼身体。 正常情况下,小蓝每天跑1千米。如果某天是周一或者月初(1日),为了激励自己,小蓝要跑2千米。如果同时是周一或月初,小蓝也是跑2千米。 小蓝跑步已经坚持了很长时间,从2000年1月1日周六(含)到2020年10月1日周四(含)。请问这段时间小蓝总共跑步多少千米?

解答

km=2     # 最后一天是10月1日,要跑2km
date=5

for year in range(2000,2020):
    for month in range(1,13):
        if month==1 or month==3 or month==5 or month==7 or month==8 or month==10 or month==12:
            for day in range(1,32):
                date=(date+1)%7
                if day==1 or date==1:
                    km=km+2
                else:
                    km=km+1
        if month==4 or month==6 or month==9 or month==11:
            for day in range(1,31):
                date=(date+1)%7
                if day==1 or date==1:
                    km=km+2
                else:
                    km=km+1
        if month==2 and year%4==0:
            for day in range(1,30):
                date=(date+1)%7
                if day==1 or date==1:
                    km=km+2
                else:
                    km=km+1
        elif month==2 and year%4!=0:
            for day in range(1,29):
                date=(date+1)%7
                if day==1 or date==1:
                    km=km+2
                else:
                    km=km+1

for month in range(1,10):   #在2020年只跑到10月1日
    if month == 1 or month == 3 or month == 5 or month == 7 or month == 8:
        for day in range(1, 32):
            date = (date + 1) % 7
            if day == 1 or date == 1:
                km = km + 2
            else:
                km = km + 1
    if month == 4 or month == 6 or month == 9:
        for day in range(1, 31):
            date = (date + 1) % 7
            if day == 1 or date == 1:
                km = km + 2
            else:
                km = km + 1
    if month == 2:
        for day in range(1, 30):
            date = (date + 1) % 7
            if day == 1 or date == 1:
                km = km + 2
            else:
                km = km + 1

print(km)     #8879

五、七段码

题干

小蓝要用七段码数码管来表示一种特殊的文字。

上图给出了七段码数码管的一个图示,数码管中一共有 7 段可以发光的二 极管,分别标记为 a, b, c, d, e, f, g。 小蓝要选择一部分二极管(至少要有一个)发光来表达字符。在设计字符的表达时,要求所有发光的二极管是连成一片的。 例如:b 发光,其他二极管不发光可以用来表达一种字符。 例如:c 发光,其他二极管不发光可以用来表达一种字符。这种方案与上一行的方案可以用来表示不同的字符,尽管看上去比较相似。 例如:a, b, c, d, e 发光,f, g 不发光可以用来表达一种字符。 例如:b, f 发光,其他二极管不发光则不能用来表达一种字符,因为发光的二极管没有连成一片。请问,小蓝可以用七段码数码管表达多少种不同的字符?

解答

import itertools

def f(*args):
    flag=True
    con={1:[2,6],2:[1,3,7],3:[2,4,7],4:[3,5],5:[4,6,7],6:[1,5,7],7:[2,3,5,6]}
    for i in range(len(args)-1):
        temp=con[args[i]]
        if args[i+1] not in temp:
            flag=False
            break
    return flag

light=[1,2,3,4,5,6,7]
sum=[]

for i in range(2,6):
    for t in itertools.permutations(light,i):
        if f(*t) == True:
            temp=list(t)
            temp.sort()
            if temp not in sum:       # 去重
                sum.append(temp)

print(len(sum)+15)

六、成绩统计

题干

【问题描述】

小蓝给学生们组织了一场考试,卷面总分为 100 分,每个学生的得分都是一个 0 到 100 的整数。 如果得分至少是 60 分,则称为及格。如果得分至少为 85 分,则称为优秀。请计算及格率和优秀率,用百分数表示,百分号前的部分四舍五入保留整数。

【输入格式】

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

【输出格式】

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

解答

n=int(input())
ok=great=0

for i in range(n):
    score=int(input())
    if score>=85:
        great=great+1
    if score>=60:
        ok=ok+1

print(str(ok*100//n)+"%")
print(str(great*100//n)+"%")

七、回文日期

题干

2020 年春节期间,有一个特殊的日期引起了大家的注意:2020 年 2 月 2 日。

因为如果将这个日期按 yyyymmdd 的格式写成一个 8 位数是 20200202,恰好是一个回文数。

我们称这样的日期是回文日期。

有人表示 20200202 是“千年一遇” 的特殊日子。

对此小明很不认同,因为不到 2 年之后就是下一个回文日期:20211202 即 2021 年 12 月 2 日。

也有人表示 20200202 并不仅仅是一个回文日期,还是一个 ABABBABA 型的回文日期。

对此小明也不认同,因为大约 100 年后就能遇到下一个 ABABBABA 型的回文日期:21211212 即 2121 年 12 月 12 日。

算不上“千年一遇”,顶多算“千年两遇”。

给定一个 8 位数的日期,请你计算该日期之后下一个回文日期和下一个 ABABBABA 型的回文日期各是哪一天。

注意:下一个回文日期和下一个 ABABBABA 型的回文日期可能是同一天。

ABABBABA 型的回文日期,需要满足 A≠B。

输入格式
输入包含一个八位整数 N,表示日期。

输出格式
第一行表示下一个回文日期,
第二行表示下一个 ABABBABA 型的回文日期。

输入样例
20200202

输出样例
20211202
21211212

数据范围
对于所有评测用例,10000101 ≤ N ≤ 89991231,保证 N 是一个合法日期的 8 位数表示。

解答

def judge(date):    #判断日期是否合法
    flag=False
    y=int(date[0:4])
    m=int(date[4:6])
    d=int(date[6:8])

    if (m==1 or m==3 or m==5 or m==7 or m==8 or m==10 or m==12) and d<=31:
        flag=True
    elif (m==4 or m==6 or m==9 or m==11) and d<=30:
        flag=True
    elif m==2:
        if y%400==0 or (y%4==0 and y%100!=0) and d<=29:
            flag=True
        elif d<=28:
            flag=True

    return flag

n=int(input())
for i in range(n+1,89991231):
    temp=str(i)
    if temp[:]==temp[::-1] and judge(temp):
        print(temp)
        break

for i in range(n+1,89991231):
    temp=str(i)
    if temp[0:4]==temp[7:3:-1] and temp[0:2]==temp[2:4] and judge(temp):
        print(temp)
        break

八、字串分值和

题干

对于一个字符串 S,我们定义 S 的分值 f(S) 为 S 中出现的不同的字符个数。
例如 f(“aba”)=2,f(“abc”)=3,f(“aaa”)=1。
现在给定一个字符串 S[0…n−1](长度为 n),请你计算对于所有 S 的非空子串 Si…j,f(S[i…j]) 的和是多少。

样例示范:

输入:ababc
输出:28

解答

def count(*args):
    l=set()
    for i in args:
        l.add(i)
    return len(l)

s=input()
sum=0

for i in range(len(s)):
    temp=[]
    for j in range(i,len((s))):
        temp.append(s[j])
        sum=sum+count(*temp)
        print(temp)

print(sum)

九、平面切分

题干

问题描述
平面上有 N条直线,其中第 i条直线是 y = Ai*x + B。

请计算这些直线将平面分成了几个部分。

输入格式
第一行包含一个整数N。

以下N行,每行包含两个整数 Ai, Bi。

输出格式
一个整数代表答案。

样例输入

3
1 1
2 2
3 3

样例输出

6

解答

在同一平面内,两条直线不平行就一定相交

新增面数为新增点数+1,这题实际上求的是交点个数

n=int(input())
flat=1
co=[]

for i in range(n):
    li=set()
    a,b=map(int,input().split())
    for j in range(len(co)):
        if a!=co[j][0]:
            x=(b-co[j][1])/(co[j][0]-a)
            li.add(x)
    flat=flat+len(li)+1
    co.append((a,b))
    
print(flat)

十、字串排序

题干

小蓝最近学习了一些排序算法,其中冒泡排序让他印象深刻。在冒泡排序中,每次只能交换相邻的两个元素。

小蓝发现,如果对一个字符串中的字符排序,只允许交换相邻的两个字符,则在所有可能的排序方案中,冒泡排序的总交换次数是最少的。例如,对于字符串 lan 排序,只需要 1次交换。对于字符串 qiao 排序V,总共需要 4 次交换。

小蓝的幸运数字是 V,他想找到一个只包含小写英文字母的字符串,对这个串中的字符进行冒泡排序,正好需要 V 次交换。请帮助小蓝找一个这样的字符串。

如果可能找到多个,请告诉小蓝最短的那个。如果最短的仍然有多个,请告诉小蓝字典序最小的那个。请注意字符串中可以包含相同的字符。

输入格式 输入一行包含一个整数"V" ,为小蓝的幸运数字。 输出格式 输出一个字符串,为所求的答案。

样例输入 4 样例输出 bbaa 样例输入 100 样例输出 jihgfeeddccbbaa

评测用例规模与约定 对于 30% 的评测用例,1<=V<=20。 对于 50% 的评测用例,1<=V<=100。 对于所有评测用例,1<=V<=10000。

解答

原本想的是先求出字符串的长度,然后以zzzyyyxxx.....aaa的顺序排,变动的是每个字母的个数。然后发现会有类似于这样的期望数据:

eyzzzzyyyyxxxxxwwwwwvvvvvuuuuutttttsssssrrrrrqqqqqpppppooooonnnnnmmmmmlllllkkkkkjjjjjiiiiihhhhhgggggfffffeeeeeddddddccccccbbbbbbaaaaaa

给我整不会了...9敏...

哪天想通了在更新吧

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值