P2437 蜜蜂路线 大整数,fib【1】

https://www.luogu.org/problemnew/show/P2437

 

题目描述

一只蜜蜂在下图所示的数字蜂房上爬动,已知它只能从标号小的蜂房爬到标号大的相邻蜂房,现在问你:蜜蜂从蜂房M开始爬到蜂房N,M<N,有多少种爬行路线?

输入输出格式

输入格式:

输入M,N的值

输出格式:

爬行有多少种路线

输入输出样例

输入样例#1: 复制

1 14

输出样例#1: 复制

377

说明

对于100%的数据,M,N≤1000

 

刚看题目,觉得非常简单,但是只有两个测试通过,之后看了别人的做法才知道是整数溢出了,改用int128,3个正确,最后又采用了这个模板,通过。

其实一开始应该看出这是一个菲比列数组,那么自然会很大。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string.h>
#include <string>
#include <vector>
#include <queue>

using namespace std;

struct BigInteger {
	typedef unsigned long long LL;

	static const int BASE = 100000000;
	static const int WIDTH = 8;
	vector<int> s;

	BigInteger& clean() {
		while(!s.back()&&s.size()>1)s.pop_back();
		return *this;
	}
	BigInteger(LL num = 0) {
		*this = num;
	}
	BigInteger(string s) {
		*this = s;
	}
	BigInteger& operator = (long long num) {
		s.clear();
		do {
			s.push_back(num % BASE);
			num /= BASE;
		} while (num > 0);
		return *this;
	}
	BigInteger& operator = (const string& str) {
		s.clear();
		int x, len = (str.length() - 1) / WIDTH + 1;
		for (int i = 0; i < len; i++) {
			int end = str.length() - i*WIDTH;
			int start = max(0, end - WIDTH);
			sscanf(str.substr(start,end-start).c_str(), "%d", &x);
			s.push_back(x);
		}
		return (*this).clean();
	}

	BigInteger operator + (const BigInteger& b) const {
		BigInteger c;
		c.s.clear();
		for (int i = 0, g = 0; ; i++) {
			if (g == 0 && i >= s.size() && i >= b.s.size()) break;
			int x = g;
			if (i < s.size()) x += s[i];
			if (i < b.s.size()) x += b.s[i];
			c.s.push_back(x % BASE);
			g = x / BASE;
		}
		return c;
	}
	BigInteger operator - (const BigInteger& b) const {
		//assert(b <= *this); // ¼õÊý²»ÄÜ´óÓÚ±»¼õÊý
		BigInteger c;
		c.s.clear();
		for (int i = 0, g = 0; ; i++) {
			if (g == 0 && i >= s.size() && i >= b.s.size()) break;
			int x = s[i] + g;
			if (i < b.s.size()) x -= b.s[i];
			if (x < 0) {
				g = -1;
				x += BASE;
			} else g = 0;
			c.s.push_back(x);
		}
		return c.clean();
	}
	BigInteger operator * (const BigInteger& b) const {
		int i, j;
		LL g;
		vector<LL> v(s.size()+b.s.size(), 0);
		BigInteger c;
		c.s.clear();
		for(i=0; i<s.size(); i++) for(j=0; j<b.s.size(); j++) v[i+j]+=LL(s[i])*b.s[j];
		for (i = 0, g = 0; ; i++) {
			if (g ==0 && i >= v.size()) break;
			LL x = v[i] + g;
			c.s.push_back(x % BASE);
			g = x / BASE;
		}
		return c.clean();
	}
	BigInteger operator / (const BigInteger& b) const {
		//assert(b > 0);  // ³ýÊý±ØÐë´óÓÚ0
		BigInteger c = *this;       // ÉÌ:Ö÷ÒªÊÇÈÃc.sºÍ(*this).sµÄvectorÒ»Ñù´ó
		BigInteger m;               // ÓàÊý:³õʼ»¯Îª0
		for (int i = s.size()-1; i >= 0; i--) {
			m = m*BASE + s[i];
			c.s[i] = bsearch(b, m);
			m -= b*c.s[i];
		}
		return c.clean();
	}
	BigInteger operator % (const BigInteger& b) const { //·½·¨Óë³ý·¨Ïàͬ
		BigInteger c = *this;
		BigInteger m;
		for (int i = s.size()-1; i >= 0; i--) {
			m = m*BASE + s[i];
			c.s[i] = bsearch(b, m);
			m -= b*c.s[i];
		}
		return m;
	}
	// ¶þ·Ö·¨ÕÒ³öÂú×ãbx<=mµÄ×î´óµÄx
	int bsearch(const BigInteger& b, const BigInteger& m) const {
		int L = 0, R = BASE-1, x;
		while (1) {
			x = (L+R)>>1;
			if (b*x<=m) {
				if (b*(x+1)>m) return x;
				else L = x;
			} else R = x;
		}
	}
	BigInteger& operator += (const BigInteger& b) {
		*this = *this + b;
		return *this;
	}
	BigInteger& operator -= (const BigInteger& b) {
		*this = *this - b;
		return *this;
	}
	BigInteger& operator *= (const BigInteger& b) {
		*this = *this * b;
		return *this;
	}
	BigInteger& operator /= (const BigInteger& b) {
		*this = *this / b;
		return *this;
	}
	BigInteger& operator %= (const BigInteger& b) {
		*this = *this % b;
		return *this;
	}

