【思特奇杯·云上蓝桥-算法集训营】第1周

1.跑步训练

问题描述

小明要做一个跑步训练,初始时,小明充满体力,体力值计为 10000。

如果小明跑步,每分钟损耗 600 的体力。

如果小明休息,每分钟增加 300 的体力。

体力的损耗和增加都是 均匀变化的。

小明打算跑一分钟、休息一分钟、再跑一分钟、再休息一分钟……如此循环。

如果某个时刻小明的体力到达 0,他就停止锻炼, 请问小明在多久后停止锻炼。

为了使答案为整数,请以秒为单位输出答案,答案中只填写数,不填写单位。

答案提交

代码 

x=10000
t=0
while True:
    x-=600     
    t+=60
    x+=300
    t+=60
    if x<600:
        break
while x!=0:
    x-=10
    t+=1
print(t)

结果:3880

2.阶乘约数

问题描述
定义阶乘 n! = 1 × 2 × 3 × ··· × n。

请问 100! (100 的阶乘)有多少个约数。

答案提交

代码

m = [i for i in range(1, 101)]
x = [2]
for i in range(3, 100):
    j = 2
    while i > j:
        if i % j == 0:
            break
        j += 1
    else:
        x.append(i)
print(x)
a = {}
for i in x:
    a[i] = 0
print(a)
for i in range(2, 101):
    for j in x:
        while i % j == 0:
            i = i / j
            a[j] += 1
sum = 1
for i in a.values():
    sum *= (i+1)
print(a)
print(sum)


结果:39001250856960000

3.出栈次序

问题描述

X星球特别讲究秩序,所有道路都是单行线。

一个甲壳虫车队,共16辆车,按照编号先后发车,夹在其它车流中,缓缓前行。

路边有个死胡同,只能容一辆车通过,是临时的检查站,如图所示。

X星球太死板,要求每辆路过的车必须进入检查站,也可能不检查就放行,也可能仔细检查。

如果车辆进入检查站和离开的次序可以任意交错。

那么,该车队再次上路后,可能的次序有多少种?

为了方便起见,假设检查站可容纳任意数量的汽车。

显然,如果车队只有1辆车,可能次序1种;2辆车可能次序2种;3辆车可能次序5种。

现在足足有16辆车啊,亲!需要你计算出可能次序的数目。

答案提交

代码

def fib(i, j):
    if i == 0: 
        return 1
    if j == 0:  
        return fib(i-1, 1)
    if j > 0: 
        return fib(i-1, j+1)+fib(i, j-1)
    return 0

print(fib(16,0))

结果:35357670

4.哥德巴赫分解

问题描述:

哥德巴赫猜想认为:不小于4的偶数都可以表示为两个素数的和。

你不需要去证明这个定理,但可以通过计算机对有限数量的偶数进行分解,验证是否可行。

实际上,一般一个偶数会有多种不同的分解方案,我们关心包含较小素数的那个方案。

对于给定数值范围,我们想知道这些包含较小素数方案中最大的素数是多少。

比如,100以内,这个数是19,它由98的分解贡献。

你需要求的是10000以内,这个数是多少?

注意,需要提交的是一个整数,不要填写任何多余的内容(比如,说明性的文字)

答案提交

代码

import itertools
num=[]
t=4
for x in range(2,10001):
    k=1
    for y in range(2,x):
        if x/y==int(x/y):
            k=0
    if k==1:
        num.append(x)
n=list(itertools.combinations(num,2))
res=[]
for x in range(4,10000,2):
    for y in n:
        if x==int(sum(y)):
            res.append(min(y))
            break
print(max(res))   

结果:173

5.图书排列

题目描述

将编号为1~10的10本书排放在书架上,要求编号相邻的书不能放在相邻的位置。

请计算一共有多少种不同的排列方案。

注意,需要提交的是一个整数,不要填写任何多余的内容。

答案提交

代码

import itertools
book = [1,2,3,4,5,6,7,8,9,10]
sum = 0
for i in itertools.permutations(book,10):
    if abs(i[0]-i[1])!=1 and abs(i[1]-i[2])!=1 and abs(i[2]-i[3])!=1 and abs(i[3]-i[4])!=1 and abs(i[4]-i[5])!=1 and abs(i[5]-i[6])!=1 and abs(i[6]-i[7])!=1 and abs(i[7]-i[8])!=1 and abs(i[8]-i[9])!=1:
        sum += 1
print(sum)

结果:479306

6.猴子分香蕉 

题目描述

5只猴子是好朋友,在海边的椰子树上睡着了。这期间,有商船把一大堆香蕉忘记在沙滩上离去。
第1只猴子醒来,把香蕉均分成5堆,还剩下1个,就吃掉并把自己的一份藏起来继续睡觉。
第2只猴子醒来,重新把香蕉均分成5堆,还剩下2个,就吃掉并把自己的一份藏起来继续睡觉。
第3只猴子醒来,重新把香蕉均分成5堆,还剩下3个,就吃掉并把自己的一份藏起来继续睡觉。
第4只猴子醒来,重新把香蕉均分成5堆,还剩下4个,就吃掉并把自己的一份藏起来继续睡觉。
第5只猴子醒来,重新把香蕉均分成5堆,哈哈,正好不剩!

