循环-小蜜蜂-斐波那契数列-大数加法

【题】

小蜜蜂(选作)


一只小蜜蜂在如下图所示的蜂窝上爬行。它爬行时,只能从一个格爬到相邻的大号格子中。例如,从 1 号格子可以爬到 2 号或者 3 号格子,从 2 号则可以爬到 3 号或者 4 号格子。

 

    请问从一个格子 a 爬到一个格子 b 一共有多少种可行的路线。

输入:

    分别是起始点 a 和终止点 b 的编号。( a 和 b 在 1~100 之间,且 a

输出:

    方案数量。

  测试输入 期待的输出 时间限制 内存限制 额外进程
测试用例 1 以文本方式显示
  1. 1 4↵
以文本方式显示
  1. 3↵
1秒 64M 0
测试用例 2 以文本方式显示
  1. 1 5↵
以文本方式显示
  1. 5↵
1秒 64M 0
测试用例 3 以文本方式显示
  1. 1 50↵
以文本方式显示
  1. 12586269025↵
1秒 64M 0
测试用例 4 以文本方式显示
  1. 2 50↵
以文本方式显示
  1. 7778742049↵
1秒 64M 0
测试用例 7 以文本方式显示
  1. 1 100↵
以文本方式显示
  1. 354224848179261915075↵
1秒 64M 0

【分析】
        分析可知,这是一个斐波那契数列。需要注意的是,C语言中所有的类型都不能表示题中的数值,需要用到大数加法。

【代码】
    (1)先给出斐波那契数列的求法:
#include "stdio.h"

int main()
{
	int a, b;
	scanf("%d %d", &a, &b);
	getchar();

	int count = b - a;
	int i, x1 = 0, x2 = 1, y;
	//斐波那契数列
	for(i = 1; i <= count; i++)
	{
		y = x1 + x2;
		x1 = x2;
		x2 = y;
	}
	printf("%d\n", y);
    return 0; 
}

    (2)大数加法
           
         
#include "stdio.h"
#include "stdlib.h"

#define N 22				//22位能表示第100个以内的斐波那契数列值

char * Add(char * x1, char * x2);
void Output(char * y);

int main()
{
	int i;

	//y = x1 + x2;
	char * x1 = (char *)malloc(sizeof(char) * N);
	char * x2 = (char *)malloc(sizeof(char) * N);
	char * y = (char *)malloc(sizeof(char) * N);

	//初始化y, x1, x2
	for (i = 0; i < N; i++)
	{
		x1[i] = '\0';
		x2[i] = '\0';
		y[i] = '\0';
	}

	//给x1和x2赋初值
	//x1 = 1256
	//x2 = 567
	x1[0] = '6';	x1[1] = '5';	x1[2] = '2';	x1[3] = '1';
	x2[0] = '7';	x2[1] = '6';	x2[2] = '5';	


	y = Add(x1, x2);

	//输出
	Output(x1);
	printf(" + ");
	Output(x2);
	printf(" = ");
	Output(y);

	printf("\n");
    return 0; 
}

//大数加法函数
char * Add(char * x1, char * x2)
{
 	char * y = (char *) malloc(sizeof(char *) * N);
	int i = 0;
	int t = 0;				//表示进位

	//实现大数加法,数组前面存的是数值的高位。如123在数组中是{'3','2','1','\0'}
	//处理相同长度的部分
	while(x1[i] != '\0' && x2[i] != '\0')
	{
		y[i] = (x1[i] - '0' + x2[i] - '0' + t) % 10 + '0';
		t = (x1[i] - '0' + x2[i] - '0' + t) / 10;
		i++;
	}
	//如果x1比x2长
	while(x1[i] != '\0')
	{
		y[i] = (x1[i] - '0' + t) % 10 + '0';
		t = (x1[i] - '0' + t) / 10;
		i++;
	}
	//如果x2比x1长
	while(x2[i] != '\0')
	{
		y[i] = (x2[i] - '0' + t) % 10 + '0';
		t = (x2[i] - '0' + t) / 10;
		i++;
	}
	//如果还有进位
	if (t == 1)
	{
		y[i++] = '1';
	}
	y[i] = '\0';
 	return y;
}

//输出
void Output(char * y)
{	
	//先找到\0的位置,然后逆序输出
	int i = 0;
	while(y[i] != '\0')
	{
		i++;
	}
	i--;
	while(i >= 0)
	{
		printf("%d", y[i--] - '0');
	}
}


    (3)斐波那契数列 + 大数加法

#include "stdio.h"
#include "stdlib.h"

#define N 22				//22位能表示第100个以内的斐波那契数列值

char * Add(char * x1, char * x2);
void Output(char * y);

int main()
{
	int a = 1, b = 100;

	scanf("%d %d", &a, &b);
	getchar();
	
	int count = b - a;
	int i;

	//y = x1 + x2;
	char * x1 = (char *)malloc(sizeof(char) * N);
	char * x2 = (char *)malloc(sizeof(char) * N);
	char * y = (char *)malloc(sizeof(char) * N);

	//初始化y, x1, x2
	for (i = 0; i < N; i++)
	{
		x1[i] = '\0';
		x2[i] = '\0';
		y[i] = '\0';
	}

	//给x1和x2赋初值
	x1[0] = '0';	x1[1] = '\0';
	x2[0] = '1';	x2[1] = '\0';

	//斐波那契数列,叠加
	for(i = 1; i <= count; i++)
	{
		y = Add(x1, x2);
		x1 = x2;
		x2 = y;
	}
	
	//输出结果
	Output(y);
	printf("\n");
    return 0; 
}

//大数加法函数
char * Add(char * x1, char * x2)
{
	char * y = (char *) malloc(sizeof(char *) * N);
	int i = 0;
	int t = 0;				//表示进位

	//实现大数加法,数组前面存的是数值的高位。如123在数组中是{'3','2','1','\0'}
	//处理相同长度的部分
	while(x1[i] != '\0' && x2[i] != '\0')
	{
		y[i] = (x1[i] - '0' + x2[i] - '0' + t) % 10 + '0';
		t = (x1[i] - '0' + x2[i] - '0' + t) / 10;
		i++;
	}
	//如果x1比x2长
	while(x1[i] != '\0')
	{
		y[i] = (x1[i] - '0' + t) % 10 + '0';
		t = (x1[i] - '0' + t) / 10;
		i++;
	}
	//如果x2比x1长
	while(x2[i] != '\0')
	{
		y[i] = (x2[i] - '0' + t) % 10 + '0';
		t = (x2[i] - '0' + t) / 10;
		i++;
	}
	//如果还有进位
	if (t == 1)
	{
		y[i++] = '1';
	}
	y[i] = '\0';
	return y;
}

//输出
void Output(char * y)
{	
	//先找到\0的位置,然后逆序输出
	int i = 0;
	while(y[i] != '\0')
	{
		i++;
	}
	i--;
	while(i >= 0)
	{
		printf("%d", y[i--] - '0');
	}
}




你可能感兴趣的:(C语言基础)