蓝桥杯 第五十六天 数位dp

度的数量

这一题主要是题意比较搞人,第一个break不太好理解

def dp(x):
    if x==0:
        return 0
    nums=[]
    while x>0:
        nums.append(x%b)
        x//=b
    ans=0
    last=0
    for i in range(len(nums)-1,-1,-1):
        x=nums[i]
        if x!=0:
            ans+=f[i][k-last]
            if x>1:
                if k-last>0:
                    ans+=f[i][k-last-1]
                break
            elif x==1:
                last+=1
                if last>k:
                    break
        if i==0 and last==k:
            ans+=1
    return ans


N=35
def init():
    for i in range(N):
        for j in range(i+1):
            if j==0:
                f[i][j]=1
            else:
                f[i][j]=f[i-1][j]+f[i-1][j-1]
    return
n,m=map(int,input().split())
k=int(input())
b=int(input())
f=[[0 for i in range(N)]for j in range(N)]
init()
print(dp(m)-dp(n-1))

数字游戏

首先得预处理一个dp数组
其次就是数位dp的一个过程

  • 枚举当前点选择该数字还是不选择该数字
  • 如果不选择该数字,那么就可以通过预处理的数字直接求得答案
  • 如果选择当前数字,则往下走,如果不满足条件了,直接break
def init():
    for i in range(10):
        dp[1][i] = 1
    for i in range(2,5):
        for j in range(10):
            for k in range(j,10):
                dp[i][j]+=dp[i-1][k]
    return
def dfs(x):
    if x==0:
        return 0
    nums=[]
    while x!=0:
        nums.append(x%10)
        x//=10
    last=0
    ans=0
    for i in range(len(nums)-1,-1,-1):
        x=nums[i]
        for k in range(last,x):
            ans+=dp[i+1][k]
        if x<last:
            break
        else:
            last=x
        if i==0:
            ans+=1
    return ans
dp=[[0 for i in range(11)]for j in range(5)]
init()
for i in range(2):
    l,r=map(int,input().split())
    print(dfs(r)-dfs(l-1))
### 蓝桥杯程序设计真题概述 蓝桥杯大赛作为一项面向全国高校学生的科技竞赛活动,其嵌入式和程序设计类别的题目涵盖了广泛的计算机科学知识点。以下是部分蓝桥杯真题及其解析: #### 嵌入式类别真题 - **第十六届蓝桥杯嵌入式真题**:涉及硬件接口编程、实时操作系统应用等内容[^1]。 - **第十二至十五届省赛及模拟考试真题**:这些题目通常围绕单片机控制、传感器数据处理以及通信协议实现展开[^1]。 #### C语言算法赛——蓝桥杯(省赛试题) 以下是一个关于计数问题的具体例子: ```c #include <stdio.h> #define MAX_QUESTIONS 30 #define MAX_SCORE 100 long long count_possible_ways() { int target_score = 70; int num_questions = 30; long long dp[MAX_QUESTIONS + 1][MAX_SCORE + 1] = { 0 }; dp[0][0] = 1; for (int i = 1; i <= num_questions; i++) { for (int j = 0; j <= target_score; j++) { dp[i][j] += dp[i - 1][j]; if (j >= 10) { dp[i][j] += dp[i - 1][j - 10]; } } } return dp[num_questions][target_score]; } int main() { long long possible_ways = count_possible_ways(); printf("小蓝所有可能的答题情况有 %lld 种。\n", possible_ways); return 0; } ``` 此代码通过动态规划方法解决了一个特定场景下的组合问题[^2]。 #### 数字特性判断问题 另一个典型问题是寻找满足特殊条件的整数集合: ```cpp #include <bits/stdc++.h> using namespace std; typedef long long LL; bool check(LL x) { LL res = x * x * x; while(x) { if((x%10) != (res%10)) return false; x /= 10, res /= 10; } return true; } int main() { int cnt = 0; for(LL i=1; i<=10000; ++i) if(check(i)) cnt++; cout << cnt << endl; return 0; } ``` 上述代码实现了对四位以内自然数的一种筛选逻辑[^3]。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值