请计算一开始最少有多少个香蕉。

需要提交的是一个整数,不要填写任何多余的内容。

答案提交

代码

n = 6
while True:
    if n % 5 == 1:
        a = (n - 1) / 5 * 4
        if int(a) % 5 == 2:
            b = (a-2) / 5 * 4
            if int(b) % 5 == 3:
                c = (b-3) / 5 * 4
                if int(c) % 5 == 4:
                    d = (c-4) / 5 * 4
                    if int(d) % 5 == 0 and d != 0:
                        break
    n += 1
print(n)

结果:3141

7.稍小分数

回到小学----
真分数:分子小于分母的分数
既约分数:分子分母互质,也就是说最大公约数是1

x星球数学城的入口验证方式是:
屏幕上显示一个真分数,需要你快速地找到一个比它小的既约分数,要求这个分数越大越好。
同时限定你的这个分数的分母不能超过100。

答案提交

代码

from fractions import Fraction
def check(x):
    if x == 2:
        return True
    for i in range(2, x):
        if x%i==0:
            return False
    return True

if __name__ == '__main__':
    m = []
    All = []
    for i in range(2, 100):
        if check(i):
            m.append(i)
    print(m)
    for i, j in enumerate(m):
        for k in m[:i]:
            a = Fraction(k, j)
            if a not in All:
                All.append(a)
    All = sorted(All)
    print(All)
    a = int(input('输入分子:'))
    b = int(input("输入分母:"))
    num = Fraction(a, b)
    out = False
    for i in range(len(All)):
        if All[i] >= num:
            print(All[i-1])
            out = True
            break
    if not out:
        print(All[-1])

8.excel地址

时间限制:1.0s   内存限制:256.0MB

问题描述

Excel单元格的地址表示很有趣,它使用字母来表示列号。

  比如,

A表示第1列,

B表示第2列,

Z表示第26列,

AA表示第27列,

AB表示第28列,

BA表示第53列,

....

  当然Excel的最大列号是有限度的,所以转换起来不难。

  如果我们想把这种表示法一般化,可以把很大的数字转换为很长的字母序列呢?

  本题目即是要求对输入的数字, 输出其对应的Excel地址表示方式。

样例输入

26

样例输出

Z

样例输入

2054

样例输出

BZZ

数据规模和约定

我们约定,输入的整数范围[1,2147483647]

峰值内存消耗(含虚拟机) < 256M

CPU消耗 < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

注意:

main函数需要返回0;

只使用ANSI C/ANSI C++ 标准;

不要调用依赖于编译环境或操作系统的特殊函数。

所有依赖的函数必须明确地在源文件中 #include <xxx>

不能通过工程设置而省略常用头文件。

提交程序时,注意选择所期望的语言类型和编译器类型。

答案提交

代码

x = [chr(i) for i in range(65,91)]
y = int(input())
res = []
while y != 0:
    if y % 26 == 0:
        res.append(26)
        y = y // 26 - 1
    else:
        res.append(y % 26)
        y = y//26
for i in range(len(res)):
    res[i] = x[res[i]-1]
    res.reverse()
print(''.join(res))

9.日期问题

小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在1960年1月1日至2059年12月31日。令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。

比如02/03/04,可能是2002年03月04日、2004年02月03日或2004年03月02日。

给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?

输入

一个日期,格式是"AA/BB/CC"。 (0 <= A, B, C <= 9)

输出

输出若干个不相同的日期,每个日期一行,格式是"yyyy-MM-dd"。多个日期按从早到晚排列。

样例输入

02/03/04

样例输出

2002-03-04

2004-02-03

2004-03-02

资源约定:

峰值内存消耗(含虚拟机) < 256M

CPU消耗 < 1000ms

答案提交

代码

while True:
    try:
        a = list(map(int, input().split("/")))
        res = []


        def isRN(year):
            if year % 4 == 0 and year % 100 != 0:
                return True
            elif year % 400 == 0:
                return True
            else:
                return False


        def f(x, y, z): 
            if x >= 0 and x <= 59:
                x += 2000
            elif x >= 60 and x <= 99:
                x += 1900
            if y <= 0 or y > 12:
                return False
            if z <= 0 or z > 31:
                return False

            if isRN(x) and y == 2 and z > 29:
                return False
            if isRN(x) == False and y == 2 and z > 28:
                return False
            if y == 4 and z > 30:
                return False
            if y == 6 and z > 30:
                return False
            if y == 9 and z > 30:
                return False
            if y == 11 and z > 30:
                return False
            else:
                if y < 10:
                    y = str(0) + str(y)
                if z < 10:
                    z = str(0) + str(z)
                res.append(str(x) + "-" + str(y) + '-' + str(z))
                return


        f(a[0], a[1], a[2])
        f(a[2], a[0], a[1])
        f(a[2], a[1], a[0])
        for i in sorted(list(set(res))):
            print(i)

    except:
        break

10.整数划分

