• 模拟赛1101d2


    幸运数字(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。

    /*
     容斥原理
      对于1~x中,ans=x/3+x/5+x/7-x/15-x/21-x/35+x/105
      注意高精度时应该先把该加的都加上,在进行减法,这样可以避免出现负数。
    */
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define N 200
    using namespace std;
    char s[N];int a1[N],b1[N],c1[N];
    struct node
    {
        int a[N],len;
        void clear()
        {
            memset(a,0,sizeof(a));len=0;
        }
    };node s1,s2,ans;
    node jia(node x,node y)
    {
        node c;c.clear();
        memset(a1,0,sizeof(a1));
        memset(b1,0,sizeof(b1));
        memset(c1,0,sizeof(c1));
        for(int i=1;i<=x.len;i++)a1[i]=x.a[x.len-i+1];
        for(int i=1;i<=y.len;i++)b1[i]=y.a[y.len-i+1];
        int len=max(x.len,y.len);
        for(int i=1;i<=len;i++)
        {
            c1[i]+=a1[i]+b1[i];
            c1[i+1]+=c1[i]/10;
            c1[i]%=10;
        }
        if(c1[len+1])len++;
        c.len=len;
        for(int i=len;i>=1;i--)c.a[i]=c1[len-i+1];
        return c;
    }
    node jian(node x,node y)
    {
        node c;c.clear();
        memset(a1,0,sizeof(a1));
        memset(b1,0,sizeof(b1));
        memset(c1,0,sizeof(c1));
        for(int i=1;i<=x.len;i++)a1[i]=x.a[x.len-i+1];
        for(int i=1;i<=y.len;i++)b1[i]=y.a[y.len-i+1];
        int len=max(x.len,y.len);
        for(int i=1;i<=len;i++)
        {
            if(a1[i]>=b1[i])c1[i]=a1[i]-b1[i];
            else
            {
                c1[i]=a1[i]+10-b1[i];
                a1[i+1]--;
            }
        }
        int p=len;
        while(c1[p]==0)p--;
        for(int i=p;i>=1;i--)c.a[++c.len]=c1[i];
        return c;
    }
    node chu(node x,int b)
    {
        node c;c.clear();
        memset(a1,0,sizeof(a1));
        int xx=0;
        for(int i=1;i<=x.len;i++)
        {
            a1[i]=(xx*10+x.a[i])/b;
            xx=xx*10+x.a[i]-a1[i]*b;
        }
        int len=1;
        while(!a1[len]&&len)len++;
        for(int i=len;i<=x.len;i++)
          c.a[++c.len]=a1[i];
        return c;
    }
    void init()
    {
        s1.a[s1.len]--;
        for(int i=s1.len;i>=1;i--)
        {
            if(s1.a[i]>=0)break;
            else
            {
                s1.a[i]+=10;
                s1.a[i-1]--;
            }
        }
        if(!s1.a[1])
        {
            s1.len--;
            for(int i=1;i<=s1.len;i++)
              s1.a[i]=s1.a[i+1];
        }
    }
    int main()
    {
        //freopen("number.in","r",stdin);
        //freopen("number.out","w",stdout);
        cin>>s;s1.len=strlen(s);
        for(int i=1;i<=s1.len;i++)s1.a[i]=s[i-1]-'0';
        cin>>s;s2.len=strlen(s);
        for(int i=1;i<=s2.len;i++)s2.a[i]=s[i-1]-'0';
        init();
        ans=chu(s2,3);
        ans=jia(ans,chu(s2,5));
        ans=jia(ans,chu(s2,7));
        ans=jia(ans,chu(s2,105));
        ans=jia(ans,chu(s1,15));
        ans=jia(ans,chu(s1,21));
        ans=jia(ans,chu(s1,35));
        ans=jian(ans,chu(s2,15));
        ans=jian(ans,chu(s2,21));
        ans=jian(ans,chu(s2,35));
        ans=jian(ans,chu(s1,3));
        ans=jian(ans,chu(s1,5));
        ans=jian(ans,chu(s1,7));
        ans=jian(ans,chu(s1,105));
        for(int i=1;i<=ans.len;i++)
          printf("%d",ans.a[i]);
        return 0;
    }

    位运算(bit)
    Time Limit:2000ms Memory Limit:64MB
    题目描述
    lyk 最近在研究位运算。它发现除了 xor,or,and 外还有很多运算。
    它新定义了一种运算符“#” 。
    具体地,可以由 4 个参数来表示。 令 a[i][j]表示 i#j。 其中 i,j 与 a 的值均∈[0,1]。
    当然问题可以扩展为>1 的情况,具体地,可以将两个数分解为 p 位,然后对于每一位
    执行上述的位运算,再将这个二进制串转化为十进制就可以了。
    例如当 a[0][0]=0, a[1][1]=0, a[0][1]=1, a[1][0]=1 时,3#4 在 p=3 时等于 7,2#3 在
    p=4 时等于 1(实际上就是异或运算)。
    现在 lyk 想知道的是,已知一个长为 n 的数列 b。它任意选取一个序列 c,满
    足 c1<c2<...<ck,其中 1≤c1 且 ck≤n,定义这个序列的价值为 b{c1}#b{c2}#...#b{ck}
    的平方。
    这里我们假设 k 是正整数,因此满足条件的 c 的序列个数一定是 2^n−1 。 lyk 想知道
    所有满足条件的序列的价值总和是多少。
    由于答案可能很大, 你只需输出答案对 1,000,000,007 取模后的结果即可。
    输入格式(bit.in)
    第一行两个数 n,p。
    第二行 4 个数表示 a[0][0], a[0][1], a[1][0], a[1][1]。
    第三行 n 个数表示 bi(0<=bi<2^p)。
    输出格式(bit.out)
    一个数表示答案。
    输入样例
    3 30
    0 1 1 0
    1 2 3
    输出样例
    28
    样例解释
    {1}的价值为 1, {2}的价值为 4, {3}的价值为 9, {1,2}的价值为 9, {1,3}的价值为 4, {2,3}
    的价值为 1, {1,2,3}的价值为 0,因此 7 个子集的价值总和为 28。
    数据范围
    总共 10 组数据。
    对于第 1,2 组数据 n<=5。
    对于第 3,4 组数据 n<=10000, p=1。
    对于第 5 组数据 a 值均为 0。
    对于第 6 组数据 a 值均为 1。
    对于第 7 组数据 a[0][0]=0,a[1][0]=0,a[1][1]=1,a[0][1]=1。
    对于第 8,9 组数据 n<=1000, p<=10。
    对于所有数据 n<=10000, 1<=p<=30。

    蚂蚁运输(ant)
    Time Limit:5000ms Memory Limit:64MB
    题目描述
    LYK 在观察一些蚂蚁。
    蚂蚁想要积攒一些货物来过冬。积攒货物的方法是这样的。
    对于第 i 只蚂蚁,它要从 li出发,拿起货物,走到 ri处放下货物,需要消耗的时间为|ri-li|。
    而且所有蚂蚁都是可以同时进行的,也就是说,假如有 m 只蚂蚁,那么运输完货物的时间
    为 max{|ri-li|}。
    LYK 决定帮蚂蚁一把,它发明了空间传输装置。具体地,当蚂蚁走到 X 处时,它可以不
    耗费任意时间的情况下瞬间到达 Y,或者从 Y 到达 X。也就是说,一个蚂蚁如果使用了空间
    传输装置,它耗费的时间将会是 min{|li-X|+|ri-Y|,|li-Y|+|ri-X|},当然蚂蚁也可以选择徒步走
    到目标点。
    由于空间传输装置非常昂贵, LYK 打算只建造这么一台机器。并且 LYK 想让蚂蚁运输完
    货物的时间尽可能短,你能帮帮它吗?
    输入格式(ant.in)
    第一行两个数 n,m, n 表示 li,ri 的最大值。
    接下来 m 行,每行两个数 li,ri。
    输出格式(ant.out)
    一个数表示答案
    输入样例
    5 2
    1 3
    2 4
    输出样例
    1
    数据范围
    对于 20%的数据 n,m<=100。
    对于 40%的数据 n,m<=1000。
    对于 60%的数据 n<=100000, m<=1000。
    对于 80%的数据 n,m<=100000。
    对于 100%的数据 n,m<=1000000, 1<=li,ri<=n( li=ri 时你甚至可以无视这只蚂蚁)。
    样例解释
    令空间传输装置的参数中 X=2, Y=3 或者 X=3, Y=2 都行。

    /*
      二分答案
      因为要求|li-X|+|ri-Y|<=mid,所以
      li-X+ri-Y<=mid;li-X+Y-ri<=mid;X-li+Y-ri<=mid;X-li+ri-Y<=mid;
      即 li+ri-mid<=X+Y<=li+ri+mid;li-ri-mid<=X-Y<=li-ri+mid
      需要找要满足上述要求的X,Y。 
    */
    #include<cstdio>
    #include<algorithm>
    #include<cstdlib>
    #include<iostream>
    #define N 1000010
    using namespace std;
    int n,m;
    struct node
    {
        int x,y;
    };node a[N];
    int read()
    {
        int num=0,flag=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')flag=-1;c=getchar();}
        while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();}
        return num*flag;
    }
    bool check(int k)
    {
        int mn=1e9,mx=-1e9;
        for(int i=1;i<=m;i++)
        {
            if(a[i].y-a[i].x<=k)continue;
            mx=max(a[i].x+a[i].y-k,mx);
            mn=min(a[i].x+a[i].y+k,mn);
        }
        if(mx>mn)return false;
        mx=-1e9,mn=1e9;
        for(int i=1;i<=m;i++)
        {
            if(a[i].y-a[i].x<=k)continue;
            mx=max(a[i].x-a[i].y-k,mx);
            mn=min(a[i].x-a[i].y+k,mn);
        }
        if(mx>mn)return false;
        return true;
    }
    int main()
    {
        freopen("jh.in","r",stdin);
        //freopen("ant.in","r",stdin);
        //freopen("ant.out","w",stdout);
        int t;scanf("%d%d",&n,&t);
        while(t--)
        {
            int x,y;scanf("%d%d",&x,&y);
            if(x>y)swap(x,y);
            if(x!=y){a[++m].x=x;a[m].y=y;}
        }
        int l=0,r=N,ans;
        while(l<=r)
        {
            int mid=(l+r)/2;
            if(check(mid))
            {
                ans=mid;r=mid-1;
            }
            else l=mid+1;
        }
        printf("%d",ans);
        return 0;
    }
     
     
  • 相关阅读:
    SpringMVC表单标签
    Toad for Oracle的安装
    大量Javascript/JQuery学习教程电子书合集
    SpringMVC 异常处理
    Git 在小团队中的管理流程(转)
    Git
    程序员必须知道的几个Git代码托管平台(转)
    工程师文化,是一种内心的欲望与恐惧的表达。对创造的欲望,对世界的恐惧。因为欲望而创造,因为恐惧而改造。创造世界,改造世界。(转)
    Do not wait until the conditions are perfect to begin. Beginning makes the conditions perfect(转)
    C++断言assert
  • 原文地址:https://www.cnblogs.com/harden/p/6036304.html
Copyright © 2020-2023  润新知