	bool operator < (const BigInteger& b) const {
		if (s.size() != b.s.size()) return s.size() < b.s.size();
		for (int i = s.size()-1; i >= 0; i--)
			if (s[i] != b.s[i]) return s[i] < b.s[i];
		return false;
	}
	bool operator >(const BigInteger& b) const {
		return b < *this;
	}
	bool operator<=(const BigInteger& b) const {
		return !(b < *this);
	}
	bool operator>=(const BigInteger& b) const {
		return !(*this < b);
	}
	bool operator!=(const BigInteger& b) const {
		return b < *this || *this < b;
	}
	bool operator==(const BigInteger& b) const {
		return !(b < *this) && !(b > *this);
	}
};

ostream& operator << (ostream& out, const BigInteger& x) {
	out << x.s.back();
	for (int i = x.s.size()-2; i >= 0; i--) {
		char buf[20];
		sprintf(buf, "%08d", x.s[i]);
		for (int j = 0; j < strlen(buf); j++) out << buf[j];
	}
	return out;
}

istream& operator >> (istream& in, BigInteger& x) {
	string s;
	if (!(in >> s)) return in;
	x = s;
	return in;
}
const int maxn=105;
#define ll BigInteger

ll dp[1008];


int main() {
	int n,m;
	cin>>n>>m;
	int rk=m-n;
	if(rk<=0) {
		cout<<0<<endl;
		return 0;
	}
	memset(dp,0,sizeof(dp));
	dp[0]=0;
	dp[1]=1;
	for(int i=2; i<=rk+1; i++) {
		dp[i]=dp[i-1]+dp[i-2];
	}
	cout<<(dp[rk+1])<<endl;

}

最后再看一些别人写的 简单加法。数组实现。

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 505;
int a[N],b[N],c[N];
 
void add(int a[],int b[],int c[]){
	fill(c,c+N,0);
	c[0]=b[0];
	for (int i=1; i<=c[0]; i++){
		c[i]+=a[i]+b[i];
		c[i+1]+=c[i]/10;
		c[i]%=10;
	}
	if (c[c[0]+1]) c[0]++;
}
 
void fibo(int n){
	if (n<=2) { c[0]=1; c[1]=n; return; }
	a[0]=a[1]=b[0]=1; b[1]=2;
	for (int i=3; i<=n; i++){
		add(a,b,c);
		memcpy(a,b,sizeof(b));
		memcpy(b,c,sizeof(c));
	}
}
 
void output(int a[]){
	for (int i=a[0]; i>=1; i--) cout<<a[i];
	cout<<endl;
}
 
int main(){
	int m,n;
	cin>>m>>n;
	fibo(n-m);    //斐波那契数列第n-m项,第1项为1,第2项为2 开始
	output(c);
	return 0;
}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值