幸运数字(number)

幸运数字(number)

Time Limit:1000ms   Memory Limit:64MB

 【题目描述】

  LYK最近运气很差,例如在NOIP初赛中仅仅考了90分,刚刚卡进复赛,于是它决定使用一些方法来增加自己的运气值。它觉得,通过收集幸运数字可以快速的增加它的RP值。它给幸运数字下了一个定义:如果一个数x能被3整除或被5整除或被7整除,则这个数为幸运数字。于是它想让你帮帮它在L~R中存在多少幸运数字。

 【输入格式】(number.in)

  第一行两个数L,R。

 【输出格式】(number.out)

  一个数表示答案。

【输入样例】

  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。

【题目分析】

  从L到R中能被3 5 7整除的数字,那就算一下这个区间:3的倍数+5的倍数+7的倍数-15的倍数-35的倍数-21的倍数+105的倍数(容斥原理),要注意计算L之内的数的个数时,L不能算在内(跟 前缀和是同样的原理)

  我们会发现后面还有两组数据的R<=10^100T_T ,高精,弃了。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
long long l,r;
int main()
{
    freopen("number.in","r",stdin);
    freopen("number.out","w",stdout);
    scanf("%I64d%I64d",&l,&r);
    l--;
    long long ans1=l/3+l/5+l/7-l/15-l/21-l/35+l/105;
    long long ans2=r/3+r/5+r/7-r/15-r/21-r/35+r/105;
    cout << ans2-ans1;
    fclose(stdin);fclose(stdout);
    return 0;
}
蒟蒻80
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
using namespace std;
char s1[1005],s2[1005];
int S1[1005],S2[1005],len1,len2,s[1005],S[1005],i;
void pl(int *a,int *b)
{
    for (int i=a[0]+1; i<=b[0]; i++) a[i]=0;
    for (int i=1; i<=b[0]; i++) a[i]+=b[i];
    a[0]=max(a[0],b[0]);
    for (int i=1; i<a[0]; i++) if (a[i]>=10) {a[i+1]++; a[i]-=10;}
    if (a[a[0]]>=10) {a[a[0]+1]=1; a[a[0]]-=10; a[0]++;}
}
void mn(int *a,int *b)
{
    for (int i=a[0]+1; i<=b[0]; i++) a[i]=0;
    for (int i=1; i<=b[0]; i++) a[i]-=b[i];
    for (int i=1; i<a[0]; i++)
    if (a[i]<0) {a[i]+=10; a[i+1]--;}
    while (a[0]>1 && a[a[0]]==0) a[0]--;
}
void work(int *a,int b,int *c)
{
    for (int i=1; i<=a[0]; i++) c[i]=a[i];
    for (int i=a[0]; i>=1; i--)
    {
        c[i-1]+=c[i]%b*10;
        c[i]/=b;
    }
    c[0]=a[0];
    while (c[0]>1 && c[c[0]]==0) c[0]--;
}
int main()
{
    freopen("number.in","r",stdin);
    freopen("number.out","w",stdout);
    scanf("%s",s1);
    scanf("%s",s2);
    len1=strlen(s1);
    len2=strlen(s2);
    for (i=1; i<=len1; i++) S1[len1-i+1]=s1[i-1]-'0';
    S1[0]=len1;
    for (i=1; i<=len2; i++) S2[len2-i+1]=s2[i-1]-'0';
    S2[0]=len2;
    work(S2,3,s);
    work(S2,5,S);
    pl(s,S);
    work(S2,7,S);
    pl(s,S);
    work(S2,15,S);
    mn(s,S);
    work(S2,21,S);
    mn(s,S);
    work(S2,35,S);
    mn(s,S);
    work(S2,105,S);
    pl(s,S);
    S[0]=1; S[1]=1;
    mn(S1,S);
    work(S1,15,S);
    pl(s,S);
    work(S1,21,S);
    pl(s,S);
    work(S1,35,S);
    pl(s,S);
    work(S1,3,S);
    mn(s,S);
    work(S1,5,S);
    mn(s,S);
    work(S1,7,S);
    mn(s,S);
    work(S1,105,S);
    mn(s,S);
    for (i=s[0]; i>=1; i--) cout<<s[i];
    return 0;
}
std的话是长这个样子的

 

posted @ 2016-11-09 06:06  [lemon]  阅读(513)  评论(0编辑  收藏  举报
……