蓝桥杯倒计时 | 倒计时10天

作者🕵️‍♂️:让机器理解语言か

专栏🎇蓝桥杯倒计时冲刺

描述🎨蓝桥杯冲刺阶段,一定要沉住气,一步一个脚印,胜利就在前方!

寄语💓:🐾没有白走的路,每一步都算数!🐾

目录

题目一:X进制减法 

思路: 

代码: 

题目二:扫雷 

思路: 

代码: 

 题目三:李白打酒加强版 

题目大意: 

法一:暴力法:(排列)

法二:递归

代码1:(递归:40%) 

法三: DP

状态转移方程:

代码2:(DP:AC) 


 

题目一:X进制减法 

问题描述

进制规定了数字在数位上逢几进一。

X 进制是一种很神奇的进制, 因为其每一数位的进制并不固定!例如说某 种 X 进制数, 最低数位为二进制, 第二数位为十进制, 第三数位为八进制, 则 X 进制数 321 转换为十进制数为 65 。

现在有两个 X 进制表示的整数 A 和 B, 但是其具体每一数位的进制还不确 定, 只知道 A 和 B 是同一进制规则, 且每一数位最高为 N 进制, 最低为二进 制。请你算出 A−B 的结果最小可能是多少。

请注意, 你需要保证 A 和 B 在 X 进制下都是合法的, 即每一数位上的数 字要小于其进制

输入格式

第一行一个正整数 N, 含义如题面所述。

第二行一个正整数 Ma​, 表示 X 进制数 A 的位数。

第三行 Ma​ 个用空格分开的整数, 表示 X 进制数 A 按从高位到低位顺序各 个数位上的数字在十进制下的表示。

第四行一个正整数 Mb​, 表示 X 进制数 B 的位数。

第五行 Mb​ 个用空格分开的整数, 表示 X 进制数 B 按从高位到低位顺序各 个数位上的数字在十进制下的表示。

请注意, 输入中的所有数字都是十进制的。

输出格式

输出一行一个整数, 表示 X 进制数 A−B 的结果的最小可能值转换为十进 制后再模 1000000007 的结果。

样例输入

11
3
10 4 0
3
1 2 0

样例输出

94

样例说明

当进制为: 最低位 2 进制, 第二数位 5 进制, 第三数位 11 进制时, 减法 得到的差最小。此时 A 在十进制下是 108,B 在十进制下是 14 , 差值是 94。

思路: 

X进制的理解

321
8102

个位 1 

十位 2 * 2

百位 3 * 10 * 2 

规律该位数字乘上前面所有进制数。

X 进制数 A−B 的结果的最小可能值,就是令每一位的进制数最小,每一数位上的数字要小于其进制,所以第i位的进制k为k = max(2, max(list_A[i], list_B[i])+1)

代码: 

n = int(input())
Ma = int(input())
list_A = list(map(int, input().split())) 
Mb = int(input())
list_B = list(map(int, input().split())) 

r = 0 # A-B最小差res
p = 1
m = 1000000007
for i in range(len(list_A)-1, -1, -1):
    k = max(2, max(list_A[i], list_B[i])+1) # 确定进制数k
    # X进制转十进制
    # X(321) -> (3*10*2 + 2*2 + 1 = 65)
    r = (r + p * (list_A[i] - list_B[i])) % m # A - B
    p = p * k % m        # 这里取余%对结果没有影响,但可以尽快运行速度
print(r)

题目二:扫雷 

2021年省赛模拟题 

题目描述

在一个 n 行 m 列的方格图上有一些位置有地雷,另外一些位置为空。

请为每个空位置标一个整数,表示周围八个相邻的方格中有多少个地雷。

输入描述

输入的第一行包含两个整数 n,m。

第 2 行到第 n+1 行每行包含 m 个整数,相邻整数之间用一个空格分隔。如果对应的整数为 0,表示这一格没有地雷。如果对应的整数为 1,表示这一格有地雷。

其中,1≤n,m≤100 分钟后还是在当天。

输出描述

输出 n 行,每行 m 个整数,相邻整数之间用空格分隔。

对于没有地雷的方格,输出这格周围的地雷数量。对于有地雷的方格,输出 9。

输入输出样例

示例 1

输入

3 4
0 1 0 0
1 0 1 0
0 0 1 0

输出

2 9 2 1
9 4 9 2
1 3 9 2

思路: 

        创建一个统计地雷的列表vis。遍历整个图,如果碰到雷,就在标记数组把这个位置标为9,然后把这个位置相邻的八个位置+1 。题目规定有地雷标为“9”,由于不是雷的位置周围最多有八个雷,所以那些位置标记不会超过8 不会和9冲突。

代码: 

n,m = map(int,input().split())
tu = [list(map(int,input().split())) for i in range(n)]#用来存地图

