码迷,mamicode.com
首页 > 其他好文 > 详细

超长数字串

时间:2017-11-10 13:48:48      阅读:224      评论:0      收藏:0      [点我收藏+]

标签:alt   +=   数组   false   2-2   idt   长度   final   oid   

这个序列开始是: 1234567891011121314... 我们叫序列 S。然后 S[1] = 1, S[2] = 2, ... , S[10] = 1, S[11] = 0, ... , 以此类推。 
George 现有一个数字系列 A ,他想知道在S中最早出现的位置。帮助他解决这个难题。

 技术分享

 

  1 #include<iostream>
  2 #include<string>
  3 using namespace std;
  4 
  5 string s;
  6 
  7 int a[300][305]={0};
  8 int flag=1;
  9 int kk=0;  
 10 //x[0~(n-m)]=s[n~m] 
 11 int getNum(int x[],int m,int n){
 12     for(int i=n;i>=m;--i)
 13     x[n-i]=s[i]-0;
 14     }
 15 void print(int x[]){
 16      int i;
 17      for(i=300;i>=0;i--)
 18      if(x[i]!=0) break;
 19      while(i>=0) cout<<x[i--];
 20      cout<<endl;
 21      }
 22 //打印补齐后的第一个数 
 23 void print(int l){
 24      for(int i=1;i<=l;++i)
 25      cout<<s[i];
 26      cout<<endl;
 27      }
 28 //x=x+t 
 29 void add(int x[],int t){
 30      x[0]+=t;
 31      int i=0;
 32      while(x[i]>=10)
 33      {
 34        x[i+1]+=x[i]/10;
 35        x[i]%=10;
 36        i++;
 37                    }
 38      }
 39 //x=x-t 
 40 void sub(int x[],int t){
 41      x[0]-=t;
 42      int i=0;
 43      while(x[i]<0)
 44      {
 45        x[i]+=10;
 46        x[i-1]-=1;
 47        i++;
 48                    }
 49      }
 50 
 51 //前后数位数都足够 
 52 bool check(int i,int j,int m,int n){
 53      if(s[i]==0||s[m]==0) return false;
 54      int x[305]={0},y[305]={0};
 55      getNum(x,i,j);
 56      getNum(y,m,n);
 57      add(x,1);
 58      for(int d=0;d<=300;d++)
 59      if(x[d]!=y[d]) return false;
 60      return true;
 61      }
 62 
 63 
 64 //后一个数位数不够,只判断后一个数与前一个数对应的位数是否相等 
 65 bool tailCheck(int i,int j,int m,int n){
 66      if(s[i]==0||s[m]==0) return false;
 67      int x[305]={0},y[305]={0};
 68      getNum(x,i,j);
 69      getNum(y,m,n);
 70      add(x,1);
 71      int d1=300,d2=300;
 72      while(x[d1]==0) d1--;
 73      while(y[d2]==0) d2--;
 74      while(d1>=0&&d2>=0)
 75      {
 76         if(x[d1]!=y[d2]) return false;        
 77         d1--;d2--;        
 78                         }
 79      return true;
 80      }
 81 
 82 
 83 //判断第一个数的位数是否能为l 
 84 bool find(int l){
 85      int i,j,m,n;
 86      i=1;j=l;m=j+1;n=j+l;
 87      if(j==s.size()-1&&s[i]==0) return false;
 88      while(true)
 89      {
 90        if(j>=s.size()-1) return true;
 91        if(n>=s.size()-1) {n=s.size()-1;if(!tailCheck(i,j,m,n)) return false;}
 92        else if(!check(i,j,m,n))  //前一个数和后一个数的位数都为l 
 93        {
 94          if(!check(i,j,m,n+1))   //前一个数位数为l,后一个数位数为l+1              
 95          return false;              
 96          else {l+=1;n+=1;}  
 97                             }
 98        i=m;
 99        j=n;
100        m=j+1;
101        n=j+l; 
102              
103              }
104      
105      return true;
106      }
107 
108 void Multiply(int x[],int y){
109      for(int i=0;i<=300;++i)
110      x[i]*=y;
111      
112      for(int i=0;i<=300;++i)
113      if(x[i]>9)
114      {
115         x[i+1]+=x[i]/10;
116         x[i]%=10;
117                   }
118      }
119 void add(int x[],int y[]){
120      for(int i=0;i<=300;++i)
121      x[i]+=y[i];
122      int i=0;
123      while(x[i]>=10)
124      {
125        x[i+1]+=x[i]/10;
126        x[i]%=10;
127        i++;
128                    }
129      }
130 
131 bool comp(int x[],int y[]){
132      for(int i=300;i>=0;--i)
133      if(x[i]<y[i]) return true;
134      else if(x[i]>y[i]) return false;
135      return false;
136      }
137 
138 void getAns(int finalAns[],int l,int k){
139      int x[305]={0},ans[305]={0};
140      getNum(x,1,l);
141      x[l-1]-=1;
142      Multiply(x,l);
143      for(int i=0;i<=300;++i)
144      ans[i]=a[l-1][i]+x[i];
145      ans[0]+=1+k+kk;
146      for(int i=0;i<=300;++i)
147      if(ans[i]>9)
148      {
149           ans[i+1]+=ans[i]/10;
150           ans[i]%=10;
151                     }   
152      
153      if(flag==1||comp(ans,finalAns))
154      for(int i=0;i<=300;++i)
155      finalAns[i]=ans[i];
156      }
157 //判断数组是否为1000....0000的形式 
158 bool Equal1000(int x[]){
159      int tot=0;
160      for(int i=0;i<=300;++i)
161      if(x[i]!=0) tot++;
162      if(tot>1) return false;
163      return true;
164      }
165 
166 //判断字符串是否为全0 
167 bool Equal000(string s1){
168      for(int i=0;i<s1.size();++i)
169      if(s1[i]!=0) return false;
170      return true;
171      }
172 
173      
174 int main()
175 { 
176     //a[i]表示所有位数<=i的字符串长度和
177     for(int i=1;i<=200;++i)
178     {
179       a[i][i-1]=9;
180       Multiply(a[i],i);
181       add(a[i],a[i-1]);
182             }
183     
184     int finalAns[305]={0};
185     flag=1;
186     
187     string s1;
188     cin>>s1;
189     
190     //如果字符串=000...0,则在最前面加上0,令kk=1,最后的答案要减去kk
191     if(Equal000(s1))
192     {s1="1"+s1;kk=1;}
193     
194     //l为字符串中第一个数的位数
195     //k表示字符串中第一个字符是第一个数的第K+1位,k<l
196     for(int l=1;l<=s1.size();++l)
197     for(int k=0;k<l;++k)
198     {
199        s=" "+s1;string s2="";
200        if(k==0)
201        {
202           if(find(l))
203              {getAns(finalAns,l,k);flag=0;}
204                }
205                
206        //如果K!=0,则补齐第一个数的前k位 
207        if(k!=0)
208        {
209 
210           int x[305]={0};
211           getNum(x,l-k+1,l-k+k);
212           
213           //1.直接把第l-k+1至l-k+k之间的数补齐第一个数的前k位  
214           s2="";
215           int i=k-1;
216           while(i>=0) s2+=x[i--]+0;
217           s=" "+s2+s1;
218           if(find(l))
219           {getAns(finalAns,l,k);flag=0;}
220           
221           //2.如果第l-k+1至l-k+k之间数的形式是10....000,也可以用99....999补齐第一个数的前k位  
222           if(Equal1000(x))
223           {
224              s2="";
225              i=k-1;
226              while(i>=0) {s2+=9;i--;}
227              s=" "+s2+s1;
228              if(find(l))
229              {getAns(finalAns,l,k);flag=0;}
230                           }
231           //3.用第l-k+1至l-k+k之间的数减去1,补齐第一个数的前k位  
232           sub(x,1);
233           i=k-1;
234           s2="";
235           while(i>=0) s2+=x[i--]+0;
236           s=" "+s2+s1;
237           if(find(l))
238           {getAns(finalAns,l,k);flag=0;}
239                
240                } 
241             
242             }
243     
244     print(finalAns);        
245                   
246   //  system("pause");
247     
248     
249 
250     } 

 

超长数字串

标签:alt   +=   数组   false   2-2   idt   长度   final   oid   

原文地址:http://www.cnblogs.com/noip/p/7813951.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!