国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

《算法競(jìng)賽·快沖300題》每日一題:“彩虹數(shù)”

這篇具有很好參考價(jià)值的文章主要介紹了《算法競(jìng)賽·快沖300題》每日一題:“彩虹數(shù)”。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

算法競(jìng)賽·快沖300題》將于2024年出版,是《算法競(jìng)賽》的輔助練習(xí)冊(cè)。
所有題目放在自建的OJ New Online Judge。
用C/C++、Java、Python三種語言給出代碼,以中低檔題為主,適合入門、進(jìn)階。


彩虹數(shù)” ,鏈接: http://oj.ecustacm.cn/problem.php?id=1840

題目描述

【題目描述】 彩虹數(shù):一個(gè)無前導(dǎo)0的10進(jìn)制整數(shù),相鄰的兩個(gè)數(shù)字不相同。
給定下界和上界,計(jì)算它們之間的彩虹數(shù)數(shù)量。
【輸入格式】 輸入第一行為正整數(shù)L,表示下界。第二行為正整數(shù)R,表示上界。
1≤L≤R≤10^(100000)。注意,此處的數(shù)字長度可能會(huì)達(dá)到100000。
【輸出格式】 輸出一個(gè)數(shù)字表示答案,由于答案過大,需要對(duì)998244353求余。
【輸入樣例】

樣例11
10

樣例212345
65432

【輸出樣例】

樣例110

樣例235882

題解

??由于區(qū)間[L, R]的范圍極大,直接暴力驗(yàn)證每個(gè)數(shù)字是否為彩虹數(shù)會(huì)超時(shí)。另外,由于數(shù)字太大,直接按數(shù)字進(jìn)行計(jì)算不方便,可以用高精度處理大數(shù),用數(shù)組num[]來存這個(gè)大數(shù),num[i]是大數(shù)的第i位。
??本題與數(shù)位統(tǒng)計(jì)有關(guān),是一道比較直接的數(shù)位統(tǒng)計(jì)DP題。代碼使用了《算法競(jìng)賽》“5.3.2 數(shù)位統(tǒng)計(jì)DP的記憶化搜索實(shí)現(xiàn)”的dfs()模板[ 數(shù)位統(tǒng)計(jì)DP的原理和兩種編碼方法見《算法競(jìng)賽》,清華大學(xué)出版社,羅勇軍、郭衛(wèi)斌著,333~338頁。本題代碼套用了書上的模板。],在dfs()中統(tǒng)計(jì)數(shù)字時(shí),排除掉彩虹數(shù)即可。
??定義dp[]為有前導(dǎo)零、無數(shù)位限制時(shí)的彩虹數(shù)的數(shù)量,例如:
??dp[1],01~09內(nèi)彩虹數(shù)的數(shù)量,有dp[1] = 9。
??dp[2],001~099內(nèi)彩虹數(shù)的數(shù)量,有dp[2] = 81。排除彩虹數(shù)001、002、…、009、011、022、…099,共排除18個(gè),得dp[2] = 99-18 = 81。
??dp[3],0001~0999內(nèi)彩虹數(shù)的數(shù)量,對(duì)應(yīng)dp[3] = 729,排除彩虹數(shù)0001、0002、0099、0100、…0111、0112、…、0999。
??代碼的步驟:
??(1)讀L,R。第28行按字符串讀入L和R。
??(2)solve(s)計(jì)算[1, s]范圍內(nèi)的彩虹數(shù),[L, R]內(nèi)的彩虹數(shù)是solve?-solve(L-1)。由于L是字符串形式表示的數(shù)字,第29~32行提前計(jì)算得到L-1的字符串形式。
??(3)在solve(s)中,先把字符串s表示的大數(shù)轉(zhuǎn)為數(shù)組num[],大數(shù)存在num[1]~num[len]中。例如輸入s =“65432”,得num[1]~num[5] =2、3、4、5、6。
??(4)dfs()統(tǒng)計(jì)[1, s]內(nèi)的彩虹數(shù)的數(shù)量,s是用num[1]~num[len]表示的大數(shù)。第13行累加無前導(dǎo)0時(shí)的數(shù)字的數(shù)量,第14行去除彩虹數(shù)。
??下面說明復(fù)雜度。dfs()的主要任務(wù)是計(jì)算dp[],即求dp[1] ~ dp[len],計(jì)算量極小,約為10×len。
【重點(diǎn)】 數(shù)位統(tǒng)計(jì)DP。

