数列极差和大数模板

引用百度上的大数模板

  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[n]);   //c[n]=c[i-1]*c[i]
196             Add(c[n],one,t);         //t=c[n]+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[n]);
220             Add(c[n],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

 

posted @ 2014-11-18 14:50  煎饼馃子  阅读(155)  评论(0编辑  收藏  举报