• 2017 济南综合班 Day 2


    木棍(stick)

    Time Limit:1000ms   Memory Limit:128MB

    题目描述

    LYK有很多木棍,具体的,总共有n根,且每根木棍都有一个长度。为了方便起见,我们可以用一个正整数ai表示第i根木棍的长度。

    LYK有一把小刀,但这把小刀由于削木棍很不方便,对于一根木棍而言,它只能用这把小刀削掉恰好1的长度。

    LYK觉得如果4根木棍头尾相连能恰好拼成长方形,说明这4根木棍是可以捆在一起卖钱的!具体的,如果这4根木棍的长度分别为a,b,c,d,如果满足a=b,c=d,说明恰好可以拼成长方形,且获得的钱为这4根木棍圈成的面积a*c。当然如果不能恰好拼成长方形,则卖不出去。

    LYK想将这些木棍尽可能的4个一组捆在一起去卖钱,它想知道最多能获得多少钱。

    输入格式(stick.in)

    第一行一个数n,表示木棍的个数。

    接下来一行n个数,第i个数ai表示第i根木棍的长度。

    输出格式(stick.out)

    一个数表示答案。

    输入样例

    12

    2 3 3 4 5 5 5 5 7 9 11 13

    输出样例

    31

    数据范围

    对于30%的数据n=4。

    对于50%的数据n<=20。

    对于70%的数据n<=1000。

    对于100%的数据1<=n<=100000,1<=ai<=1000000。

    从大到小枚举长度,如果是奇数个,就割1

    再从大到小枚举长度,拿出两个来相乘

    #include<cstdio>
    #include<algorithm>
    #define N 1000001
    using namespace std;
    int n,x,maxn,minn=N;
    int a[N],b[N];
    long long ans;
    int main()
    {
        freopen("stick.in","r",stdin);
        freopen("stick.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&x);
            a[x]++;
            maxn=max(maxn,x);
            minn=min(minn,x);
        }
        for(int i=maxn;i>=minn;i--)
            if(a[i] && (a[i]+b[i])&1) b[i-1]++,a[i]--;
        for(int i=maxn;i>=minn;i--) a[i]+=b[i];
        int r1,r2,now=maxn;
        while(now>=minn) 
        {
            while(now>=minn && a[now]<2) now--;
            if(now<minn) break;
            r1=now; a[now]-=2;
            while(now>=minn && a[now]<2) now--;
            if(now<minn) break;
            r2=now; a[now]-=2;  
            ans+=1ll*r1*r2;
        }
        printf("%I64d",ans);
    }
    View Code

    寻找最美的你(select)

    Time Limit:2000ms   Memory Limit:128MB

    题目描述

    LYK带着悲伤行走在黑暗里。寂穆的夜空没有星月的点缀,身旁的树木、房屋、万事万物连同你自己,都融于宇宙的虚无缥缈之中。黑暗,压抑、膨胀、严严实实包围整个世界,LYK害怕,彷徨,无奈。突然,眼前出现一扇窗,流漏出点点昏黄的灯光。LYK欣喜地奔去看,原来这里有n个数字LYK深深地被它们吸引。

    这个问题是这样的,如果一个区间[L,R]存在一个数ai,使得这个数是这个区间所有数的约数,那么[L,R]这段区间,是一段好区间。

    现在,LYK想知道最长的好区间的长度是多少,并且它想知道最长的好区间具体的位置,如果有多个,从小到大输出它们的左端点。

    输入格式(select.in)
    第一行一个数n,表示有n个这样的数字。

    第二行n个数ai。

    输出格式(select.out)

    第一行两个数sum,len。其中sum表示有sum个最长的好区间,len表示最长的好区间的长度。

    第二行sum个数,从小到大输出,表示所有最长好区间的左端点。

    输入样例

    5

    4 6 9 3 6

    输出样例

    1 4

    2

    样例解释:

    有一个最长的好区间[2,5]。

    数据范围

    对于40%的数据n<=100。

    对于60%的数据n<=3000。

    对于80%的数据n<=30000。ai<=1000。

    对于100%的数据1<=n<=300000,1<=ai<=1000000。ai以一定方式随机。

    从小到大枚举每个数,看以它为约数向左向右最远能扩展到哪儿

    扩展到的地方打上标记,打上标记的数不再枚举

    O(n)

    #include<cstdio>
    #include<algorithm>
    #define N 300001
    using namespace std;
    int n,a[N],minn;
    int ans[N],len;
    bool v[N];
    struct node
    {
        int num,id;
        bool operator < (node p)const
        {
            return num<p.num;
        }
    }e[N];
    int main()
    {
        freopen("select.in","r",stdin);
        freopen("select.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]),e[i].id=i,e[i].num=a[i];
        sort(e+1,e+n+1);
        for(int i=1;i<=n;i++)
        {
            if(v[e[i].id]) continue;
            v[e[i].id]=true;
            minn=e[i].num;
            int j,k;
            for(j=e[i].id-1;j;j--) if(a[j]%minn) break; else v[j]=true;
            for(k=e[i].id+1;k<=n;k++) if(a[k]%minn) break; else v[k]=true;
            j++; k--;
            if(k-j+1>len) len=k-j+1,ans[0]=1,ans[1]=j;
            else if(k-j+1==len) ans[++ans[0]]=j;
        }
        sort(ans+1,ans+ans[0]+1);
        printf("%d %d
    ",ans[0],len);
        for(int i=1;i<=ans[0];i++) printf("%d ",ans[i]);
    }
    View Code

    数字(number) 

    Time Limit:2000ms   Memory Limit:128MB

    题目描述

    LYK定义了一个新的计算。

    具体地,一开始它有两个数字a和b。

    每一步,它可以将b增加1,或者将a乘上b。

    也就是说(a,b)经过一次操作后可以变成(a,b+1)或者(a*b,b)。再经过一次操作可以变成(a,b+2)或者(a*(b+1),b+1)或者(a*b,b+1)或者(a*b*b,b)。接下来都类似……它认为只有在这个括号左侧的数字才是有意义的,并且它想执行的操作数不会很多。

    具体的,如果LYK能通过不超过p步,使得这个括号内左侧的数字变成x,那么x就是一个有意义的数字!

    zhw觉得这个题目太难了,会为难大家,于是他将这个问题中初始的a定义为了1,把b定义为了0。

    LYK想知道在一段区间[L,R]中,存在多少有意义的数字。

    输入格式(number.in)

    第一行3个数分别表示L,R,p。

    输出格式(number.out)

    一个数表示答案。

    输入样例1

    1 100 10

    输出样例1

    46

    输入样例2

    233 233333333 50

    输出样例2

    332969

    数据范围

    对于30%的数据L,R<=10。

    对于另外20%的数据p<=20。

    对于70%的数据1<=L<=R<=10001<=p<=50。

    对于90%的数据1<=L<=R<=10000001<=p<=50。

    对于100%的数据1<=L<=R<=5000000001<=p<=50。

    首先,如果一个数可能有意义,那么他分解质因数的结果全都<=p

    所以先预处理所有可能有意义的数,大概一百万个

    dp[j]+i 表示 左边到j,右边到i ,所需的最少操作次数

    显然,只有dp[j]+i<=p,j这个数才有意义

    如果k是j的约数,那么dp[j]可以由dp[k]加1更新

    而j的范围到500000000,显然数组开不下

    所以将所有有意义的数映射,即j不再表示有意义的数是j,表示第j个有意义的数

    #include<cstdio>
    #include<algorithm>
    #define N 3000001
    using namespace std;
    int l,r,p;
    int prime[51],sum_prime;
    int b[N],cnt;
    int dp[N];
    bool v[N];
    void dfs(int x,int num)
    {
        if(x==sum_prime+1) 
        {
            b[++cnt]=num;
            return;
        }
        dfs(x+1,num);
        while(1)
        {
            if(1ll*num*prime[x]>r) return;
            num*=prime[x];
            dfs(x+1,num);
        }
    }
    int main()
    {
    //    freopen("number.in","r",stdin);
    //    freopen("number.out","w",stdout);
        scanf("%d%d%d",&l,&r,&p);
        bool f=true;
        for(int i=2;i<=p;i++)
        {
            f=true;
            for(int j=2;j*j<=i;j++)
             if(i%j==0) { f=false; break; }
            if(f) prime[++sum_prime]=i;
        }
        dfs(1,1);
        sort(b+1,b+cnt+1);
        for(int i=2;i<=cnt;i++) dp[i]=100;
         for(int i=2;i<=p;i++)
        {
            int k=1;
            for(int j=1;j<=cnt;j++)
             if(b[j]%i==0)
             {
                 if(dp[k]+1<dp[j]) dp[j]=dp[k]+1;
                 k++;
                 if(dp[j]+i<=p) v[j]=true;
             }
        }
        v[1]=true;
        int ans=0;
        for(int i=1;i<=cnt;i++)
         if(b[i]>=l && v[i]) ans++;
        printf("%d",ans);
    }
    View Code
  • 相关阅读:
    windows下安装mysql教程
    python生成器实现杨辉三角
    python默认参数问题
    python中判断素数的函数
    extract()和extact_first()的区别
    硬连接和软连接的区别
    du与df的区别
    命题逻辑
    关于 better-scroll 设置了以后无法滚动或不生效的问题
    Maven *IDEA*
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/7299776.html
Copyright © 2020-2023  润新知