代码编织梦想

好久没写了,发现自己啥也不会(悲

今天练习了蓝桥杯2021初赛的题目,只会写简单题目。不过收获也不少。

题目链接:问题 - New Online Judge (ecustacm.cn)

题目1:卡片

简简单单的暴力,代码如下:

n = 2021
arr = [n]*10
i = 1
while True:
    tem = i
    while tem>=10:
        pivot = tem%10
        if arr[pivot] != 0:
            arr[pivot] -= 1
        else:
            break
        tem = tem//10
    pivot = tem%10
    if arr[pivot] != 0:
        arr[pivot] -= 1
    else:
        break
    i+=1
print(i)
            
        
        

结果为:

3182

题目2:直线

初中知识啦,算个斜率k和截距b,用元组存到数组里面,一样的就不存,对于斜率为无穷和0的单独计算就完事了,代码如下:

res = []
width = 20
height = 21
for x1 in range(width):
    for y1 in range(height):
        for x2 in range(width):
            for y2 in range(height):
                if x1==x2 or y1 == y2:
                    continue
                else:
                    k = (y1-y2)/(x1-x2)
                    b = (x1*y2-y1*x2)/(x1-x2)
                    if (k,b) not in res:
                        res.append((k,b))
print(width+height+len(res))

计算量也不大,反正主打的就是一个暴力,结果为:

40257

还是学习到了东西的,比如元组存在数组中,用in判断是否存在,还是很好用的。 

 题目3:货物摆放

一开始做的时候脑子有点抽风,没get到点。其实把全部因子求出来,然后三重循环就好了,想通了就很简单。代码如下:

n = 2021041820210418
sq_n = int(n**0.5+1)
arr = []
num = 0
for i in range(1,sq_n):
    if n%i == 0:
        if i not in arr:
            arr.append(i)
        if n//i not in arr:
            arr.append(n//i)
print(arr)
ln = len(arr)
for n1 in arr:
    for n2 in arr:
        for n3 in arr:
            if n1*n2*n3==n:
                num +=1
print(num)
    

由于因子不多,三重循环快的,结果如下:

2430

题目4: 路径

这道题目真不会写,主要是python的Dij算法还没写过,之前只是写过Java版本的,过几天学了再写,先放出一部分代码(给出路径矩阵)

def f(x,y):
    if x==y:#当到自身是路径为0
        return 0
    x,y = max(x,y),min(x,y)
    add = x
    while True:
        if x%y==0:
            return x
        else:
            x += add

arr = []
for i in range(1,2022):
    tem = []
    if i<=21:
        for j in range(1,i+22):
            tem.append(f(j,i))
    elif i>=2000:
        for j in range(i-21,2022):
            tem.append(f(j,i))
    else:
        for j in range(i-21,i+22):
            tem.append(f(j,i))
    arr.append(tem)
print("over!")

跑出矩阵的速度还是很快的,主要是我Dij算法不会写,过几天一定学呜呜呜

题目5~6:不会,放一下

题目7:左孩子右兄弟

最开始的想法比较简单,就是从叶节点开始一层一层遍历回去,就是从数组最后一个遍历回根节点,因为左边是孩子节点,右边是兄弟节点,当遍历的时候只需要比较两边那边最大,然后存下来。只能说很幼稚,很暴力的想法,只是有深度搜索的雏形。果不其然,只跑出来了10%。

代码如下:

n = int(input())
tree = [0]
for i in range(n-1):
    tree.append(int(input())-1)
tree.sort()
deep = [0]*n
has_child = [0]*n
#print(tree)
for i in range(n-1,0,-1):
    deep[tree[i]] = max(deep[tree[i]],1+deep[i]+has_child[tree[i]])
    has_child[tree[i]] += 1
    #print(deep)
    #print(has_child)
print(deep[0])

上述代码的缺陷如下:

1.有深搜的影子但是还是贪心算法,而且只是按照输入的顺序暴力搜索

2.在从前往后遍历的时候,要求输入必须是按照顺序输入的,就是子节点要连在一起。

在网上找到了一篇博客学习: (77条消息) 第十二届蓝桥杯python_niuniuyi~的博客-CSDN博客

n = int(input())
tree = [[] for i in range(n+1)]

for i in range(2,n+1):
    father = int(input())
    tree[father].append(i)

def dfs(t):
    deep = 0
    for i in range( len(tree[t]) ):
        deep = max(deep,dfs(tree[t][i])+len(tree[t]))
    return deep

print(dfs(1))

有时候真佩服这么想出来这么简洁的代码却能跑出这么好的效果。

题目8:括号序列

哦,完全不会,不过上课讲过一种利用栈判断括号是否完备的小小算法。练手一下。

代码如下:

s = input()
arr = [ 1 if s[i]=='(' else 0 for i in range(len(s))]
def isR(arr):
    vertify = []
    for tem in arr:
        if tem == 1:
            vertify.append(tem)
        else:
            if len(vertify)==0:
                return False
            vertify.pop()
    return len(vertify)==0

if isR(arr):
    print(0)
else:
    pass

题目9:时间显示

简简单单的,甚至不需要判断年份,非常体贴。

import time
T = int(input())
arr = []
for i in range(T):
    arr.append(int(input()))
ans = []
for i in range(T):
    tem = arr[i]
    tem //= 1000
    hour = str((tem//3600)%24)
    min = str((tem//60)%60)
    sec = str(tem%60)
    if len(hour)==1:
        hour = "0"+hour
    if len(min)==1:
        min = "0"+min
    if len(sec)==1:
        sec = "0"+sec
    s = str(hour+":"+min+":"+sec)
    ans.append(s)

for i in ans:
    print(i)

这种题目就算繁琐一点也是简单的,不解释了。

题目10:杨辉三角形

没什么思路,主要就是求一下中间最大值,然后判断区间,接着暴力,只通过了10%,标准答案是利用二分法,我简单看了一下,很巧妙,回头学习,放出我写的代码:

def C(n,m):
    if n==0:
        return 1
    if n==1:
        return m
    x = 1
    y = 1
    for i in range(1,n+1):
        x *= i
    for i in range(m,m-n,-1):
        y *= i
    return y//x

def find(tem,arr):
    for i in range(len(arr)):
        if tem <= arr[i]:
            return i
    return -1

res = [1, 1, 2, 3, 6, 10, 20, 35, 70, 126, 252, 462, 924, 1716, 3432, 6435, 12870, 24310, 48620, 92378, 184756, 352716, 705432, 1352078, 2704156, 5200300, 10400600, 20058300, 40116600, 77558760, 155117520, 300540195, 601080390, 1166803110]
T = int(input())
arr = []
for i in range(T):
    arr.append(int(input()))
ans = []
for i in range(T):
    tem = arr[i]
    if tem==1:
        ans.append(1)
        continue
    pivot = find(tem,res)
    #print(pivot,"p")
    n,m = 0,0
    flag = False
    for i in range(pivot,tem+1):
        if flag:
            break
        for j in range(i//2,0,-1):
            cn = C(j,i)
            if tem > cn:
                i += 1
                break
            if tem == cn:
                n = j
                m = i
                flag = True
                break
    count = (m+1)*m//2+n+1
    ans.append(count)
    
for i in range(T):
    print(ans[i])

写得真的很烂,也没注释。

总结:

第二次开始写算法题目,一些简单的暴力题目还是可以的,也学习到了一些python小技巧,设计难一点的算法就不会了,还得多多学习,未来会更新Dij算法,括号序列和杨辉三角的二分法。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_64112516/article/details/129482403

蓝桥杯2021——路径-爱代码爱编程

 可以先求出所有路径 然后dp求出最短路径 #include<bits/stdc++.h> using namespace std; int gcd(int a,int b) { return a%b==0?b:gcd(b,a%b); } int lcm(int a,int b) { return a*b/gcd(a,b); } i

[蓝桥杯2021初赛] 砝码称重-爱代码爱编程

题目 题目描述 你有一架天平和N 个砝码,这N 个砝码重量依次是W1, W2, … , WN。 请你计算一共可以称出多少种不同的重量? 注意砝码可以放在天平两边。 输入格式 输入的第一行包含一个整数N。 第二行包含N 个整数:W1, W2, W3, … , WN。 对于50% 的评测用例,1 ≤ N ≤ 15。 对于所有评测用例,1 ≤ N ≤ 100,

【蓝桥杯2021初赛】卡片——C++-爱代码爱编程

一、题目描述 小蓝有很多数字卡片,每张卡片上都是数字0 到9。 小蓝准备用这些卡片来拼一些数,他想从1 开始拼出正整数,每拼一个,就保存起来,卡片就不能用来拼其它数了。 小蓝想知道自己能从1 拼到多少。 例如,当小蓝有30 张卡片,其中0 到9 各3 张,则小蓝可以拼出1 到10,但是拼11 时卡片1 已经只有一张了,不够拼出11。 现在小蓝手里有

NOJ 1552: [蓝桥杯2021初赛] 货物摆放【枚举】-爱代码爱编程

NOJ 1552: [蓝桥杯2021初赛] 货物摆放 一、题目链接二、题目分析(一)算法标签(二)解题思路三、AC代码四、其它题解 一、题目链接 NOJ 1552: [蓝桥杯2021初赛] 货物摆放 二、题目分析 (一)算法标签 枚举 约数 (二)解题思路 重点:两重循环!每一层枚举到根号! 三、AC代码 解法一:(1872ms

NOJ 1553: [蓝桥杯2021初赛] 路径【最大公约数】【最小公倍数】【最短路】-爱代码爱编程

NOJ 1553: [蓝桥杯2021初赛] 路径 一、题目链接二、题目分析(一)算法标签(二)解题思路三、AC代码四、其它题解 一、题目链接 NOJ 1553: [蓝桥杯2021初赛] 路径 二、题目分析 (一)算法标签 最大公约数 最小公倍数 最短路 (二)解题思路 三、AC代码 解法一: #include <iostr

[蓝桥杯2021初赛] 路径(动态规划16行代码足以吊打)-爱代码爱编程

小蓝学习了最短路径之后特别高兴,他定义了一个特别的图,希望找到图中的最短路径。 小蓝的图由2021 个结点组成,依次编号1 至2021。 对于两个不同的结点a, b,如果a 和b 的差的绝对值大于21,则两个结点之间没有边相连; 如果a 和b 的差的绝对值小于等于21,则两个点之间有一条长度为a 和b 的最小公倍数的无向边相连。 例如:结点1 和结点23

[蓝桥杯2021初赛] 路径 Java-爱代码爱编程

题目描述 小蓝学习了最短路径之后特别高兴,他定义了一个特别的图,希望找到图中的最短路径。 小蓝的图由2021 个结点组成,依次编号1 至2021。 对于两个不同的结点a, b,如果a 和b 的差的绝对值大于21,则两个结点之间没有边相连; 如果a 和b 的差的绝对值小于等于21,则两个点之间有一条长度为a 和b 的最小公倍数的无向边相连。 例如:结点1

1558: [蓝桥杯2021初赛] 砝码称重-爱代码爱编程

题目描述(背包问题) (此题目的关键问题在于:如果此时的天秤上的重量可以称出,那么1. 此时天秤上的重量与当时循环的砝码重量之差的绝对值或者和也一定可以称出。以此来进行动态规划: 即 if(ff[i]) {         ff[abs(i - w[i])] = 1;         ff[i + w[i]] = 1;(此时需要判断 天秤上的重量

1551: [蓝桥杯2021初赛] 直线 Java-爱代码爱编程

在平面直角坐标系中,两点可以确定一条直线。 如果有多点在一条直线上,那么这些点中任意两点确定的直线是同一条。 给定平面上2 × 3 个整点{(x, y)|0 ≤ x < 2, 0 ≤ y < 3, x ∈ Z, y ∈ Z}, 即横坐标是0 到1 (包含0 和1) 之间的整数、纵坐标是0 到2 (包含0 和2) 之间的整数的点。 这些点一共确定

NOJ 1551: [蓝桥杯2021初赛] 直线【精度问题】-爱代码爱编程

NOJ 1551: [蓝桥杯2021初赛] 直线 一、题目链接二、题目分析(一)算法标签(二)解题思路三、AC代码四、其它题解 一、题目链接 NOJ 1551: [蓝桥杯2021初赛] 直线 二、题目分析 (一)算法标签 枚举 精度问题 (二)解题思路 三、AC代码 解法一: #include <iostream>

1558: [蓝桥杯2021初赛] 砝码称重 C/C++-爱代码爱编程

砝码称重 题目描述 你有一架天平和N 个砝码,这N 个砝码重量依次是W1, W2, ... , WN。 请你计算一共可以称出多少种不同的重量? 注意砝码可以放在天平两边。 输入格式 输入的第一行包含一个整数N。 第二行包含N 个整数:W1, W2, W3, ... , WN。 对于50% 的评测用例,1 ≤ N ≤ 15。 对于所有评测用例,1 ≤

[蓝桥杯2021初赛] 卡片C语言B组-爱代码爱编程

#include<stdio.h> main() { int x[11]={0},i,j,t; for(i=1;;i++) { j=i; while(j) { t=j%10;//获得各位置的数 x[t]++;//桶排 j/=10; if(x[t]==2022)//相较于到2021就比较更好 {

[蓝桥杯2021初赛] 货物摆放C语言B组-爱代码爱编程

小蓝有一个超大的仓库,可以摆放很多货物。 现在,小蓝有n 箱货物要摆放在仓库,每箱货物都是规则的正方体。 小蓝规定了长、宽、高三个互相垂直的方向,每箱货物的边都必须严格平行于长、宽、高。 小蓝希望所有的货物最终摆成一个大的立方体。即在长、宽、高的方向上分别堆L、W、H 的货物,满足n = L × W × H。 给定n,请问有多少种堆放货物的方案满足要求。

1551: [蓝桥杯2021初赛] 直线-爱代码爱编程

去年做对了但实在想不起当时在考场用的什么方法。。 这个方法是用HashSet去重,用分数表示防止算k,b时精度爆炸,而分数需要化简,用辗转相除法来求然后加入set集合即可 import java.util.HashSet; public class Main { public static void main(String[] args)

蓝桥杯2021 直线-爱代码爱编程

这道题 求y=k*x+b ,统计斜率,对于竖直的直线和横着的直线,单拉出来。 统计两个点的斜率,最后去重,可以用STL的set容器,表示没有重复数的集合 #include<bits/stdc++.h> //集合去重的作用; set using namespace std; typedef pair<double,double>

蓝桥杯 2021 卡片-爱代码爱编程

#include <iostream> using namespace std; int check(int n) { int k = 0; while(n) { int a = n%10; if(a == 1) k++; n = n/10; } return k; } int main() {

【[蓝桥杯2021初赛] 货物摆放】_让我冬个眠先的博客-爱代码爱编程

[蓝桥杯2021初赛] 货物摆放 一、题目描述二、解题思路三、具体实现 一、题目描述 二、解题思路    1. 设长、宽和高分别为L、W和H,不妨令L<=W<=H;    2. 根据对称性,当三者各不相同时,有6种解法;当三者都相同时有1种解法,剩下的只有两者相同时有3种解法;    3. 先求出n所有的因子,若一个数n有因

【蓝桥杯历年真题合集】蓝桥杯2021初赛_蓝桥杯eda历年真题-爱代码爱编程

✅🎡个人主页:程序猿追 ✅🎡系列专栏:算法合集 ✅🎡目前状态:创建Java学习之路(零基础到就业实战)系列,目前更新到JAVAWEB开发 ✅🎡作者简介:大家好,我是程序猿追,全栈领域新星创作者,算法爱好者,常在作者周榜排名前30,某不知名的 ACMer ✅🎡推荐一款刷题面试找工作三不误的网站——牛客网 ✅🎡个人名言:不积跬步无以至