51nod 1425 减减数

本文提供了一道名为“减减数”的算法题的解答思路,该题出自 CodeForces 平台。文章详细介绍了如何通过二维 map 记忆化搜索的方法来解决这个问题,并给出了完整的 C++ 代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目来源:  CodeForces
基准时间限制:1 秒 空间限制:131072 KB 分值: 80  难度:5级算法题
 收藏
 关注

初始给定一个整数n。每次可以对其做一个操作,这个操作是将n减去他其中的某一位。得到新的一个数字n’,然后继续操作,直到他变成0为止。

比如24这个例子,24 → 20 → 18 → 10 → 9 → 0


Input
单组测试数据。
第一行有一个整数n(0 ≤ n ≤ 10^12)
Output
输出一个整数表示使得n变成0最少的操作步数。.
Input示例
24
Output示例
5






自己代码还没有理清= = 

晕乎着过了- -  大致就是二维map 记忆化搜索

#include <iostream>
#include <cstring>
#include <iomanip>
#include <cstdio>
#include <string>
#include <algorithm>
#include <queue>
#include <cmath>
#include <map>
using namespace std;
map<long long ,long long >d[100];
map<long long ,long long >p[100];
long long part(long long );
void dfs(long long n,long long s)
{

    if(d[s][n]) return ;
    if(n<=0) return ;
    if(n%10==n)
    {
        d[s][n]=1;
        return ;
    }
    long long x=part(n);
    long long y=part(n-x);
    if(x==n) while(x>9) x/=10;
    while(y>9) y/=10;
    if(y<s) y=s;
    dfs(x,y);
    if(x<s) x=s;
    long long z=0;
    long long w;
    if(p[y][x]<y&&p[y][x])
    {
        //cout<<z<<' '<<n<<endl;
        z=p[y][x];
        w=n-x+z-y;
        dfs(n-x+z-y,s);
        d[s][n]+=d[y][x]+d[s][n-x+z-y];
        p[y][n]=p[y][n-x+z-y];
    }
    else
    {
        if((n-x)%10==n-x)
        {
            if(n-x>0) d[s][n-x]=1;
            else d[s][n-x]=0;
            if(n-x>0)p[s][n-x]=n-x;
            //cout<<s<<' '<<n-x<<endl;
        }
        else
        {
            dfs(n-x,s);
        }
        w=n-x;
        d[s][n]+=d[y][x]+d[s][n-x];
        p[s][n]=p[s][n-x];
    }
    p[s][n]=p[s][w];
    //cout<<s<<' '<<n<<' '<<n-x<<' '<<w<<' '<<' '<<x<<' '<<d[s][n]<<' '<<p[s][n]<<' '<<y<<' '<<x<<' '<<p[y][x]<<endl;

}

long long part(long long n)
{
    long long s=0;
    long long m=0,cc=0,ms=1;
    while(n>0)
    {
        s=s+(n%10)*ms;
        if(n%10>m)
        {
            m=n%10;
            cc=s;
        }
        n=n/10;
        ms*=10;
    }
    return cc;
}

int main()
{
    long long n;
    while(cin>>n)
    {
        dfs(n,0);
        cout<<d[0][n]<<endl;
        long long i=0;
        while(i<100)
        {
            d[i].clear();
            i++;
        }i=0;
        while(i<100)
        {
            p[i].clear();
            i++;
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值