【第十一届 蓝桥杯省赛B组】试题解析

一、门牌制作。

1. 难度系数:⭐
2. 知识点: 枚举
3. 要点分析:无。
import sys
import os

count = 0
nums = []
for i in range(1,2020+1):
    for t in str(i):
        if t == '2':
            count += 1
print(count)

二、寻找2020。

1. 难度系数:⭐⭐⭐
2. 知识点: 模拟
3. 要点分析

①分成三种情况来进行讨论,特别是对于斜线上元素的分析。

②我的方法主要在于列举出所有的情况,代码部分存在冗余,仅供参考。

import math

matrixs = """ """  #字符串太长,此处忽略
matrixs = matrixs.split('\n')

# 计算个数
def test(matrixs):
    count = 0
    for matrix in matrixs:
      for i in range(len(matrix)):
          if matrix[i:i+4] == '2020':
              count += 1
    return count

# 打横
summ = 0
summ += test(matrixs)

# 打竖
matrixs_new = []
for j in range(len(matrixs[1])):
    x = []
    for i in range(len(matrixs)):
        x.append(matrixs[i][j])
    matrixs_new.append(''.join(x))
summ += test(matrixs_new)

# 打斜
# 1.上三角
x=0;y=0
matrixs_new_new = []
for _ in range(len(matrixs)+len(matrixs[0])-1):
    tmp = []
    i=x;j=y
    while i<len(matrixs) and j<len(matrixs[0]):
        tmp.append(matrixs[i][j])
        i+=1; j+=1
    matrixs_new_new.append(''.join(tmp))
    y += 1
summ += test(matrixs_new_new)
# 2.下三角  
x=1;y=0
matrixs_new_new = []
for _ in range(len(matrixs)+len(matrixs[0])-1):
    tmp = []
    i=x;j=y
    while i<len(matrixs) and j<len(matrixs[0]):
        tmp.append(matrixs[i][j])
        i+=1; j+=1
    matrixs_new_new.append(''.join(tmp))
    x += 1
summ += test(matrixs_new_new)

print(summ)

下面的代码进行了子问题的划分;在一次双层循环中,即完成了对每个位置元素的三种情况的探索,值得学习:

import os
import sys

N = 300
maps = [list(str(input())) for _ in range(N)]   #自行输入字符串
length = 0
for i in range(N):
  for j in range(N):
    if maps[i][j] == '2':
      # 判断同行连续函数
      if j <= N - 4 and maps[i][j+1] == '0' and maps[i][j+2] == '2' and maps[i][j+3] == '0':
        length += 1
      
      # 判断同列连续函数
      if i <= N - 4 and maps[i+1][j] == '0' and maps[i+2][j] == '2' and maps[i+3][j] == '0':
        length += 1

      # 判断斜对角的连续函数
      if i <= N-4 and j <= N-4 and maps[i+1][j+1]=='0' and maps[i+2][j+2] == '2' and maps[i+3][j+3]=='0':
        length += 1
print(length)

 三、跑步锻炼。

1.难度系数:⭐⭐⭐
2. 知识点:模拟 枚举
3. 要点分析

①每天都需要跑1km,因此计算出总天数。

②月初或周一额外跑多1km,难点在于计算“重复部分”。

再将两者直接相加即可。

import sys
import os


days = [31,28,31,30,31,30,31,31,30,31,30,31]
days_r = [31,29,31,30,31,30,31,31,30,31,30,31]  #闰年
month_initial = []
# 天数,即基本跑步数 1km
summ = 0
k = 0
for i in range(2000,2020+1):
  if i%4==0:
      summ += 366
      for t in days_r:
         k += t
         month_initial.append(k+1)  #月初的日子
  else:
      summ += 365
      for t in days:
         k += t
         month_initial.append(k+1)  #月初的日子
summ -= (30+31+30)

# 判断为周一的日子
mondays = []
for i in range(3,7580+1,7):
  mondays.append(i)

# 基本跑步数+额外数
print(summ+len(set(mondays+month_initial[:-2])))  #去重(月初and周一)

 还可以直接调用python的内置库“datatime“进行计算,

import datetime

start = datetime.date(2000, 1, 1)
end = datetime.date(2020, 10, 1)
days = datetime.timedelta(days=1) #时间间隔
ans = 0

while end >= start:
    if start.day == 1 or start.weekday() == 0:
        ans += 2
    else:
        ans += 1
    start += days
print(ans)

datatime 的常用函数:

(1)datatime.data(year,month,day)        #转换成datatime格式 

(2)datatime.timedelta(days=1)        #表示时间间隔

(3)start.day        #表示月份中的哪一天,范围从1到31(取决于具体的月份)

(4)start,weekday()        #表示星期,0代表星期一,1代表星期二,依此类推   

四、蛇形填数。

1.难度系数:⭐⭐⭐
2. 知识点:模拟 规律 思维
3. 要点分析:无。
import sys
import os

