NOIP 2012 国王游戏

33 篇文章 0 订阅
13 篇文章 0 订阅

评测传送

贪心,按照a*b升序排序,如果相同,则a小的在前。

解释一下:
排序的时候,我们假设前面的已经排好了,而且当前这两个为a1,b1,a2,b2
那么 这两个怎样排对后面的影响都是一样的,所以只需看这两个大臣的顺序对这两个的影响,
我们肯定是

returnka1/b2<ka2/b1
k表示前面的左手乘积,化简一下就是
returna1b1<a2b2

如果直接上单纯的计算会炸掉,60分。

需要加高精。

我压了4位。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<ctime>
#include<queue>
#define LL long long
const long long P=10000;
using namespace std;
int n;
struct H{
    LL a,b,c;
}p[1009];
LL ak,bk,ans;
bool cmp(H x,H y)
{
    if(x.c==y.c) return x.b<y.b;
    return x.c<y.c;
}
int s1[1009],s2[1009],s3[1009],len,len2,len3;
void MAX()//比较大小 
{
    int f=0;
    if(len2<len3) return;
    if(len2==len3)
    {
        for(int i=len2;i>=1;i--)
        {
            if(s2[i]<s3[i])return;
            if(s2[i]>s3[i]){f=1;break;}
        }
    }
    if(len2>len3) f=1;
    if(f) 
    {
        for(int i=1;i<=len2;i++) s3[i]=s2[i];
        len3=len2;
    }
}
int main()
{
    freopen("game.in","r",stdin);
    scanf("%d%lld%lld",&n,&ak,&bk);
    for(int i=1;i<=n;i++) scanf("%lld%lld",&p[i].a,&p[i].b),p[i].c=p[i].a*p[i].b;
    sort(p+1,p+n+1,cmp);
    p[0].a=ak;
    len=1; 
    s1[1]=1;
    for(int i=0;i<=n-1;i++)//高精乘p[0~n-1].a; 
    {
        LL k=p[i].a;//cout<<k<<endl;
        for(int j=1;j<=len;j++)
        {
            s1[j]=s1[j]*k;
        }
        for(int j=1;j<=len;j++)
        {
            s1[j+1]+=s1[j]/P;
            s1[j]%=P;
        }
        if(s1[len+1]) len++;

        k=p[i+1].b;
        for(int j=1;j<=len;j++) s2[j]=s1[j];
        for(int j=len;j>=1;j--)
        {
            s2[j-1]+=s2[j]%k*P;
            s2[j]/=k;
        }
        len2=len;
        while(!s2[len2]&&len2>1) len2--;
        MAX();
    }
    while(!s3[len3]&&len3>1) len3--;
    printf("%d",s3[len3]);
    for(int i=len3-1;i>=1;i--)
    printf("%04d",s3[i]);
    //printf("\ntime:%.2lf",clock()/1000.0);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值