题意
这个里程表当走到3或8的时候就会跳过 给我们这个里程表上显示的数字
让我们求这个里程表的真实数据是多少
分析
由于 3 和 8 不存在 那么就相当于一个八进制数 但是这个八进制中3 是写作4 8是写作9
那么就好写了 也就是把数入的“特别八进制数”转化成一个十进制数
还有一个方法就是推每一位具体是少了多少个数
做题的时候一开始想往数位dp上想
结果Z犇一下就想到了递推 !!
通过对输入数据的每一位进行递推 看看到底少了多少个数
比如当推导数位长度等于2 时 少了: C(2,1)∗10+(10−2)∗2=36
前面的是当首位是3或8 的时候 后面一位有10种情况 后面的是 当首位非3,8 有8种情况后面一位或3或8
比如当长度为3的时候 : C(2,1)∗10∗10+(10−2)∗num[两位的情况] 这里也就相当于递推了
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;
}