洛谷 P1011 车站 C语言题解

附上代码
一定要看下面的文字题解,单看代码有些晦涩

#include<stdio.h>
int sa[2002],sx[2002],da[2002],dx[2002];
int main()
{
	int initnum,stanum,peo,loc;//开始有多少人,即a,总战术,最后一站下车的人数,计算第几站
	scanf("%d%d%d%d",&initnum,&stanum,&peo,&loc);
	//initnum是一开始上车的人数,stanum是车站的总数,peo是最后一站下车的人数,loc是题目所问的第几站
	sa[0] = 1;
	sa[1] = 0;
	sa[2] = 1;
	sa[3] = 1;
	sx[0] = 0;
	sx[1] = 1;
	sx[2] = 1;
	if(stanum >= 6)
		for(int i = 4;i < stanum ;i++)
		{
			sa[i] = sa[i - 1] + sa[i - 2];
		}
	if(stanum >= 4)
		for(int i = 3;i < stanum - 1;i++)
		{
			sx[i] =sx[i - 1] + sx[i - 2];
		}
	dx[1] = 1;
	dx[2] = 1;
	dx[3] = 1;
	if(stanum >= 4)
	{
		for(int i = 4;i < stanum - 1;i++)
		{
			dx[i] = dx[i - 1] + dx[i - 2];
		}
	}
	da[3] = 1;
	da[4] = 1;
	if(stanum > 5)
	{
		for(int i = 5;i < stanum - 1;i++)
		{
			da[i] = da[i - 1] + da[i - 2];
		}
	}
	int suma = 0;
	int sumx = 0;;
	for(int i = 0;i <= stanum - 2;i++)
	{
		suma += (sa[i] - da[i]);
		sumx += (sx[i] - dx[i]);
	}
	int x = (peo - suma * initnum) / sumx;
	suma = 0;
	sumx = 0;
	for(int i = 0;i < loc;i++)
	{
		suma += (sa[i] - da[i]);
		sumx += (sx[i] - dx[i]);
	}
	printf("%d",suma * initnum + sumx * x);
	return 0;
}

先明确两个变量,一个是initnum,就是第一站的时候车上的人数,一个是x,就是在第二站上车的人数,
代码中我定义了四个数组,分别是
sa 斐波那契而数列中initnum前面的系数,
sx,最初上车人数x的系数,
da,每一站下车的人数中initnum前的系数,
dx,每一站下车人数x前的系数
通过亲自把数据列出来,我们可以发现,
第一站:上车initnum 人;车上有 initnum 人;

第二站:假设上车 x 人,则下车 x 人;车上仍然是initnum人;

第三站:上车人数等于前两站上车人数之和:initnum + x 人,下车人数等于上次上车人数 x 人;

第四站:上车人数 initnum + 2x,下车人数 initnum + x;

第五站:上车人数2initnum + 3x,下车人数 initnum +2x,

第六站:上车人数 3initnum + 5x,下车 2initnum +3x 人,

如果单看上车人数initnum前的系数,我们可以发现,他的系数是 1 0 1 1 2 3 5 8 13 21 …
如果单看上车人数前的系数,他们的系数是 0 1 1 2 3 5 8 13 21…
看下车人数initnum前的系数,他们是0 0 0 1 1 2 3 5 8 13 21 …
看下车人数x前的系数,他们是 0 1 1 1 2 3 5 8 13 21…
他们或许只有前几项不符合斐波那契额数列,但是几项过后,都是符合数列规律的。
所以我们可以选择一个不是很优雅的方法,就使将四个数列的前导列出来,然后根据车站的总数选择我们要计算的次数,将四个数列分别用数组存储起来,在后面解x的时候使用。
题上还告诉我们一个信息,就是最后一站下车的人数,我们可以通过将前n-1站上下车的斐波那契额数列的系数相加,让上车减下车的initnum的系数为suma,上车减下车的x系数为sumx,所以我们就有这个方程式

initnum * suma + x * sumx = 最后一站的下车人数
通过解这个方程就可以得到第二站上车的人数x,最后通过题目要求,求第几站,就按照上面一样的方法算出来就可以了,用数组注意不要越界啊
通过这个不美观的方法,就可以AC了
删除线格式
溜了溜了~~

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值