第十一届蓝桥杯大赛软件类省赛第二场C/C++大学B组的python实现

1. 门牌制作

  1. 思路:从1到2020,查看之间有多少个2即可
  2. 代码实现:
ls = []
for i in range(1, 2021):
    ls.append(str(i))
ans = 0
for i in ls:
    ans += i.count('2')
print(ans)
  1. 答案为:624

2. 既约分数

  1. 思路:暴力遍历即可
  2. 代码实现:
import math
ans = 0
for i in range(1, 2021):
    for j in range(1, 2021):
        if math.gcd(i, j) == 1:
            ans += 1
print(ans)
  1. 答案:2481215

3. 蛇形填数

  1. 思路:找规律,根据处在行列相同的数字【1, 5, 13, 25…】可以看出,中间每个数相差等差数列个4,直接按等差数列求和,找到第一个数到第20行20列的数字相差多少个4即可
  2. 代码实现:
count = 0
for i in range(1, 20):
    count += i
ans = 1 + count * 4
print(ans)
  1. 答案:761

4. 跑步锻炼

  1. 思路:找到2000.1.1到2020.10.1一共有多少天,其中有多少是周一或者月初,有多少既是周一又是月初即可。是由datetime模块即可
  2. 代码实现:
import datetime
start_time = datetime.date(2000, 1, 1)
end_time = datetime.date(2020, 10, 1)
# 得到两者之间相隔的天数    7579
DeltaTime = end_time - start_time
aday = datetime.timedelta(days = 1)
ans = 0
for i in range(7579):
    if start_time.day == 1 or start_time.isoweekday() == 1:
        ans += 2
    else:
        ans += 1
    start_time += aday
# 最后一天没有计算,所以手动加2即可
ans += 2
print(ans)
  1. 答案:8879

5. 七段码

  1. 思路;从图的角度入手,将紧邻的边看作图中的节点的连通,美剧可能出现的情况,判断连通性即可
  2. 代码实现:
import itertools

new_list = []
# 计数
num = 0
# 采用字典将该标号相接的所有标号列举出来
dict = {'a': ['f', 'b'], 'b': ['a', 'c', 'g'], 'c': ['b', 'd', 'g'],
        'd': ['e', 'c'], 'e': ['d', 'f', 'g'], 'f': ['a', 'e', 'g'],
        'g': ['b', 'c', 'e', 'f']}

string = "".join(list(dict.keys()))
for i in range(1, 8):
    # 对string字符串中的前i个字符进行无序组合
    for j in (itertools.combinations(list(string), i)):
        new_list.append("".join(j))
for str1 in new_list:
    if len(str1) == 1:
        num += 1
        continue

    for situation in itertools.permutations(str1):
        for c in range(1, len(situation)):
            if situation[c - 1] not in dict[situation[c]]:
                break

        else:
            num += 1
            break
print(num)
  1. 答案:80

6. 成绩查询

  1. 思路:计算及格人数以及优秀人数,再计算相关结果即可
  2. 代码实现;
def search_grade():
    n = int(input())
    total = n
    jige = 0
    great = 0
    for i in range(n):
        grade = int(input())
        if grade >= 85:
            jige += 1
            great += 1
        elif grade >= 60:
            jige += 1
        else:
            pass
    print(str(int(round(jige / n  * 100, 0))) + '%')
    print(str(int(round(great / n  * 100, 0))) + '%')
    return 0
search_grade()
  1. 结果在这里插入图片描述

7. 回文日期

  1. 思路:考察对字符串的操作。在这里,我们直接对年份进行操作,之后翻转得到回文的月和日,判断月和日是否符合日期规则即可。
  2. 代码实现:
from calendar import isleap

gap_year = [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
normal_year = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]


def judge(date, is_gap):
    month = int(date[:2])
    day = int(date[2:])
    if month > 12:
        return False
    if is_gap:
        return day < gap_year[month]
    else:
        return day < normal_year[month]


def judge_next_year(year: str):
    res_year = year[::-1]
    new_year = year + res_year
    revers_str = new_year[::-1]
    if new_year == revers_str:
        is_gap = isleap(int(year))
        flag = judge(res_year, is_gap)
        if flag:
            return [True, revers_str]
        else:
            return [False, revers_str]
    else:
        return [False, revers_str]


def get_next(data: str):
    year = data[:4]
    res = list()
    while True:
        year = str(int(year) + 1)
        ans = judge_next_year(year)
        flag, tmp = ans[0], ans[1]
        if flag:
            res.append(tmp)
            break
    num = int(data[0:2])
    while True:
        num += 1
        year = str(num) + str(num)
        ans = judge_next_year(year)
        flag, tmp = ans[0], ans[1]
        if flag:
            res.append(tmp)
            break
    return res


if __name__ == '__main__':
    data = input()
    res = get_next(data)
    for i in res:
        print(i)
  1. 结果:
    在这里插入图片描述

8.子串分值和

  1. 思路:动态规划,dp[i] = dp[i - 1] + change[i] (以s[i]结尾的字串的贡献为以前一个字符结尾的贡献 + s[i]的贡献)
  2. 代码实现:
def son_str_sum(s):
    n = len(s)
    index_ls = [0] * 26
    index_ls[ord(s[0]) - 97] += 1
    dp = [0] * n
    dp[0] = 1
    for i in range(1, n):
        dp[i] = dp[i - 1] +  i + 1 - index_ls[ord(s[i]) - 97]
        index_ls[ord(s[i]) - 97] = i + 1
    return sum(dp)
if __name__ == '__main__':
    s = input()
    ans = son_str_sum(s)
    print(ans)

  1. 答案:
    在这里插入图片描述

9. 平面切分

  1. 思路: 通过观察规律得到新加入的直线所分割成的平面数为1 + 加入直线之后平面中现存直线的交点
  2. 代码实现:
def get_node(line1, line2):
    A1 = line1[0]
    B1 = line1[1]
    A2 = line2[0]
    B2 = line2[1]
    # 如果平行
    if A1 - A2 == 0:
        return None
    x = (B2 - B1) / (A1 - A2)
    y = A1 * x + B1
    # 避免浮点数计算中出现精度问题
    x = round(x, 8)
    y = round(y, 8)
    return (x, y)


if __name__ == "__main__":
    n = int(input())
    lines = []
    for i in range(n):
        a, b = map(int, input().split())
        lines.append((a, b))
    lines = list(set(lines))
    n = len(lines)
    mid = [1] * (n + 1)
    node = set()
    for i in range(1, n):
        node.clear()
        for j in range(i):
            mux_node = get_node(lines[i], lines[j])
            if mux_node == None:
                pass
            else:
                node.add(mux_node)
        mid[i] +=  len(node)
    print(sum(mid))
  1. 结果:
    在这里插入图片描述

10.字串排序

  1. 思路:暂时没想到,等之后想到了再更新
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值