[题解]UVA10700 Camel trading
链接:http://vjudge.net/problem/viewProblem.action?id=21358
描述:给出一个算式,算式里面有加法和乘法,可以任意添加括号从而改变计算顺序。求可能得到的最大结果和最小结果。
思路:贪心
求最大结果:尽量让乘数最大,所以先把所有加法做完,然后再做乘法。
求最小结果:尽量让乘数最小,所以就优先做乘法,这样乘数就只是'*'相邻的两个数。
我的实现(高精度版):
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 #define MaxLen 100 6 #define hp_Len 100 7 typedef int hp[hp_Len]; 8 char str[MaxLen]; 9 int n,Len; 10 hp ans_Max,ans_Min; 11 void hp_Add(hp a,hp b,hp &ans) 12 { 13 hp c; 14 int i,len=max(a[0],b[0])+3; 15 memset(c,0,sizeof(c)); 16 if(a[0]>=b[0]) 17 { 18 for(i=1;i<=b[0];++i) 19 { 20 c[i]+=a[i]+b[i]; 21 c[i+1]+=c[i]/10; 22 c[i]%=10; 23 } 24 for(;i<=a[0];++i) 25 { 26 c[i]+=a[i]; 27 c[i+1]+=c[i]/10; 28 c[i]%=10; 29 } 30 } 31 else 32 { 33 for(i=1;i<=a[0];++i) 34 { 35 c[i]+=a[i]+b[i]; 36 c[i+1]+=c[i]/10; 37 c[i]%=10; 38 } 39 for(;i<=b[0];++i) 40 { 41 c[i]+=b[i]; 42 c[i+1]+=c[i]/10; 43 c[i]%=10; 44 } 45 } 46 while(len>1&&c[len]==0) 47 len--; 48 c[0]=len; 49 memcpy(ans,c,sizeof(c)); 50 } 51 void hp_Mul(hp a,hp b,hp &ans) 52 { 53 hp c; 54 int i,j,len=a[0]+b[0]+5; 55 memset(c,0,sizeof(c)); 56 for(i=1;i<=a[0];++i) 57 for(j=1;j<=b[0];++j) 58 c[i+j-1]+=(a[i]*b[j]); 59 for(i=1;i<=len;++i) 60 { 61 c[i+1]+=c[i]/10; 62 c[i]%=10; 63 } 64 while(len>1&&c[len]==0) 65 len--; 66 c[0]=len; 67 memcpy(ans,c,sizeof(c)); 68 } 69 inline void Put_in_hp(hp &ans,int a) 70 { 71 hp c; 72 memset(c,0,sizeof(c)); 73 while(a) 74 { 75 c[0]++; 76 c[c[0]]=a%10; 77 a/=10; 78 } 79 memcpy(ans,c,sizeof(c)); 80 } 81 void Get_Max() 82 { 83 Len+=2; 84 str[Len-2]='*';str[Len-1]='1'; 85 int i,tmp=0; 86 hp Pre,Cur; 87 Pre[0]=1;Pre[1]=0;//Pre=0; 88 ans_Max[0]=1;ans_Max[1]=1;//ans_Max=1; 89 for(i=0;i<Len;++i) 90 { 91 if('0'<=str[i]&&str[i]<='9') 92 { 93 tmp=tmp*10+str[i]-'0'; 94 continue; 95 } 96 Put_in_hp(Cur,tmp); 97 hp_Add(Pre,Cur,Pre);//Pre+=Cur; 98 if(str[i]=='*') 99 { 100 hp_Mul(ans_Max,Pre,ans_Max);//ans_Max*=Pre; 101 Pre[0]=1;Pre[1]=0;//Pre=0; 102 } 103 tmp=0; 104 } 105 } 106 void Get_Min() 107 { 108 str[Len-2]='+';str[Len-1]='0'; 109 int i,tmp=0; 110 hp Pre,Cur; 111 Pre[0]=1;Pre[1]=1;//Pre=1; 112 ans_Min[0]=1;ans_Min[1]=0;//ans_Min=0; 113 for(i=0;i<Len;++i) 114 { 115 if('0'<=str[i]&&str[i]<='9') 116 { 117 tmp=tmp*10+str[i]-'0'; 118 continue; 119 } 120 Put_in_hp(Cur,tmp); 121 hp_Mul(Pre,Cur,Pre);//Pre*=Cur; 122 if(str[i]=='+') 123 { 124 hp_Add(ans_Min,Pre,ans_Min);//ans_Min+=Pre; 125 Pre[0]=1;Pre[1]=1;//Pre=1; 126 } 127 tmp=0; 128 } 129 } 130 void hp_Print(hp c) 131 { 132 int i; 133 for(i=c[0];i>=1;--i) 134 printf("%d",c[i]); 135 } 136 inline void Print() 137 { 138 printf("The maximum and minimum are "); 139 hp_Print(ans_Max); 140 printf(" and "); 141 hp_Print(ans_Min); 142 printf(".\n"); 143 } 144 int main() 145 { 146 scanf("%d",&n); 147 for(int i=1;i<=n;++i) 148 { 149 scanf("%s",str); 150 Len=strlen(str); 151 Get_Max(); 152 Get_Min(); 153 Print(); 154 } 155 return 0; 156 }
实现二(long long版,之前因为%I64d的原因WA了,改成%lld就AC了):
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 #define MaxLen 100 6 char str[MaxLen]; 7 typedef long long llt; 8 llt n,Len,ans_Max,ans_Min; 9 void Get_Max() 10 { 11 Len+=2; 12 str[Len-2]='*';str[Len-1]='1'; 13 llt i; 14 llt Pre=0,Cur=0; 15 ans_Max=1; 16 for(i=0;i<Len;++i) 17 { 18 if('0'<=str[i]&&str[i]<='9') 19 { 20 Cur=Cur*10+str[i]-'0'; 21 continue; 22 } 23 Pre+=Cur; 24 if(str[i]=='*') 25 { 26 ans_Max*=Pre; 27 Pre=0; 28 } 29 Cur=0; 30 } 31 } 32 void Get_Min() 33 { 34 str[Len-2]='+';str[Len-1]='0'; 35 llt i; 36 llt Pre=1,Cur=0; 37 ans_Min=0; 38 for(i=0;i<Len;++i) 39 { 40 if('0'<=str[i]&&str[i]<='9') 41 { 42 Cur=Cur*10+str[i]-'0'; 43 continue; 44 } 45 Pre*=Cur; 46 if(str[i]=='+') 47 { 48 ans_Min+=Pre; 49 Pre=1; 50 } 51 Cur=0; 52 } 53 } 54 int main() 55 { 56 scanf("%I64d",&n); 57 for(int i=1;i<=n;++i) 58 { 59 scanf("%s",str); 60 Len=strlen(str); 61 Get_Max(); 62 Get_Min(); 63 printf("The maximum and minimum are %I64d and %I64d.\n",ans_Max,ans_Min); 64 } 65 return 0; 66 }