将大臣手上数字的乘积升序排序 , 就是最优排队方案 证明: 如果 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 }