C. Unlucky Numbers(数位dp)

简介: C. Unlucky Numbers(数位dp)

题目

题意

  • 给两个数 l 和 r  (1≤l≤r≤1018) ( 1 ≤ l ≤ r ≤ 10^{18})(1lr1018)
  • 请找出再这个范围内的一个数字,使得按数位这个数字中的数最大值和最小值之差最小

思路

  • 当 l 和 r 的数位长度不一样时,可以输出和l长度相同的999...(贪心)
  • 在此之外,数位dp的思想,进行搜索
  • 定义dfs(intst,intstart,inted,charmaxLast,charminLast)dfs(int st, int start, int ed, char maxLast, char minLast)dfs(intst,intstart,inted,charmaxLast,charminLast)
  • st 当前搜索到的数位
  • start 左边界是否受限
  • ed 右边界是否受限
  • maxLast(mingLast) 当前搜索的最大和最小值

代码

ini

复制代码

string a, b;
int ans = 10;
string res;
string temp;
void dfs(int st, int start, int ed, char maxLast, char minLast)
{
    if (maxLast - minLast >= ans)  //剪枝掉比当前不优的情况
        return;
    if (st == a.size())            //搜索结束
    {
        ans = maxLast - minLast;
        res = temp;
        return;
    }
    char l ;                       //搜索的起点和终点
    char r ;
    
    if (start && ed)
        l = a[st],r = b[st];
    else if (start)
        l = a[st],r = '9';
    else if (ed)
        l = '0',r = b[st];
    else
        l = '0', r = '9';
    for (char i = l; i <= r; i++)
    {
        temp.push_back(i);
        dfs(st + 1, i == l && start, i == r && ed, max(maxLast, i), min(minLast, i));
        temp.pop_back();
    }
}
void solve()
{
    int l, r;
    cin >> l >> r;
    a = to_string(l);
    b = to_string(r);
    res = a;
    ans = 10;
    temp.clear();
    if (a.size() + 1 <= b.size())
    {
        cout << string((int)a.size(), '9') << endl;
        return;
    }
    for (char i = a[0]; i <= b[0]; i++)
    {
        temp.push_back(i);
        dfs(1, i == a[0], i == b[0], i, i);
        temp.pop_back();
    }
    cout << res << endl;
}


相关文章
|
6月前
不要62(数位dp)
不要62(数位dp)
42 0
|
6月前
|
存储
【题型总结】数位dp(一)
【题型总结】数位dp(一)
78 0
筛质数、分解质因数和快速幂的应用
筛质数、分解质因数和快速幂的应用
62 0
|
1月前
|
存储
72. 编辑距离、198.打家劫舍、213_打家劫舍2(12021-11-06)
72. 编辑距离、198.打家劫舍、213_打家劫舍2(12021-11-06)
22 0
|
6月前
数位dp(计数问题)
数位dp(计数问题)
|
6月前
|
存储 网络架构
【题型总结】数位dp(二)
【题型总结】数位dp(二)
73 0