【noip2012 T2】 国王的游戏

本文深入解析了一道2012年的神奇贪心算法题目,通过具体的代码实现介绍了如何对区间乘积进行排序并求解最大值。文章详细展示了使用C++实现的高精度计算过程,包括乘法和除法运算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

神奇的 2012 好多 神题。

这题就是 个 神奇的 贪心

这咋整 马神说:
考试时会证就证,不会就算了。

考完也不会证,贪心的策略就是 a.l*a.r 从小到大排序

嗯 但是很麻烦的是 mdzz
要写高精。。

#include<cstdio>
#include<algorithm>
#include<cstring>
//by mars_ch
using namespace std;
struct data
{
    int l,r;
}p[10005];
char str[100005];
int len,pos,maxlen;
int a[50005],b[50005],d[50005],maxx[50005];
bool cmp(data a,data b)
{
    return a.l*a.r<b.l*b.r;
 } 
 void cheng(int c[],int x)
 {
    memset(d,0,sizeof(d));
    for(int i=1;i<=len;i++)
    {
        d[i]=c[i]*x;
    }
    for(int i=1;i<=len;i++)
    {
        if(d[i]/10)
        {
            d[i+1]+=d[i]/10;
            d[i]=d[i]%10;
        }
    }
    while(d[len+1]) len++;
    while(d[len]/10)
    {
        d[len+1]+=d[len]/10;
        d[len]=d[len]%10;
        len++;
    }
    for(int i=1;i<=len;i++)
    {
        c[i]=d[i];
    }
 }
void chu(int c[],int x)
{
    memset(d,0,sizeof(d));
    int m=0;
    for(int i=1;i<=len;i++)
    {
        d[i]=(c[i]+m*10)/x;
        m=(c[i]+m*10)%x;
    }
    int pd=0;
    for(int i=1;i<=len;i++)
    {
        if(d[i])
        {
            pd=1;
            break;
        }
    }
    if(pd)
    {
        int i=1;
        while(!d[i]) i++;
        pos=i;
        for(int j=pos;j<=len;j++)
        {
            if((d[j]>=maxx[j]&&maxlen==len-pos+1) || maxlen<len-pos+1)
            {
                for(int k=1;k<=len;k++)
                {
                    maxx[k]=d[k];
                }
                maxlen=len-pos+1;
                break;
            }
            if(maxlen>len-pos+1 || d[j]<maxx[j]) break;
        }
    }

} 
int main()
{
    int n;
    scanf("%d",&n); 
    for(int i=0;i<=n;i++)
    {
        scanf("%d%d",&p[i].l,&p[i].r);
    }
    sort(p+1,p+n+1,cmp);
    while(p[0].l)
    {
        str[++len]=p[0].l%10+'0';
        p[0].l/=10;
    }
    for(int i=1;i<=len;i++)
    {
        a[i]=str[i]-'0';
        b[i]=str[len-i+1]-'0';
    }
    for(int i=1;i<=n;i++)
    {
        chu(b,p[i].r);
        cheng(a,p[i].l);
        for(int i=1;i<=len;i++)
        {
            b[i]=a[len-i+1];
        }
    }
    int f=1;
    while(maxx[f]==0) f++;
    for(int i=f;i<=maxlen+f-1;i++)
    {
        printf("%d",maxx[i]);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值