matirxs = [[0]*100 for _ in range(100)]
matirxs[0][0] = 1
t = 1
for k in range(50):
    if k%2==0:
      i = 0; j = k+1;
      while i<=k+1 and j>=0:
        t += 1
        matirxs[i][j] = t
        i += 1
        j -= 1
    else:
      j = 0; i = k+1;
      while i<=k+1 and i>=0:
        t += 1
        matirxs[i][j] = t
        i -= 1
        j += 1
print(matirxs[20-1][20-1])

 五、排序。

1.难度系数:⭐
2. 知识点:排序
3. 要点分析:无。

#include <stdio.h>
#include <stdlib.h>
void sel_sort(int* x, int n)
{
    int k, i, m, t;
    for(k=0; k<n-1; k++)  // 多趟排序
    {
        m = _____________;  // 填空1
        for(i=k+1; i<n; i++)
        {
            if(x[i] < x[m]) _________________;  // 填空2
        }

        t = x[k];
        x[k] = x[m];
        x[m] = t;
    }
}

void display(int* x, int n)
{
    for(int i=0; i<n; i++)  printf("%d ", x[i]);
    printf("\n");
}

int main()
{
    int N = 10;
    int a[] = {5, 12, 35, 28, 19, 22, 36, 17, 4, 11};
    display(a, N);
    sel_sort(a, N);
    display(a, N);
}

六、成绩统计。

1. 难度系数:⭐
2. 知识点: 模拟
3. 要点分析

需要额外注意一下整数的取法,

①向上取整:math.ceil(x)

②向下取整:math.floor(x)

③四舍五入取整:round(x)
④四舍五入保留两位小数:round(x,2) 

import sys
import os
import math

n = int(input())

passes = []
excellent = []
count = 0
for i in range(n):
    score = int(input())
    count += 1
    if score >= 60:
        passes.append(score)
    if score >= 85:
        excellent.append(score)
print("{}%".format(round(len(passes)/count*100)))
print("{}%".format(round(len(excellent)/count*100)))

七、单词分析。

1. 难度系数:⭐⭐
2. 知识点:规律 思维 二分
3. 要点分析

①字母与数字的转换(ASCAII)。

②利用数组的下标,来记录每个字母的出现次数。 

import sys
import os
import math

s = input()

alpha_count = [0]*26
for t in s:
    alpha_count[ord(t)-97] += 1

pos = alpha_count.index(max(alpha_count))
print(chr(pos+97))
print(max(alpha_count))

八、数字三角形。

1. 难度系数:⭐⭐⭐⭐
2. 知识点:DFS 动态规划
3. 要点分析

(1)状态表示。

eq?dp%5Bi%5D%5Bj%5D 表示上一个位置来到当前位置的最佳方案。

(2)转移关系(退位、不进不退、退位)。

eq?dp%5Bi%5D%5Bj%5D%20%3D%20max%28number%5Bi%5D%5Bj%5D&plus;dp%5Bi-1%5D%5Bj-1%5D%2C%20number%5Bi%5D%5Bj%5D&plus;dp%5Bi-1%5D%5Bj%5D%29

前者表示上一个位置是向右下走,后者表示上一个位置是向左下走。

(3)初始状态。

eq?dp%5B0%5D%20%3D%20number%5B0%5D  等于三角形第一行的数据。

①为了便于计算,构建了一个n*(n+1)维的数组,没有值的位置都填0.

②利用了“回溯”,来依次确定当前最大值是否满足“向左下走和向右下走的次数不超过1”,若满足则直接输出答案;若不满足则使该最大值为0,检验下一个最大值。

import sys

def dfs(x, y):
    global left, right
    if x==0:
        return
    
    if dp[x][y] - number[x][y] == dp[x-1][y]:
        right += 1
        dfs(x-1, y)
    else:
        left += 1
        dfs(x-1, y-1)

n = int(input())
number = [[0]*(n+1) for _ in range(n)]
for i in range(n):
    number[i][1:i+1] = [int(t) for t in input().split()]

dp = [[0]*(n+1) for _ in range(n)]
dp[0] = number[0]
for i in range(1, n):
    for j in range(1, n+1):
        dp[i][j] = max(number[i][j]+dp[i-1][j-1], number[i][j]+dp[i-1][j])

for _ in range(n):
    left = 0
    right = 0   
    pos = dp[-1].index(max(dp[-1]))
    dfs(n-1, pos)
    if abs(left-right) <= 1:
        print(dp[n-1][pos])
        break
    else:
        dp[-1][pos] = 0

九、平面切分。

1. 难度系数:⭐⭐⭐
2. 知识点:规律 思维 计算几何
3. 要点分析

①考虑边界情况,即n=1.

②发现规律,平面新增加的切割面等于新增交点加一,也就是等于n+1.

③寻找交点,并利用set()存储交点,以便去重。

n = eval(input())
line = [tuple(map(int,input().split())) for i in range(n)]
se = set(line)
line = list(se)  #去重后的线
if line:
    ans=2
    for i in range(1,len(line)):
        a1,b1=line[i]
        pos=set()
        for j in range(i):
            a2,b2=line[j]
            if a1==a2:
                continue
            x=(b1-b2)/(a1-a2)     #斜率
            y=a1*x+b1
            pos.add((x,y))
        ans += len(pos)+1
print(ans)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值