栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

第十三届蓝桥杯

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

第十三届蓝桥杯

我本来是python组,为了写一下题目,所以用python和go语言编写代码;

九进制转十进制

九进制正整数 (2022)9 转换成十进制等于多少?直接使用x进制转十进制的公式计算即可:

package main

import (
	"fmt"
)

func power(x int, n int) int {
	res := 1
	for i := 0; i < n; i++ {
		res *= x
	}
	return res
}

func main() {
	fmt.Println(2*power(9, 3) + 2*power(9, 1) + 2)
}
if __name__ == '__main__':
    print(2 * 9 ** 3 + 2 * 9 + 2)
顺子日期

小明特别喜欢顺子。顺子指的就是连续的三个数字: 123、 456 等。顺子日期指的就是在日期的 yyyymmdd 表示法中,存在任意连续的三位数是一个顺子的日期。例如 20220123 就是一个顺子日期,因为它出现了一个顺子: 123;而 20221023 则不是一个顺子日期,它一个顺子也没有。小明想知道在整个 2022年份中,一共有多少个顺子日期。这里是将012也看成是顺子日期,我们可以枚举2022年的每一天,判断当前日期的yyyymmdd表示中是否是顺子日期即可:

package main

import (
	"fmt"
)

// 判断当前的s是否是顺子日期
func check(s string) bool {
	n := len(s)
	for i := 0; i+2 < n; i++ {
		// 字符串中的每一个字符是uint8类型, 也即是一个数字
		if s[i+1] == s[i]+1 && s[i+2] == s[i+1]+1 {
			return true
		}
	}
	return false
}

