HDU-4278 Faulty Odometer 数学递推 || 八进制

题意

这个里程表当走到3或8的时候就会跳过 给我们这个里程表上显示的数字
让我们求这个里程表的真实数据是多少

分析

由于 3 和 8 不存在 那么就相当于一个八进制数 但是这个八进制中3 是写作4 8是写作9
那么就好写了 也就是把数入的“特别八进制数”转化成一个十进制数
还有一个方法就是推每一位具体是少了多少个数
做题的时候一开始想往数位dp上想
结果Z犇一下就想到了递推 !!
通过对输入数据的每一位进行递推 看看到底少了多少个数
比如当推导数位长度等于2 时 少了: C(2,1)10+1022=36
前面的是当首位是3或8 的时候 后面一位有10种情况 后面的是 当首位非3,8 有8种情况后面一位或3或8
比如当长度为3的时候 : C(2,1)1010102num[] 这里也就相当于递推了

code

八进制:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    while(scanf("%d",&n),n){
        int tmp = n,sum,p;
        p=1;
        sum=0;
        while(tmp){
            int b = tmp%10;
            if(b>8)b-=2;
            else if(b>3)b-=1;
            sum+=b*p;
            p*=8;
            tmp/=10;
        }
        cout<<n<<": "<<sum<<endl;
    }

    return 0;
 }

递推:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int t[11];
ll pow(ll a,ll b){
    ll ans = 1;
    while(b){
        if(b&1)ans*=a;
        a*=a;
        b>>=1;
    }
    return ans;
}

int main()
{
    int n;
    t[0]=0,t[1]=2;
    for(int i=2;i<=9;i++){
        t[i] = pow(10,i-1)*2 + 8*t[i-1];
    }
    while(scanf("%d",&n),n)
    {
        vector<int>ans;
        int tmp = n;
        while(tmp){
            ans.push_back(tmp%10);
            tmp/=10;
        }    
        int cnt=0;        
        for(int i=ans.size()-1;i>0;i--)
        {
            if(ans[i]){
                if(ans[i]>3&&ans[i]<8)ans[i]-=1,cnt+=pow(10,i);
                else if(ans[i]>7&&ans[i]<10)ans[i]-=2,cnt+=2*pow(10,i);
                cnt+=ans[i]*t[i];
            }
        }
        if(ans[0]){
            if(ans[0]>3&&ans[0]<8)cnt++;
            else if(ans[0]>8&&ans[0]<10)cnt+=2;
        }
        printf("%d: %d\n",n,n-cnt);
    }
    return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值