ACdream 1064完美数

来源:互联网 发布:fcn网络结构 编辑:程序博客网 时间:2024/06/08 14:21

http://acdream.info/problem?pid=1064



求L到r之间含有3不含有8 或者 含有8不含有3的数的数量。
大思路就是用1-r符合条件的数减去1-(L-1)符合条件的数。
至于求有多少个,就是数位dp的知识了,从高位开始向后去数。
可以先将前10,100,1000,10000,100000等中包含一个数不包含另一个数的情况打表算出来。
算的时候要注意算到后面的位数的时候要标记前面高位有无出现3或者8.




#include<bits/stdc++.h>using namespace std;long long int ans1[22]={0,1,17,217,2465,26281,269297,2685817,26269505,253202761};long long int ans2[22]={0,9,81,81*9,81*81,81*81*9,81*81*81,81*81*81*9,81*81*81*81,81*81*81*81*9};long long int find(char a[]){int l=strlen(a);long long int ans=0;bool f1=0,f2=0;int i;for(i=0;i<=l-2;i++){        if(f1==0&&f2==0)        {        if(a[i]<='3')        {        ans+=ans1[l-i-1]*2*(a[i]-'0');}else if(a[i]>'3'&&a[i]<='8'){ans+=ans1[l-i-1]*(2*(a[i]-'0'-1))+ans2[l-i-1];}else ans+=ans1[l-i-1]*(2*(a[i]-'0'-2))+ans2[l-i-1]*2;}if(f1==1&&f2==0){ if(a[i]<='8'){ans+=ans2[l-i-1]*(a[i]-'0');}else ans+=ans2[l-i-1]*((a[i]-'0')-1);}if(f1==0&&f2==1){if(a[i]<='3'){ans+=ans2[l-i-1]*(a[i]-'0');}else ans+=ans2[l-i-1]*((a[i]-'0')-1);}if(a[i]=='3')f1=1;if(a[i]=='8')f2=1;}if(f1==0&&f2==0){if(a[l-1]<'3');else if(a[l-1]>='8')ans+=2;else ans+=1;}if(f1==1&&f2==0){if(a[l-1]>='8')ans+=a[l-1]-'0';else ans+=a[l-1]-'0'+1;}if(f1==0&&f2==1){if(a[l-1]>='3')ans+=a[l-1]-'0';else ans+=a[l-1]-'0'+1;}return ans;}int main(){    char a[111],b[111];    int n;    cin>>n;    while(n--)    {    cin>>a>>b;    long long int ans=find(a);    long long int ans12=find(b);    bool f1=0,f2=0;    for(int i=0;i<strlen(a);i++)    {    if(a[i]=='3')f1=1;    if(a[i]=='8')f2=1;}if(f1!=f2)ans--;//cout<<ans<<" "<<ans12<<endl;cout<<ans12-ans<<endl;}return 0;}


原创粉丝点击