vis = [[0 for j in range(m)]for i in range(n)]# 标记数组:统计周围地雷
dir = [(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)]#写一个方向数组

for i in range(n):#遍历整个tu
    for j in range(m):
        if tu[i][j]==1:#如果这个位置是有雷
            vis[i][j]=9#就将标记数组标记为9
            for x in dir:#然后对周围八个位置进行检查遍历
                xi = i +x[0]
                xj = j +x[1]
                if 0<=xi<=n-1 and 0<=xj<=m-1:#筛选八个位置中不出界的位置
                    if vis[xi][xj]!=9:#如果这个位置不是9 
                        vis[xi][xj]+=1#就将这个位置+1 表示周围有一个雷了  
for i in range(n):#循环遍历输出
    for j in range(m):
        print(vis[i][j],end=' ')
    print()

 题目三:李白打酒加强版 

2022年C/C++省赛压轴题 

问题描述

话说大诗人李白, 一生好饮。幸好他从不开车。

一天, 他提着酒显, 从家里出来, 酒显中有酒 2 斗。他边走边唱:

无事街上走,提显去打酒。 逢店加一倍, 遇花喝一斗。

这一路上, 他一共遇到店 N 次, 遇到花 M 次。已知最后一次遇到的是花, 他正好把酒喝光了。

请你计算李白这一路遇到店和花的顺序, 有多少种不同的可能?

注意: 显里没酒 ( 0 斗) 时遇店是合法的, 加倍后还是没酒; 但是没酒时遇 花是不合法的。

输入格式

第一行包含两个整数 N 和 M.

输出格式

输出一个整数表示答案。由于答案可能很大,输出模 1000000007 的结果.

样例输入

5 10

样例输出

14

样例说明

如果我们用 0 代表遇到花,1 代表遇到店,14 种顺序如下:

010101101000000

010110010010000

011000110010000

100010110010000

011001000110000

100011000110000

100100010110000

010110100000100

011001001000100

100011001000100

100100011000100

011010000010100

100100100010100

101000001010100

题目大意: 

        李白一开始有 2斗酒,他会经过 N次店,遇到M次花,每遇到一次花,他就会喝 1斗酒;每遇到 一次店 ,酒量会变成原来的2倍。最后一次他遇到花,喝完一斗洒后,酒正好是0斗。求满足条件的不同顺序的花和店的母其方案数 

法一:暴力法:(排列)

N次店,M次花,总共N+M次,有(N+M)! 个排列,但N,M≤100,超时。。。 

法二:递归

遇到店,store-1,wine*2

遇到花,flower-1,wine-1

结束条件:当店为0,花为1,酒为1时,方案数+1

代码1:(递归:40%) 

N,M = map(int,input().split())
list=[]
def fun(store,flower,wine):
    if store>0:
        fun(store-1,flower,wine*2)
    if flower>0:
        fun(store,flower-1,wine-1)
    if store==0 and flower==1 and wine==1:
        list.append(1)
    return list
fun(N,M,2)
print(len(list))

法三: DP

dp[i][j][k]:经过 i个位置 ,中间遇到j次店,洒数为k斗的方案教

i的范围1~N+M,j的范围0~N,k的范围0~M (酒量k肯定不能超过M斗,因为只能遇到M次花,每次减一斗,且到最后要减为0) 

遇到店的情况j不为0(已经遇到过店) 且  k % 2 == 0(酒在遇到店后k必为偶数,因为酒在遇到店后翻倍了,才能保证遇到店之前k//2为整数)

状态转移方程:

① 到位置i遇到花/店:dp[i][j][k] = dp[i - 1][j][k + 1] + dp[i - 1][j - 1][k //2]  两种方案数相加

 到位置i遇到花:dp[i][j][k] = dp[i - 1][j][k + 1]

最终的结果:dp[n+m-1][n][1]  前面走过了 n+m-1个位置,中间遇到了n个店,且此时有1斗洒,那么最后1个位置就肯定是花,且走完后酒恰好变为0斗 。

代码2:(DP:AC) 

n, m = map(int, input().split())
MOD = int(1e9) + 7
dp = [[[0] * 110 for _ in range(110)] for i in range(210)]

dp[0][0][2] = 1    # 初始化DP
for i in range(1, n + m + 1):
    for j in range(0, min(i + 1, n + 1)):  # 遍历店,店不超过n个
        for k in range(0, m + 1):          # 酒量
            if j and k % 2 == 0:           # 已经遇到过店且酒是偶数:遇到店/花
                dp[i][j][k] = (dp[i - 1][j][k + 1] + dp[i - 1][j - 1][k //2]) % MOD
            else:                          # 其他情况下:遇到花
                dp[i][j][k] = dp[i - 1][j][k + 1]
print(dp[n + m - 1][n][1])

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小叶pyか

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值