数列极差和大数模板
2017-11-08 14:13
351 查看
引用百度上的大数模板
View Code
1 /***************************************************************************** 2 无符号大整数类,包括了*和+法,类可以用小整数或者字符串输入,储存方式为:下标大的位储存高位 3 字符串输入时,必须手动去除前面多余的0 4 加法函数和乘法函数中,前2个参数为输入,最后个返回,参数中,前两个可以相同,但是最后个不能和前面的重复 5 减法函数中,被减数a必须大于减数b,返回到a中,要算c=a-b可以用Cpy,Sub两个函数合用 6 ******************************************************************************/ 7 #include<stdio.h> 8 #include<stdlib.h> 9 #include<string.h> 10 #include <algorithm> 11 #include <iostream> 12 using namespace std; 13 14 const int OneNode = 1000000 ;//一位里不能超过OneNode 15 const int NodeLen = 6 ;//一位储存NodeLen位,和OneNode必须同时更改,输出部分格式必须跟随这里!!! 16 const int Numtmax = 4005 ;//储存位数限制,真实位数为Numtmax*6 17 struct BigNum 18 { 19 unsigned num[Numtmax] ;//高位 对 下标大位 20 unsigned numlen ; 21 void set(unsigned sm=0){ num[0] = sm ; numlen = 1; }//sm<OneNode 22 void set(char *string , int strlen) 23 { 24 numlen = (strlen-1) / NodeLen + 1 ; 25 memset (num , 0 , sizeof(unsigned)*numlen ); 26 int temp , i ; 27 for( i=strlen-1 ; i>=0 ; i-- ) 28 { 29 temp = i / NodeLen ; 30 num[temp] = num[temp]*10 + string[strlen-1-i]-'0' ; 31 } 32 } 33 void print() 34 { 35 printf("%d",num[numlen-1]); 36 int i = numlen-1; 37 while( i ) 38 { 39 i--; 40 printf("%06d",num[i]); 41 } 42 printf("\n"); 43 } 44 }; 45 46 void Add(BigNum &a,BigNum &b,BigNum &c) // a+b ->c 47 { 48 unsigned lentmax = a.numlen>b.numlen?a.numlen:b.numlen; 49 c.numlen = lentmax; 50 unsigned i,carry=0; 51 for ( i=0 ; i<lentmax ; i++ ) 52 { 53 c.num[i] = carry ; 54 if( a.numlen > i ) 55 c.num[i]+= a.num[i]; 56 if( b.numlen > i ) 57 c.num[i]+= b.num[i]; 58 carry = c.num[i] / OneNode ; 59 c.num[i] %= OneNode ; 60 } 61 if ( carry ) 62 { 63 c.num[i] = carry ; 64 c.numlen ++; 65 } 66 } 67 68 void Mul(BigNum &a,BigNum &b,BigNum &c) // a*b ->c 69 { 70 unsigned carry = 0 , lentmax = a.numlen+b.numlen-1 ,i,j ; 71 unsigned __int64 temp ; 72 c.numlen = lentmax; 73 for ( i=0 ; i<lentmax ; i++ ) 74 { 75 temp = carry ; 76 for ( j=0 ; j<a.numlen ; j++ ) 77 { 78 if ( i<j ) 79 break; 80 if ( i-j >= b.numlen ) 81 { 82 j = i-b.numlen ; 83 continue; 84 } 85 temp += (unsigned __int64)a.num[j] * b.num[i-j] ; 86 } 87 carry = temp / OneNode ; 88 c.num[i] = temp % OneNode ; 89 } 90 while(carry) 91 { 92 c.num[c.numlen++] = carry % OneNode ; 93 carry/=OneNode; 94 } 95 while(c.numlen>1&&!c.num[c.numlen-1]) 96 c.numlen--; 97 } 98 99 int Cmp(BigNum &a,BigNum &b) //a>b --> 1 , < --> -1 ,== --> 0 100 { 101 if( a.numlen>b.numlen ) 102 return 1; 103 if( a.numlen<b.numlen ) 104 return -1; 105 int len = a.numlen ; 106 while(len) 107 { 108 len --; 109 if(a.num[len]>b.num[len])return 1; 110 if(a.num[len]<b.num[len])return -1; 111 } 112 return 0; 113 } 114 115 void Cpy(BigNum &a , BigNum &b) //b-->a 116 { 117 a.numlen=b.numlen; 118 memcpy(a.num,b.num,sizeof(unsigned)*b.numlen); 119 } 120 121 void Sub( BigNum &a , BigNum b ) //a-b -> a , a>=b 122 { 123 unsigned i = 0; 124 unsigned carry = 0 ; 125 for ( i=0 ; i<b.numlen ; i++ ) 126 { 127 a.num[i] = a.num[i]-carry-b.num[i]; 128 if(a.num[i]>OneNode) //有进位(由于相减如果小于0会向上溢出) 129 { 130 a.num[i] += OneNode ; 131 carry = 1; 132 } 133 else carry = 0; 134 } 135 while(carry) 136 { 137 if(a.num[i]) 138 { 139 a.num[i] --; 140 carry = 0; 141 } 142 else 143 { 144 a.num[i] = OneNode-1; 145 i++; 146 } 147 } 148 while(a.num[a.numlen-1]==0 && a.numlen!=1) 149 { 150 a.numlen --; 151 } 152 } 153 void Div(BigNum &a,int b,int &l) // a/=b -> 余数l 154 { 155 int carry=0; 156 int i; 157 for(i=a.numlen-1;i>=0;i--) 158 { 159 a.num[i]+=carry*OneNode; 160 carry=a.num[i]%b; 161 a.num[i]/=b; 162 } 163 if(a.numlen>1&&!a.num[a.numlen-1])a.numlen--; 164 l=carry; 165 } 166 /********以上是模板部分**********/ 167 168 int n; 169 int a[2010],b[2010]; 170 BigNum c[2010],t,tmax,tmin,ans,one; 171 172 bool cmp (const int a, const int b) 173 { 174 return a > b; 175 } 176 177 int main() 178 { 179 one.set(1); 180 while(scanf("%d",&n)!=EOF) 181 { 182 int i,j; 183 for(i=0;i<n;++i) 184 { 185 scanf("%d",&a[i]); 186 b[i]=a[i]; 187 } 188 sort(a,a+n); //计算tmax 189 for(i=0;i<n;++i) 190 { 191 c[i].set(a[i]); 192 } 193 for(i=1;i<n;i++) 194 { 195 Mul(c[i-1],c[i],c ); //c =c[i-1]*c[i] 196 Add(c ,one,t); //t=c +1; 197 for(j=i+1;j<n;++j) 198 { 199 if(Cmp(t,c[j])<=0) //t<=c[j]; 200 { 201 break; 202 } 203 else 204 { 205 Cpy(c[j-1],c[j]); //c[j-1]=c[j] 206 } 207 } 208 Cpy(c[j-1],t); 209 } 210 Cpy(tmax,c[n-1]); 211 212 sort(b,b+n,cmp); //计算tmin 213 for(i=0;i<n;++i) 214 { 215 c[i].set(b[i]); 216 } 217 for(i=1;i<n;i++) 218 { 219 Mul(c[i-1],c[i],c ); 220 Add(c ,one,t); 221 for(j=i+1;j<n;++j) 222 { 223 if(Cmp(t,c[j])>=0) //t<=c[j] 224 { 225 break; 226 } 227 else 228 { 229 Cpy(c[j-1],c[j]); 230 } 231 } 232 Cpy(c[j-1],t); 233 } 234 Cpy(tmin,c[n-1]);//tmin=c[n-1]; 235 236 Sub(tmax,tmin); //tmax=tmax-tmin; 237 int cnt,v; 238 cnt=0; 239 v=tmax.num[tmax.numlen-1]; 240 do 241 { 242 cnt++; 243 v/=10; 244 }while(v); 245 if(tmax.numlen-2>=0) 246 cnt+=(tmax.numlen-1)*6; 247 248 printf("%d\n",cnt); 249 tmax.print(); 250 } 251 return 0; 252 }
View Code
相关文章推荐
- 数列极差和大数模板
- 模板 大数的斐波那契额数列(可以用来求大数加法)
- HDU1134——Game of Connections (大数乘法,除法)+ (卡特兰数列)
- C++大数模板
- [BZOJ2179]-大数乘法-FFT模板
- 模板整理---大数模板
- 数列极差问题(贪心) 求数据(一直Wrong)
- [Codeforces 903 D. Almost Difference]树状数组+大数模板
- 【NOI 2005】【JZOJ 2413】维护数列 平衡树操作模板题
- 大数模板
- 【模板】c++ 大数模板
- 容斥原理 + 大数模板(跳蚤 POJ - 1091)
- 【模板】逆序数,java大数,2014 Multi-University Training Contest 5,
- C++大数模板
- HDU5351大数模板加斐波那契
- poj 1811 随机素数和大数分解(模板)
- 贪心算法-数列极差问题-JAVA
- 大数斐波那契数列
- 大数乘法 poj 2389 ||大数乘法 hdu1402 FFT模板
- hdu-4344-Mark the Rope-大数分解质因子模板