C++代碼

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int num[100005];        //存輸入的數(shù)字
ll dp[100005];
ll MOD = 998244353;
ll dfs(int pos,int last,bool lead,bool limit){             //last: 上一位
    ll ans = 0;
    if(pos==0)   return 1;                                 //遞歸到0位數(shù),結(jié)束返回
    if(!lead && !limit && dp[pos]!=-1)  return dp[pos];    //記憶化搜索
    int up=(limit ? num[pos] : 9);                         //這一位的最大值
    for(int i=0;i<=up;i++){
        if(i==0 && lead)   ans += dfs(pos-1,i,true, limit&&(i==up)); //lead=true,無前導(dǎo)0
        else if(last != i) ans += dfs(pos-1,i,false,limit&&(i==up)); //與上一位不同,排除彩虹數(shù)
        ans %= MOD;
    }
    if(!lead && !limit)    dp[pos] = ans;    //狀態(tài)記錄:有前導(dǎo)0,無數(shù)位限制
    return ans;
}
ll solve(string s){
    int len=0;
    for(int i=s.length()-1;i>=0;i--)   //把字符串轉(zhuǎn)成數(shù)字,存入num[1]~num[len]
        num[++len]=(s[i]-'0');         //例如輸入“65432”,得num[1:5]=2 3 4 5 6
    memset(dp,-1,sizeof(dp));
    return dfs(len,-1,true,true);
}
int main(){
    string L,R;   cin>>L>>R;
    for(int i=L.length()-1;i>=0;i--){    //求L-1,例如L=12345,L-1=12344
        if(L[i]!='0') { L[i]--; break;}  //這一位不是0,減1即可
        else   L[i]='9';                 //這一位是0,減1得9
    }
    cout<<((solve(R)-solve(L))%MOD + MOD) % MOD;
    return 0;
}

Java代碼

import java.util.*;
public class Main {
    static long[] dp = new long[100005];
    static int[] num = new int[100005];
    static long MOD = 998244353;
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String L = scanner.next();
        String R = scanner.next();
        StringBuilder resultL = new StringBuilder(L);
        for (int i = L.length() - 1; i >= 0; i--) {
            if (resultL.charAt(i) != '0') {
                resultL.setCharAt(i, (char)(resultL.charAt(i) - 1));
                break;
            } else {
                resultL.setCharAt(i, '9');
            }
        }
        System.out.println((solve(R) - solve(resultL.toString()) + MOD) % MOD);
    }
    public static long dfs(int pos, int last, boolean lead, boolean limit) {
        long ans = 0;
        if (pos == 0) return 1;
        if (!lead && !limit && dp[pos] != -1) return dp[pos];
        int up = (limit ? num[pos] : 9);
        for (int i = 0; i <= up; i++) {
            if (i == 0 && lead) ans += dfs(pos - 1, i, true, limit && (i == up));
            else if (last != i) ans += dfs(pos - 1, i, false, limit && (i == up));
            ans %= MOD;
        }
        if (!lead && !limit) dp[pos] = ans;
        return ans;
    }

    public static long solve(String s) {
        int len = 0;
        num = new int[100005];
        for (int i = s.length() - 1; i >= 0; i--) 
            num[++len] = s.charAt(i) - '0';
        Arrays.fill(dp, -1);
        return dfs(len, -1, true, true);
    }
}

Python代碼

?? 在solve(s)中,先把字符串s表示的大數(shù)轉(zhuǎn)為數(shù)組num[],大數(shù)存在num[0]~num[len-1]中。例如輸入s =“65432”,得num[0]~num[4] =2、3、4、5、6。文章來源地址http://www.zghlxwxcb.cn/news/detail-696515.html

import sys
sys.setrecursionlimit(100000)
 