func main() {
	months := []int{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
	year, month, day := 2022, 1, 1
	res := 0
	// 枚举2022年的每一天
	for i := 0; i < 365; i++ {
		// 格式化字符串
		s := fmt.Sprintf("%04d%02d%02d", year, month, day)
		if check(s) {
			res += 1
		}
		day += 1
		if day > months[month] {
			day = 1
			month += 1
		}
	}
	fmt.Println(res)
}
class Solution:
    def check(self, s: str):
        i = 0
        while i + 2 < len(s):
            if ord(s[i + 1]) == ord(s[i]) + 1 and ord(s[i + 1]) + 1 == ord(s[i + 2]):
                return True
            i += 1
        return False

    def process(self):
        months = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
        year, month, day = 2022, 1, 1
        res = 0
        for i in range(365):
            # 使用formt函数函数输出, 左补0
            s = "{:04d}{:02d}{:02d}".format(year, month, day)
            if self.check(s):
                res += 1
                # print(s)
            day += 1
            // 进入下一个月
            if day > months[month]:
                day = 1
                month += 1
        return res


if __name__ == '__main__':
    print(Solution().process())
刷题统计(模拟)

小明决定从下周一开始努力刷题准备蓝桥杯竞赛。他计划周一至周五每天做 a 道题目,周六和周日每天做 b 道题目。请你帮小明计算,按照计划他将在第几天实现做题数大于等于 n 题?

思路分析:我们以7天为一周,计算n道题目至少需要几周来刷,剩余的题目肯定不足一周然后计算剩余的题目需要几天来刷,两部分加起来的天数就是答案:

package main

import "fmt"

func main() {
	var (
		a int64
		b int64
		n int64
	)
	fmt.Scan(&a, &b, &n)
	res := int64(0)
	week := n / (5*a + 2*b)
	res += 7 * week
	last := n % (5*a + 2*b)
	i := 0
	for last > 0 {
		if i < 5 {
			last -= a
		} else {
			last -= b
		}
		res += 1
		i += 1
	}
	fmt.Println(res)
}
class Solution:
    def process(self):
        a, b, n = map(int, input().split())
        week = n // (5 * a + 2 * b)
        total = 7 * week
        last = n % (5 * a + 2 * b)
        i = 0
        # 剩余的题目不足一周模拟一下
        while last > 0:
            if i < 5:
                last -= a
            else:
                last -= b
            total += 1
            i += 1
        print(total)


if __name__ == '__main__':
    Solution().process()
修剪灌木(模拟 + 枚举)

爱丽丝要完成一项修剪灌木的工作。有 N 棵灌木整齐的从左到右排成一排。爱丽丝在每天傍晚会修剪一棵灌木,让灌木的高度变为 0 厘米。爱丽丝修剪灌木的顺序是从最左侧的灌木开始,每天向右修剪一棵灌木。当修剪了最右侧的灌木后,她会调转方向,下一天开始向左修剪灌木。直到修剪了最左的灌木后再次调转方向。然后如此循环往复。灌木每天从早上到傍晚会长高 1 厘米,而其余时间不会长高。在第一天的早晨,所有灌木的高度都是 0 厘米。爱丽丝想知道每棵灌木最高长到多高。

思路分析:分析题目可以知道相当于是已知一个数轴,数轴上的整数点表示的要修剪的灌木,对于第i颗灌木,高度取到最大的有两种可能,第一种是从左往右-->从右往左裁,第二种是从右往左--->从左往右,并且需要注意裁剪的时间:是先长再裁剪,对于第一种高度为2 * (n - i),第二种高度为2 * (i - 1),枚举所有的位置,对于每一个位置两种情况取一个max即可:

package main

import "fmt"

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func main() {
	var n int
	fmt.Scan(&n)
	for i := 1; i <= n; i++ {
		fmt.Println(max(2*(n-i), 2*(i-1)))
	}
}
if __name__ == '__main__':
    n = int(input())
    for i in range(1, n + 1):
        print(max(2 * (i - 1), 2 * (n - i)))
X 进制减法(贪心)

进制规定了数字在数位上逢几进一。X 进制是一种很神奇的进制,因为其每一数位的进制并不固定!例如说某种 X 进制数,最低数位为二进制,第二数位为十进制,第三数位为八进制,则X 进制数 321 转换为十进制数为 65。现在有两个 X 进制表示的整数 A 和 B,但是其具体每一数位的进制还不确定,只知道 A 和 B 是同一进制规则,且每一数位最高为 N 进制,最低为二进制。请你算出 A − B 的结果最小可能是多少。请注意,你需要保证 A 和 B 在 X 进制下都是合法的,即每一数位上的数字要小于其进制。

思路分析:这道题目的第一个难点是在于理解题目的意思上,对于一般的进制来说每一位的进制进位都是一样的,而对于x进制来说每一位的进制可能不一样,我们可以以题目中给出的例子理解65是怎么样计算出来的,其实也是类似于10进制的进位,10进制是逢十进一,而对于当前的x进制来说我们需要看每一位进1需要多少次,以x进制的321为例:最低位1需要1次,第二位那么需要2 * 2 = 4次,对于第三位那么需要3 * 10 * 2,那么总共需要1 + 4 + 60 = 65次才可以表示x进制,这样我们就知道了当前的x进制如何转换为10进制,题目中规定了A >= B,所以我们不妨设A,B最大位数为N位,如果不足N位那么最高位补0即可,我们可以使用表达式表达出A - B,而第二个难点在于A - B公式的工具表达提取出对应的pi,找到使得A - B最小每一个pi需要满足什么条件,最终化简之后可以发现每一个pi都是独立的要想使得A - B最小那么使得每一个pi最小即可,那么pi = max{a[i] + 1,b[i] + 1,2},因为进制肯定是比当前的数字至少大1的所以需要加上1,而且最小的进制为2进制,最终使用秦九韶算法计算出A - B的值即可:

package main

import "fmt"

func max1(a, b int) int {
	if a > b {
		return a
	}
	return b
}

// 求解三个int整数的最大值
func max2(a, b, c int) int {
	max := a
	if a < b {
		max = b
	}
	if max < c {
		max = c
	}
	return max
}

func main() {
	const N = 100010
	var (
		n, m1, m2 int
		// a, b存储每一位上的数字
		a, b [N]int
	)
	fmt.Scan(&n, &m1)
    // 逆序存储, 也即低位对齐
	for i := m1 - 1; i >= 0; i-- {
		fmt.Scan(&a[i])
	}
	fmt.Scan(&m2)
	for i := m2 - 1; i >= 0; i-- {
		fmt.Scan(&b[i])
	}
	res, mod := 0, 1000000007
	m := max1(m1, m2)
	for i := m - 1; i >= 0; i-- {
        // 秦九韶算法计算A - B, 每一个pi都是独立的所以要想使得A - B最小那么需要使得每一个pi最小
        // 那么每一个pi填的数字就是确定的
		res = (res*(max2(a[i]+1, b[i]+1, 2)) + a[i] - b[i]) % mod
	}
	fmt.Println(res)
}
if __name__ == '__main__':
    n = int(input())
    m1 = int(input())
    a = list(map(int, input().split()))
    # 这里是低位对齐这样会比较好操作, 所以需要翻转一下
    a = a[::-1]
    m2 = int(input())
    b = list(map(int, input().split()))
    b = b[::-1]
    m = max(m1, m2)
    # 高位补0
    for i in range(m1, m):
        a.append(0)
    for i in range(m2, m):
        b.append(0)
    res = 0
    mod = 10 ** 9 + 7
    for i in range(m - 1, -1, -1):
        res = (res * max(2, a[i] + 1, b[i] + 1) + a[i] - b[i]) % mod
    print(res)
统计子矩阵

给定一个 N × M 的矩阵 A,请你统计有多少个子矩阵 (最小 1 × 1,最大N × M) 满足子矩阵中所有数的和不超过给定的整数 K?

package main

import "fmt"

func main() {
	const N = 510
	var (
		n, m, k int
		// s存储每一列的前缀和
		s [N][N]int
	)
	fmt.Scan(&n, &m, &k)
	for i := 1; i <= n; i++ {
		for j := 1; j <= m; j++ {
			fmt.Scan(&s[i][j])
			s[i][j] += s[i-1][j]
		}
	}
	res := 0
	for i := 1; i <= n; i++ {
		for j := i; j <= n; j++ {
			tot := 0
			l, r := 1, 1
			for r <= m {
				tot += s[j][r] - s[i-1][r]
				for tot > k {
					tot -= s[j][l] - s[i-1][l]
					l += 1
				}
				res += r - l + 1
				r += 1
			}
		}
	}
	fmt.Println(res)
}

python:(超时):

class Solution:
    def process(self):
        n, m, k = map(int, input().split())
        # s存储每一列的前缀和
        s = [[0] * (m + 10) for i in range(n + 10)]
        a = list()
        for i in range(n):
            a.append(list(map(int, input().split())))
        for i in range(1, n + 1):
            for j in range(1, m + 1):
                s[i][j] += s[i - 1][j] + a[i - 1][j - 1]
        res = 0
        # 枚举上下两行
        for i in range(1, n + 1):
            for j in range(i, n + 1):
                # 枚举左右两列的的位置
                l = r = 1
                tot = 0
                while r <= m:
                    tot += s[j][r] - s[i - 1][r]
                    while tot > k:
                        tot -= s[j][l] - s[i - 1][l]
                        l += 1
                    # l, r之间的矩阵都是满足条件那么[l, r]之间的个数就是当前固定两行的位置以及对应的每一个r与之最左边的位置l之前的满足子矩阵的个数
                    res += r - l + 1
                    r += 1
        print(res)


if __name__ == '__main__':
    Solution().process()

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/846307.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号