对于一个正整数n的划分,就是把n变成一系列正整数之和的表达式。注意,分划与顺序无关,例如6=5+1.跟6=1+5是同一种分划,另外,这个整数本身也是一种分划。

例如:对于正整数n=5,可以划分为:

1+1+1+1+1

1+1+1+2

1+1+3

1+2+2

2+3

1+4

5

输入描述

输入一个正整数n

输出描述

输出n整数划分的总数k

输入样例

5

输出样例

7

答案提交

def f(n,a,k):
   if n <= 0:
         for i in range(k):
             print(a[i], end='')
         print()
         return
     for i in range(n, 0, -1):
         if k > 0 and i < a[k-1]:
             continue
         a[k] = i
         f(n-i, a, k+1)
 a = [0] * 10000
 f(6, a, 0)

11.一步之遥

从昏迷中醒来,小明发现自己被关在X星球的废矿车里。

矿车停在平直的废弃的轨道上。

他的面前是两个按钮,分别写着“F”和“B”。

小明突然记起来,这两个按钮可以控制矿车在轨道上前进和后退。

按F,会前进97米。按B会后退127米。

透过昏暗的灯光,小明看到自己前方1米远正好有个监控探头。

他必须设法使得矿车正好停在摄像头的下方,才有机会争取同伴的援助。

或许,通过多次操作F和B可以办到。

矿车上的动力已经不太足,黄色的警示灯在默默闪烁...

每次进行 F 或 B 操作都会消耗一定的能量。

小明飞快地计算,至少要多少次操作,才能把矿车准确地停在前方1米远的地方。

请填写为了达成目标,最少需要操作的次数。

注意,需要提交的是一个整数,不要填写任何无关内容(比如:解释说明等)

答案提交

代码

x = 1
a = [-1]
b = []
j = [1]*10000005
while x:
    b = a
    a = []
    for i in b:
        if j[i+97]:
            j[i+97]=0
            a.append(i+97)
        if j[i-127]:
            j[i-127]=0
            a.append(i-127)
        if i+97==0 or i-127==0:
            print(x)
            x=-1
            break
    x+=1



12.机器人塔

X星球的机器人表演拉拉队有两种服装,A和B。

他们这次表演的是搭机器人塔。

类似:

     A

    B B

   A B A

  A A B B

 B B B A B

A B A B B A

队内的组塔规则是:

  A 只能站在 AA 或 BB 的肩上。

  B 只能站在 AB 或 BA 的肩上。

你的任务是帮助拉拉队计算一下,在给定A与B的人数时,可以组成多少种花样的塔。

输入一行两个整数 M 和 N,空格分开(0<M,N<500),分别表示A、B的人数,保证人数合理性。

要求输出一个整数,表示可以产生的花样种数。

例如:

用户输入:

1 2

程序应该输出:

3

再例如:

用户输入:

3 3

程序应该输出:

4

资源约定:

峰值内存消耗 < 256M

CPU消耗  < 1000ms

答案提交

代码

import math

def check():
    a = 0
    b = 0
    tmp = row
    while tmp >0:
        for i in range(1, tmp+1):
            if cnt[i] == 1:
                a +=1
            else:
                b += 1
        for i in range(2, tmp+1):
            if cnt[i-1]==cnt[i]:
                cnt[i-1] = 1
            else:
                cnt[i-1] = 2
        tmp -=1
    if a == m and b == n:
        return True
    else:
        return False

def dfs(k):
    global res
    if k > row:
        if check():
            res +=1
        return
    cnt[k] = 1
    dfs(k+1)
    cnt[k] = 2
    dfs(k+1)

if __name__ == "__main__":
    m = int(input())
    n = int(input())
    res = 0
    cnt = [0 for _ in range(100010)]
    row = int(math.sqrt(2*(m+n)))
    dfs(1)
    print(res)

13.七星填空

如下图所示。在七角星的 14 个节点上填入 1 ~ 14的数字,不重复,不遗漏。 要求每条直线上的四个数字之和必须相等。

图片描述

图中已经给出了 3 个数字。 请计算其它位置要填充的数字,答案唯一。

填好后,请输出绿色节点的 4 个数字(从左到右,用空格分开)。

答案提交

代码

import itertools

x = [i for i in range(1, 15)]

x.remove(6)
x.remove(11)
x.remove(14)

def check(a):
    num1 = a[0] + a[1] + a[2] + a[3]
    num2 = 6 + a[1] + a[4] + 14
    if num1 != num2:
        return False
    num3 = 6 + a[2] + a[5] + 11
    if num2 != num3:
        return False
    num4 = a[3] + a[5] + a[7] + a[10]
    if (num3 != num4):
        return False
    num5 = a[8] + a[9] + a[7] + 11
    if (num4 != num5):
        return False
    num6 = a[6] + a[10] + a[8] + 14
    if (num5 != num6):
        return False
    num7 = a[0] + a[4] + a[6] + a[9]
    if (num6 != num7):
        return False
    return True

for i in itertools.permutations(x):
    if check(i):
        print(i)
        for j in range(4):
            print(i[j])
        break

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值