幸运数字(容斥原理+高精度与低精度的加 减 除)

来源:互联网 发布:js内存泄漏检测工具 编辑:程序博客网 时间:2024/04/30 10:14

幸运数字

题目描述:
LYK 最近运气很差,例如在 NOIP 初赛中仅仅考了 90 分,刚刚卡进复赛,于是它决定使用一些方法来增加自己的运气值。
它觉得,通过收集幸运数字可以快速的增加它的 RP 值。
它给幸运数字下了一个定义:如果一个数 x 能被 3 整除或被 5 整除或被 7 整除,则这个数为幸运数字。
于是它想让你帮帮它在 L~R 中存在多少幸运数字。
输入格式:
第一行两个数 L,R。
输出格式:
一个数表示答案。
输入样例
10 15
输出样例
4
数据范围:
对于 50%的数据 1<=L<=R<=10^5。
对于 60%的数据 1<=L<=R<=10^9。
对于 80%的数据 1<=L<=R<=10^18。
对于 90%的数据 1<=L<=R<=10^100。
对于另外 10%的数据 L=1, 1<=R<=10^100。
对于 100%的数据 L, R 没有前导 0。
思路:
容斥原理
设num(n,i)表示1~n中是i的倍数
则求1~n中3或5或7的倍数为
num(n,3)+num(n,5)+num(n,7)-num(n,3*5)-num(n,3*7)-num(5*7)+num(n,3*5*7)
这样求出1~r的减去1~l-1的即可
高精度!!!

#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int maxn=1010;int len,a[maxn],b[maxn],t[maxn],ans[maxn];int sa[maxn],sb[maxn],c[2]={1,1};char s1[maxn],s2[maxn];void jian2(int *a,int *b){    memset(sa,0,sizeof(sa));    memset(sb,0,sizeof(sb));    sa[0]=a[0];    for(int i=1;i<=a[0];i++)    sa[i]=a[a[0]-i+1];    for(int i=1;i<=b[0];i++)    sb[i]=b[b[0]-i+1];    int len=1;    while(len<=sa[0])    {        sa[len]=sa[len]-sb[len];        if(sa[len]<0)        {            sa[len]=sa[len]+10;            sa[len+1]--;        }        len++;    }    while(sa[0]>1&&!sa[a[0]])    sa[0]--;a[0]=sa[0];    for(int i=1;i<=sa[0];i++)    a[i]=sa[sa[0]-i+1];}void div(int *r,int *a,int x){    int s=0;r[0]=a[0];    for(int i=1;i<=a[0];i++)    {        s=s*10+a[i];        r[i]=s/x;        s=s%x;    }}void add(int *a,int *b){    memset(sa,0,sizeof(sa));    memset(sb,0,sizeof(sb));    int len1=a[0],len2=b[0],len=1;    for(int i=1;i<=len2;i++)    sb[i]=b[len2-i+1];    while(len<=len1||len<=len2)    {        sa[len]+=a[len]+sb[len];        sa[len+1]=sa[len]/10;        sa[len]=sa[len]%10;        len++;    }    while(len>1&&!sa[len])    len--;sa[0]=len;    for(int i=0;i<=sa[0];i++) a[i]=sa[i];}void jian(int *a,int *b){    memset(sb,0,sizeof(sb));    for(int i=1;i<=b[0];i++)    sb[i]=b[b[0]-i+1];    int len=1;    while(len<=a[0])    {        a[len]=a[len]-sb[len];        if(a[len]<0)        {            a[len]=a[len]+10;            a[len+1]--;        }        len++;    }    while(a[0]>1&&!a[a[0]])    a[0]--;}int main(){    freopen("number.in","r",stdin);    freopen("number.out","w",stdout);    cin>>s1>>s2;    int l1=strlen(s1),l2=strlen(s2);    a[0]=l1,b[0]=l2;    for(int i=1;i<=l1;i++) a[i]=s1[i-1]-'0';     for(int i=1;i<=l2;i++) b[i]=s2[i-1]-'0';    jian2(a,c);    div(t,b,3);add(ans,t);    div(t,b,5);add(ans,t);    div(t,b,7);add(ans,t);    div(t,a,3*5);add(ans,t);    div(t,a,3*7);add(ans,t);    div(t,a,5*7);add(ans,t);    div(t,b,3*5*7);add(ans,t);    div(t,b,3*5);jian(ans,t);    div(t,b,3*7);jian(ans,t);    div(t,b,5*7);jian(ans,t);    div(t,a,3);jian(ans,t);    div(t,a,5);jian(ans,t);    div(t,a,7);jian(ans,t);    div(t,a,3*5*7);jian(ans,t);    for(int i=ans[0];i>=1;i--)    cout<<ans[i];    fclose(stdin);fclose(stdout);    return 0;}
0 0
原创粉丝点击