zoukankan      html  css  js  c++  java
  • 洛谷P1080(NOIP2012)国王游戏——贪心排序与高精度

    题目:https://www.luogu.org/problemnew/show/P1080

    排序方法的确定,只需任取两个人,通过比较与推导,可以得出ai*bi小的人排在前面;

    高精度写的时候犯了些细节错误,详见注释。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define MAXN 200005
    using namespace std;
    typedef long long ll;//用long long! 
    ll n,ka,kb,ans[MAXN],tmp[MAXN],tmp2[MAXN],c[MAXN];
    struct N{
        ll a,b;
    }p[1005];
    bool cmp(N x,N y)
    {
        return x.a*x.b<y.a*y.b;
    }
    void chu(ll a[],ll b)
    {
        ll x=0;
        c[0]=a[0];
        for(ll i=a[0];i>0;i--)//倒序存储,正序除 
        {
            c[i]=(x*10000+a[i])/b;
            x=(x*10000+a[i])%b;
        }
        while(c[c[0]]==0&&c[0]>0)c[0]--;
    }
    void ch(ll a[],ll b)
    {
        ll x=0;
        for(ll i=1;i<=a[0];i++)//倒序乘 
        {
            a[i]*=b;a[i]+=x;
            x=a[i]/10000;
            a[i]%=10000;
        }
        while(x)a[0]++,a[a[0]]=x%10000,x/=10000;
    }
    int com(ll a[],ll b[])
    {
        if(a[0]>b[0])return 1;
        if(a[0]<b[0])return -1;
        for(ll i=a[0];i;i--)//倒序! 
            if(a[i]>b[i])return 1;
        return 0;
    }
    void print(ll a[])
    {
    //    if(a[a[0]]==0)//?
    //    {
    //        printf("1");
    //        return;
    //    }
        printf("%lld",a[a[0]]);
        for(ll i=a[0]-1;i>0;i--)
        {
            printf("%lld",a[i]/1000);
            a[i]%=1000;
            printf("%lld",a[i]/100);
            a[i]%=100;
            printf("%lld",a[i]/10);
            a[i]%=10;
            printf("%lld",a[i]);
        }
    }
    int main()
    {
        scanf("%lld%lld%lld",&n,&ka,&kb);
        for(ll i=1;i<=n;i++)
            scanf("%d%d",&p[i].a,&p[i].b);
        sort(p+1,p+n+1,cmp);
        tmp[0]=1;tmp[1]=ka;//压位 
        for(ll i=1;i<=n;i++)
        {
            memcpy(tmp2,tmp,sizeof tmp);
            memset(c,0,sizeof c);
            chu(tmp2,p[i].b);
            if(com(c,ans)>0)memcpy(ans,c,sizeof c);//必须>0,否则-1也会被算! 
            ch(tmp,p[i].a);
        }
        print(ans);
        return 0;
    }

    这个运行起来有点慢,有些地方写得不够好,下面有一篇运行很快的代码,可以比较看看提速的方法。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int INF=10000;
    typedef long long ll;
    ll n,gb,ljc[1005],max,tmp[1005],ans[1005];
    char tp[5];
    struct Node{
        ll a,b,w;
    }r[1005];
    bool cmp(Node x,Node y)
    {
        return x.w<y.w;
    }
    void chu(ll b)
    {
        ll x=0;
        tmp[0]=ljc[0];
        for(ll i=ljc[0];i;i--)
        {
            ll s=ljc[i]+x*INF;
            tmp[i]=s/b;
            x=s%b;
        }
        while(!tmp[tmp[0]]&&tmp[0]>1)tmp[0]--;
    }
    bool comp(ll ans[],ll b[])
    {
        if(ans[0]>b[0])return 0;
        if(ans[0]<b[0])return 1;
        for(ll i=ans[0];i;i--)
        {
            if(ans[i]>b[i])return 0;
            if(ans[i]<b[i])return 1;
        }
        return 0;
    }
    void mul(ll a)
    {
        ll x=0;
        for(ll i=1;i<=ljc[0];i++)
        {
            ll s=ljc[i]*a+x;
            x=s/INF;
            ljc[i]=s%INF;
        }
        if(x)ljc[0]++,ljc[ljc[0]]=x;//至多进一位 
    }
    int main()
    {
        scanf("%lld%lld%lld",&n,&ljc[1],&gb);
        ljc[0]=1;
        for(ll i=1;i<=n;i++)
        {
            scanf("%lld%lld",&r[i].a,&r[i].b);
            r[i].w=r[i].a*r[i].b;
        }
        sort(r+1,r+n+1,cmp);
        for(ll i=1;i<=n;i++)
        {
            memset(tmp,0,sizeof tmp);
            chu(r[i].b);
            if(comp(ans,tmp))memcpy(ans,tmp,sizeof tmp);
            mul(r[i].a);
        }
        printf("%lld",ans[ans[0]]);
        for(ll i=ans[0]-1;i;i--)
        {
            printf("%lld",ans[i]/1000);
            printf("%lld",ans[i]/100%10);
            printf("%lld",ans[i]/10%10);
            printf("%lld",ans[i]%10);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    date之Hi时间的思考
    空循环比较 for foreach array_map array_walk
    ECSHOP 数据库结构说明 (适用版本v2.7.3)
    自定义写入读出文件作为存储的函数
    session 重写进入redis测试
    单独批次性任务采用MySQL定时器解决需求
    php 接收 Content-Type 是 application/json的请求数据
    centos 6.4 mysql rpm 离线安装【备忘】
    solr单机版安装与基本部署
    vim&vi在编辑的时候突然卡死,不接收输入问题的解决
  • 原文地址:https://www.cnblogs.com/Zinn/p/8531302.html
Copyright © 2011-2022 走看看