zoukankan      html  css  js  c++  java
  • luoguP1080 国王游戏 (贪心+高精度)

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

    参考:https://www.luogu.org/problemnew/solution/P1080

    思路:这道题的考点是贪心和高精度。

    贪心部分:

    …(设这一段乘积为X1)…(设这一段乘积为Y2)
    L1 R1
    …(设这一段乘积为X2) …(设这一段乘积为Y2)
    L2 R2
    由上面这张表格可以知道这样的情况时:

    第一个人所得的金币数为X1/R1;

    第二个人所得的金币数为X1×L1×X2/R2;

    所以最小值为 max(X1/R1, X1×L1×X2/R2);


    然后交换两个人的位置


    …(这一段乘积为X1)…(这一段乘积为Y2)
    L2 R2
    …(这一段乘积为X2) …(这一段乘积为Y2)
    L1 R1
    由上面这张表格可以知道交换后的情况时:

    第一个人所得的金币数为X1×L2×X2/R1;

    第二个人所得的金币数为X1/R2;

    所以此时最小值为max(X1×L2×X2/R1, X1/R2);

    综合上面两种情况:

    如果变换之前的情况要优于变换之后的情况,那么

    max(X1/R1, X1×L1×X2/R2) < max(X1×L2×X2/R1, X1/R2);

    而X1/R1 < X1×L2×X2/R1 恒成立;

    X1×L1×X2/R2 > X1/R2;

    所以上述条件成立时

    必须有X1×L1×X2/R2 < X1×L2×X2/R1 恒成立;所以化简可得 L1×R1 < L2×R2恒成立。

    综上,很容易想到Li×Ri越大的应该排在越后面,所以对数据排个序就行。

    另外就是高精度,数据最大可能达到10的4000次方,故需要使用高精度,这种高精度方法是参考的别人的,比较方便巧妙,不需要花费时间进行整数与字符串的转化。

    代码如下:

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 
     5 struct node{
     6     int a,b;
     7     bool operator < (const node& other) const{
     8         return a*b<other.a*other.b;
     9     }
    10 }dat[1005];
    11 
    12 int n,in=1;
    13 int hp[4005];
    14 
    15 void mul(int k){
    16     for(int i=1;i<=in;i++)
    17         hp[i]*=dat[k].a;
    18     for(int i=1;i<=in;i++){
    19         hp[i+1]+=hp[i]/10;
    20         hp[i]%=10;
    21     }
    22     in++;
    23     while(hp[in]>9){
    24         hp[in+1]=hp[in]/10;
    25         hp[in]%=10;
    26         in++;
    27     }
    28     if(hp[in]==0)
    29         in--;
    30 }
    31 
    32 void div(){
    33     for(int i=in;i>=1;i--){
    34         hp[i-1]+=((hp[i]%dat[n].b)*10);
    35         hp[i]/=dat[n].b;    
    36     }
    37     while(hp[in]==0)
    38         in--;
    39 }
    40 
    41 int main(){
    42     scanf("%d",&n);
    43     for(int i=0;i<=n;i++)
    44         scanf("%d%d",&dat[i].a,&dat[i].b);
    45     sort(dat+1,dat+n+1);
    46     hp[1]=dat[0].a;
    47     for(int i=1;i<n;i++)
    48         mul(i);
    49     div();
    50     if(in==0)
    51         printf("1");  //最终数组长度为0,由于每个人都会得到赏金,故每个人最多分到1赏金
    52     else
    53         for(int i=in;i>=1;i--)
    54             printf("%d",hp[i]);
    55     printf("
    ");
    56     return 0;
    57 }
  • 相关阅读:
    进程提权小结
    进程工作集WorkingSet (PSAPI 01)
    GetSystemInfo 和 GlobalMemoryStatus获取系统信息,内存信息
    C++11智能指针 share_ptr,unique_ptr,weak_ptr用法
    结构体及类对象的内存对齐
    菱形继承问题和虚继承
    TLS反调试
    获取程序目录,模块路径
    docker install for centos7
    docker镜像与容器概念
  • 原文地址:https://www.cnblogs.com/FrankChen831X/p/10348183.html
Copyright © 2011-2022 走看看