luogu P1080 国王游戏 排序 高精度

将大臣手上数字的乘积升序排序 , 就是最优排队方案 证明: 如果 mul * a1 /b2 > mul * a2 /b1 ==> a1 * b1 > a2 * b2 那么交换1和2,可以使最大值更小(最大值并不一定是最后一个大臣 , 只是说明相邻两个大臣是否需要交换) 比较乘积的时候,如果相等,就比较右手上的数,小的放前面。 就相当于我们按照这个比较规则排序一次。然后配合高精度即可。

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 using namespace std;
  5 struct peo
  6 {
  7     int l,r,m;
  8     friend bool operator < (peo a,peo b)
  9     {
 10         if (a.m == b.m)
 11             return a.r < b.r;
 12         return a.m < b.m;
 13     }
 14 } c[1100];
 15 int ans,len,hloc,maxl,n;
 16 int a[10000],a2[10000],d[10000],maxx[10000];
 17 char str[10000];
 18 
 19 void mul(int a[],int b)
 20 {
 21     memset(d,0,sizeof(d));
 22     for(int i = 1; i <= len; i++)
 23         d[i] = a[i] * b;
 24     for(int i = 1; i <= len; i++)
 25         if (d[i] / 10)
 26         {
 27             d[i + 1] += d[i] / 10;
 28             d[i] %= 10;
 29         }
 30     if(d[len+1])
 31         len++;
 32     while(d[len] / 10)
 33     {
 34         d[len + 1] += d[len] / 10;
 35         d[len] %= 10;
 36         len++;
 37     }
 38     for(int i = 1; i <= len; i++)
 39         a[i] = d[i];
 40 }
 41 
 42 void div(int a[],int b)
 43 {
 44     memset(d,0,sizeof(d));
 45     int x = 0;
 46     for(int i = 1;i <= len;i++)
 47     {
 48         d[i] = (a[i] + x * 10) / b;
 49         x = (a[i] + x * 10) % b;
 50     }
 51     bool hav = 0;
 52     for (int i = 1;i <= len;i++) 
 53         if (d[i])
 54         {
 55             hav = 1;
 56             break;
 57         }
 58     if (hav)
 59     {
 60         int i = 1;
 61         while (d[i] == 0)
 62             i++;
 63         hloc = i;//最高为位置 
 64         for (;i <= len;i++)
 65         {
 66             if (d[i] > maxx[i] && len - hloc + 1 == maxl || len - hloc + 1 > maxl)
 67             {
 68                 for (int j = hloc;j <= len;j++) maxx[j] = d[j];
 69                 maxl = len - hloc + 1;
 70                 break;
 71             }
 72             if (maxl > len - hloc + 1 || d[i] < maxx[i]) 
 73                 break;
 74         }
 75     }
 76 }
 77 int main()
 78 {
 79     scanf("%d",&n);
 80     for (int i = 0; i <= n; i++)
 81     {
 82         scanf("%d%d",&c[i].l,&c[i].r);
 83         c[i].m = c[i].l * c[i].r;
 84     }
 85     sort(c + 1,c + n + 1);
 86     for(int i = 0; c[0].l; i++)
 87     {
 88         str[i] = c[0].l % 10 + '0';
 89         c[0].l /= 10;
 90     }
 91     len = strlen(str);
 92     for (int i = 1; i <= len; i++)
 93         a[i] = str[i - 1] - '0';
 94     for (int i = 1; i <= len; i++)
 95         a2[i] = str[len - i] - '0';
 96     for (int i = 1; i <= n; i++)
 97     {
 98         //注意乘法从低位算到高位,除法从高位算到低位,所以一正一反。 
 99         div(a2,c[i].r);//算之前的乘积,除当前右手。 
100         mul(a,c[i].l); //把当前左手乘进去。 
101         for (int j = 1; j <= len;j++)
102             a2[j] = a[len - j + 1];
103     }
104     for (int i = hloc; i <= maxl + hloc - 1; i++)
105         printf("%d",maxx[i]);
106     return 0;
107 }

 

 

 

posted @ 2019-09-07 19:19  IAT14  阅读(318)  评论(0编辑  收藏  举报