1216: 斐波那契数列
From: 合工宣OJ http://xcacm.hfut.edu.cn/problem.php?id=1216
时间限制: 1 Sec 内存限制: 128 MB
题目描述 Fibonacci数列,定义如下: f(1)=f(2)=1 f(n)=f(n-1)+f(n-2) n>=3 计算第n项Fibonacci数值。
输入
输入第一行为一个整数n(1<=n<=10000)。
输出
输出对应的f(n)。
样例输入
1 2 3 4 5
样例输出
1 1 2 3 5
本题需要用到大整数,unsign long long已经明显装不下了,c++没有内置封装好的大整数(而JAVA是有的),需要自己定义大整数,大整数的模板很好找到,然而很多功能需要根据实际需要删减,本题只需重载加减符号,然而为用的方便此处未作删减。菲波那切递推公式已经给出,只需循环将每一个情况存在大整数开出的数组里,用时调用即可。原先把#define MAX_L 3000 开到了10000 结果出现内存超限,改合适一些内存会降低很多。 代码如下:
1 #include<string> 2 #include<iostream> 3 #include<iosfwd> 4 #include<cmath> 5 #include<cstring> 6 #include<stdlib.h> 7 #include<stdio.h> 8 #include<cstring> 9 #define MAX_L 3000 10 using namespace std; 11 class bign //定义大整数 12 { 13 public: 14 int len, s[MAX_L]; 15 bign(); 16 bign(const char*); 17 bign(int); 18 bool sign; 19 string toStr() const; 20 friend istream& operator>>(istream &,bign &); 21 friend ostream& operator<<(ostream &,bign &); 22 bign operator=(const char*); 23 bign operator=(int); 24 bign operator=(const string); 25 bool operator>(const bign &) const; 26 bool operator>=(const bign &) const; 27 bool operator<(const bign &) const; 28 bool operator<=(const bign &) const; 29 bool operator==(const bign &) const; 30 bool operator!=(const bign &) const; 31 bign operator+(const bign &) const; 32 bign operator++(); 33 bign operator++(int); 34 bign operator+=(const bign&); 35 bign operator-(const bign &) const; 36 bign operator--(); 37 bign operator--(int); 38 bign operator-=(const bign&); 39 bign operator*(const bign &)const; 40 bign operator*(const int num)const; 41 bign operator*=(const bign&); 42 bign operator/(const bign&)const; 43 bign operator/=(const bign&); 44 bign operator%(const bign&)const; 45 void clean(); 46 ~bign(); 47 }; 48 #define max(a,b) a>b ? a : b 49 #define min(a,b) a<b ? a : b 50 bign::bign() 51 { 52 memset(s, 0, sizeof(s)); 53 len = 1; 54 sign = 1; 55 } 56 bign::bign(const char *num) 57 { 58 *this = num; 59 } 60 bign::bign(int num) 61 { 62 *this = num; 63 } 64 string bign::toStr() const 65 { 66 string res; 67 res = ""; 68 for (int i = 0; i < len; i++) 69 res = (char)(s[i] + '0') + res; 70 if (res == "") 71 res = "0"; 72 if (!sign&&res != "0") 73 res = "-" + res; 74 return res; 75 } 76 istream &operator>>(istream &in, bign &num) 77 { 78 string str; 79 in>>str; 80 num=str; 81 return in; 82 } 83 ostream &operator<<(ostream &out, bign &num) 84 { 85 out<<num.toStr(); 86 return out; 87 } 88 bign bign::operator=(const char *num) 89 { 90 memset(s, 0, sizeof(s)); 91 char a[MAX_L] = ""; 92 if (num[0] != '-') 93 strcpy(a, num); 94 else 95 for (int i = 1; i < strlen(num); i++) 96 a[i - 1] = num[i]; 97 sign = !(num[0] == '-'); 98 len = strlen(a); 99 for (int i = 0; i < strlen(a); i++) 100 s[i] = a[len - i - 1] - 48; 101 return *this; 102 } 103 bign bign::operator=(int num) 104 { 105 if (num < 0) 106 sign = 0, num = -num; 107 else 108 sign = 1; 109 char temp[MAX_L]; 110 sprintf(temp, "%d", num); 111 *this = temp; 112 return *this; 113 } 114 bign bign::operator=(const string num) 115 { 116 const char *tmp; 117 tmp = num.c_str(); 118 *this = tmp; 119 return *this; 120 } 121 bool bign::operator<(const bign &num) const 122 { 123 if (sign^num.sign) 124 return num.sign; 125 if (len != num.len) 126 return len < num.len; 127 for (int i = len - 1; i >= 0; i--) 128 if (s[i] != num.s[i]) 129 return sign ? (s[i] < num.s[i]) : (!(s[i] < num.s[i])); 130 return !sign; 131 } 132 bool bign::operator>(const bign&num)const 133 { 134 return num < *this; 135 } 136 bool bign::operator<=(const bign&num)const 137 { 138 return !(*this>num); 139 } 140 bool bign::operator>=(const bign&num)const 141 { 142 return !(*this<num); 143 } 144 bool bign::operator!=(const bign&num)const 145 { 146 return *this > num || *this < num; 147 } 148 bool bign::operator==(const bign&num)const 149 { 150 return !(num != *this); 151 } 152 bign bign::operator+(const bign &num) const 153 { 154 if (sign^num.sign) 155 { 156 bign tmp = sign ? num : *this; 157 tmp.sign = 1; 158 return sign ? *this - tmp : num - tmp; 159 } 160 bign result; 161 result.len = 0; 162 int temp = 0; 163 for (int i = 0; temp || i < (max(len, num.len)); i++) 164 { 165 int t = s[i] + num.s[i] + temp; 166 result.s[result.len++] = t % 10; 167 temp = t / 10; 168 } 169 result.sign = sign; 170 return result; 171 } 172 bign bign::operator++() 173 { 174 *this = *this + 1; 175 return *this; 176 } 177 bign bign::operator++(int) 178 { 179 bign old = *this; 180 ++(*this); 181 return old; 182 } 183 bign bign::operator+=(const bign &num) 184 { 185 *this = *this + num; 186 return *this; 187 } 188 bign bign::operator-(const bign &num) const 189 { 190 bign b=num,a=*this; 191 if (!num.sign && !sign) 192 { 193 b.sign=1; 194 a.sign=1; 195 return b-a; 196 } 197 if (!b.sign) 198 { 199 b.sign=1; 200 return a+b; 201 } 202 if (!a.sign) 203 { 204 a.sign=1; 205 b=bign(0)-(a+b); 206 return b; 207 } 208 if (a<b) 209 { 210 bign c=(b-a); 211 c.sign=false; 212 return c; 213 } 214 bign result; 215 result.len = 0; 216 for (int i = 0, g = 0; i < a.len; i++) 217 { 218 int x = a.s[i] - g; 219 if (i < b.len) x -= b.s[i]; 220 if (x >= 0) g = 0; 221 else 222 { 223 g = 1; 224 x += 10; 225 } 226 result.s[result.len++] = x; 227 } 228 result.clean(); 229 return result; 230 } 231 bign bign::operator * (const bign &num)const 232 { 233 bign result; 234 result.len = len + num.len; 235 236 for (int i = 0; i < len; i++) 237 for (int j = 0; j < num.len; j++) 238 result.s[i + j] += s[i] * num.s[j]; 239 240 for (int i = 0; i < result.len; i++) 241 { 242 result.s[i + 1] += result.s[i] / 10; 243 result.s[i] %= 10; 244 } 245 result.clean(); 246 result.sign = !(sign^num.sign); 247 return result; 248 } 249 bign bign::operator*(const int num)const 250 { 251 bign x = num; 252 bign z = *this; 253 return x*z; 254 } 255 bign bign::operator*=(const bign&num) 256 { 257 *this = *this * num; 258 return *this; 259 } 260 bign bign::operator /(const bign&num)const 261 { 262 bign ans; 263 ans.len = len - num.len + 1; 264 if (ans.len < 0) 265 { 266 ans.len = 1; 267 return ans; 268 } 269 270 bign divisor = *this, divid = num; 271 divisor.sign = divid.sign = 1; 272 int k = ans.len - 1; 273 int j = len - 1; 274 while (k >= 0) 275 { 276 while (divisor.s[j] == 0) j--; 277 if (k > j) k = j; 278 char z[MAX_L]; 279 memset(z, 0, sizeof(z)); 280 for (int i = j; i >= k; i--) 281 z[j - i] = divisor.s[i] + '0'; 282 bign dividend = z; 283 if (dividend < divid) { k--; continue; } 284 int key = 0; 285 while (divid*key <= dividend) key++; 286 key--; 287 ans.s[k] = key; 288 bign temp = divid*key; 289 for (int i = 0; i < k; i++) 290 temp = temp * 10; 291 divisor = divisor - temp; 292 k--; 293 } 294 ans.clean(); 295 ans.sign = !(sign^num.sign); 296 return ans; 297 } 298 bign bign::operator/=(const bign&num) 299 { 300 *this = *this / num; 301 return *this; 302 } 303 bign bign::operator%(const bign& num)const 304 { 305 bign a = *this, b = num; 306 a.sign = b.sign = 1; 307 bign result, temp = a / b*b; 308 result = a - temp; 309 result.sign = sign; 310 return result; 311 } 312 void bign::clean() 313 { 314 if (len == 0) len++; 315 while (len > 1 && s[len - 1] == '\0') 316 len--; 317 } 318 bign::~bign() {} 319 320 bign f[10002]; //大整数数组 321 322 int main() 323 { 324 int a,i; 325 f[4]=3;f[1]=1;f[2]=1;f[3]=2; 326 for(i=5;i<=10000;i++) 327 { 328 f[i]=f[i-1]+f[i-2]; 329 } 330 while(cin>>a) 331 { 332 cout<<f[a]<<endl; 333 } 334 return 0; 335 } 336 /************************************************************** 337 Problem: 1216 338 User: 2014217052 339 Language: C++ 340 Result: 正确 341 Time:864 ms 342 Memory:118808 kb 343 ****************************************************************/