MOD = 998244353
dp = [-1] * 100005
num = []
def dfs(pos, last, lead, limit):
    if pos == -1:   return 1     
    global dp
    global num 
    if not lead and not limit and dp[pos] != -1:   return dp[pos]     
    up = num[pos] if limit else 9
    ans = 0     
    for i in range(up + 1):
        if i == 0 and lead:  ans += dfs(pos - 1, i, True,  limit and (i == up))
        elif last != i:      ans += dfs(pos - 1, i, False, limit and (i == up))         
        ans %= MOD     
    if not lead and not limit:    dp[pos] = ans         
    return ans
 
def solve(s):
    global dp
    global num
    num = [int(c) for c in s[::-1]]  #把字符串轉(zhuǎn)成數(shù)字,存入num[0]~num[len-1]
    dp = [-1] * 100005
    return dfs(len(num) - 1, -1, True, True)
 
L = input()
R = input()
L_minus_one = str(int(L) - 1)
result = (solve(R) - solve(L_minus_one) + MOD) % MOD
print(result)

到了這里,關(guān)于《算法競(jìng)賽·快沖300題》每日一題:“彩虹數(shù)”的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 《算法競(jìng)賽·快沖300題》每日一題:“湊二十四”

    《 算法競(jìng)賽·快沖300題 》將于2024年出版,是《算法競(jìng)賽》的輔助練習(xí)冊(cè)。 所有題目放在自建的OJ New Online Judge。 用C/C++、Java、Python三種語言給出代碼,以中低檔題為主,適合入門、進(jìn)階。 “ 湊二十四 ” ,鏈接: http://oj.ecustacm.cn/problem.php?id=1793 【題目描述】 給你n個(gè)數(shù)字,

    2024年02月11日
    瀏覽(18)
  • 《算法競(jìng)賽·快沖300題》每日一題:“松鼠與栗子”

    《 算法競(jìng)賽·快沖300題 》將于2024年出版,是《算法競(jìng)賽》的輔助練習(xí)冊(cè)。 所有題目放在自建的OJ New Online Judge。 用C/C++、Java、Python三種語言給出代碼,以中低檔題為主,適合入門、進(jìn)階。 “ 松鼠與栗子 ” ,鏈接: http://oj.ecustacm.cn/problem.php?id=1852 【題目描述】 現(xiàn)在有m棵栗

    2024年02月11日
    瀏覽(23)
  • 羅勇軍 → 《算法競(jìng)賽·快沖300題》每日一題:“排列變換” ← 貪心算法

    【題目來源】 http://oj.ecustacm.cn/problem.php?id=1812 http://oj.ecustacm.cn/viewnews.php?id=1023 【題目描述】 給定一個(gè)長度為 n 的排列 a,需要將這個(gè)排列變成 b。 每次可以選擇一個(gè)數(shù)字往左移若干個(gè)位置。 請(qǐng)求出 最小需要移動(dòng)的元素個(gè)數(shù) 。 【輸入格式】 第一行為正整數(shù) n,1≤n≤100000。

    2024年02月12日
    瀏覽(24)
  • 羅勇軍 →《算法競(jìng)賽·快沖300題》每日一題:“游泳” ← DFS+剪枝

    【題目來源】 http://oj.ecustacm.cn/problem.php?id=1753 http://oj.ecustacm.cn/viewnews.php?id=1023 【題目描述】 游泳池可以等分為n行n列的小區(qū)域,每個(gè)區(qū)域的溫度不同。 小明現(xiàn)在在要從游泳池的左上角(1, 1)游到右下角(n, n),小明只能向上下左右四個(gè)方向游,不能游出泳池。 而小明對(duì)溫度十分

    2024年02月10日
    瀏覽(19)
  • 羅勇軍 →《算法競(jìng)賽·快沖300題》每日一題:“小球配對(duì)” ← 并查集

    羅勇軍 →《算法競(jìng)賽·快沖300題》每日一題:“小球配對(duì)” ← 并查集

    【題目來源】 http://oj.ecustacm.cn/problem.php?id=1850 http://oj.ecustacm.cn/viewnews.php?id=1023 【題目描述】 給定 n 個(gè)小球,編號(hào)為 1-n ,給定 m 個(gè)籃子,編號(hào)為 1-m 。 每個(gè)球只允許放入樣例給定的編號(hào)為 Ai 或者 Bi 的兩個(gè)籃子中的 1 個(gè)。 每個(gè)球必須放入某個(gè)籃子。 如果籃子中球的數(shù)量為奇

    2024年02月11日
    瀏覽(24)
  • ( 動(dòng)態(tài)規(guī)劃) 516. 最長回文子序列 ——【Leetcode每日一題】

    ( 動(dòng)態(tài)規(guī)劃) 516. 最長回文子序列 ——【Leetcode每日一題】

    難度:中等 給你一個(gè)字符串 s ,找出其中最長的回文子序列,并返回該序列的長度。 子序列定義為:不改變剩余字符順序的情況下,刪除某些字符或者不刪除任何字符形成的一個(gè)序列。 示例 1: 輸入:s = “bbbab” 輸出:4 解釋:一個(gè)可能的最長回文子序列為 “bbbb” 。 示例

    2024年02月06日
    瀏覽(29)
  • ( 動(dòng)態(tài)規(guī)劃) 1035. 不相交的線 ——【Leetcode每日一題】

    ( 動(dòng)態(tài)規(guī)劃) 1035. 不相交的線 ——【Leetcode每日一題】

    難度:中等 在兩條獨(dú)立的水平線上按給定的順序?qū)懴?nums1 和 nums2 中的整數(shù)。 現(xiàn)在,可以繪制一些連接兩個(gè)數(shù)字 nums1[i] 和 nums2[j] 的直線,這些直線需要同時(shí)滿足滿足: nums1[i] == nums2[j] 且繪制的直線不與任何其他連線(非水平線)相交。 請(qǐng)注意,連線即使在端點(diǎn)也不能相交

    2024年02月05日
    瀏覽(27)
  • 【Leetcode每日一題】 動(dòng)態(tài)規(guī)劃 - 地下城游戲(難度???)(61)

    【Leetcode每日一題】 動(dòng)態(tài)規(guī)劃 - 地下城游戲(難度???)(61)

    1. 題目解析 題目鏈接:174. 地下城游戲 這個(gè)問題的理解其實(shí)相當(dāng)簡單,只需看一下示例,基本就能明白其含義了。 2.算法原理 一、狀態(tài)表定義 在解決地下城游戲問題時(shí),我們首先需要對(duì)狀態(tài)進(jìn)行恰當(dāng)?shù)亩x。一個(gè)直觀的想法是,從起點(diǎn)開始,到達(dá)[i, j]位置時(shí)所需的最低初始

    2024年04月29日
    瀏覽(20)
  • 【每日一題 | 動(dòng)態(tài)規(guī)劃】訪問完所有房間的第一天

    【每日一題 | 動(dòng)態(tài)規(guī)劃】訪問完所有房間的第一天

    【動(dòng)態(tài)規(guī)劃】【數(shù)組】【2024-03-28】 1997. 訪問完所有房間的第一天 定義狀態(tài) 定義 f[i] 表示第一次到達(dá)房間 i 的日期編號(hào)。 根據(jù)題意,首次(第 1 次)訪問房間 i 時(shí),因?yàn)?1 是計(jì)數(shù),所以下一次一定會(huì)訪問房間 j = nextVisit[i] 。只有訪問次數(shù)達(dá)到偶數(shù)才能訪問右邊的下一個(gè)房間

    2024年04月16日
    瀏覽(27)
  • [Week 19]每日一題(C++,數(shù)學(xué),并查集,動(dòng)態(tài)規(guī)劃)

    [Week 19]每日一題(C++,數(shù)學(xué),并查集,動(dòng)態(tài)規(guī)劃)

    目錄 [Daimayuan] T1 倒數(shù)第n個(gè)字符串(C++,進(jìn)制) 輸入格式 輸出格式 樣例輸入 樣例輸出 解題思路 [Daimayuan] T2 排隊(duì)(C++,并查集) 輸入格式 輸出格式 樣例輸入1 樣例輸出1 樣例輸入2 樣例輸出2 樣例輸入3 樣例輸出3 數(shù)據(jù)規(guī)模 解題思路 [Daimayuan] T3 素?cái)?shù)之歡(C++,BFS) 數(shù)據(jù)規(guī)模

    2024年02月02日
    瀏覽(28)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包