题解:2018级算法第二次上机 Zexal的排座位

题目描述:

 

样例:

实现解释:

一道看似复杂但实际既是斐波那契变形的题目

知识点:递推,斐波那契

通过问题的描述,可以得到以下规律:(除了座位数为一时)男生坐最后时,倒数第二个一定是女生;女生坐最后,倒数第二个均可。转化:i个位置时男生结尾的情况数等于i-1个位置时女生结尾的情况数,i个位置时女生结尾的情况数等于i-1个位置时的总情况数。

于是便可得出两种解决方案:斐波那契变形和直接循环递推

斐波那契变形:

i位置男生结尾的情况 = i-1位置女生结尾情况数 = i-2位置总情况数

i位置女生结尾的情况 = i-1位置总情况数

则有num(i) = num(i-1)+num(i-2); num(1) = 2; num(0) = 1;

编写递归程序即可。

直接循环递推:

直接按转化后的递推关系编写程序即可:利用temp储存前一次男生结尾情况,男生结尾数 = 前一次的女生结尾数,女生结尾数 = 前一次女生结尾数加上存储好的前一次男生结尾数即可。

最后的代码还包括一个没事儿干的时候进行代码缩减后的递推代码,省去了temp变量。

坑点:

斐波那契方法时注意特殊值0和1的判断输出

递推方法时注意两种选择情况的重置

完整代码:

斐波那契变形:

//斐波那契变形 直接斐波那契
#include<iostream>
using namespace std; 
int fi(int n)
{
	if(n == 0) return 1;
	if(n == 1) return 2;
	return fi(n-1)+fi(n-2);
}
int main()
{
	ios::sync_with_stdio(false);
	int n;
	while(cin >> n)
	{
		cout << fi(n) << '\n';
	}
	return 0;
}

  

直接循环递推:

#include<iostream>
using namespace std;
int main()
{
	ios::sync_with_stdio(false);
	int n;
	long long temp,choiceMan,choiceWoman;
	//分别为中间值,男生坐最后的情况总数,女生坐最后的情况总数
	while(cin >> n)
	{
		//一个座位时,男女最后的情况分别为1
		choiceMan = choiceWoman = 1;
		for(int i = 1;i<n;i++)
		{
			//记录 
			temp = choiceMan;
			//座位增多后,男生只能坐在女生结尾的座位后
			choiceMan = choiceWoman;
			//女生可以女生最后也可以男生最后,求和 
			choiceWoman += temp;
			//注意交换赋值的顺序 
		}
		cout << choiceMan+choiceWoman << endl;
	}
	return 0;
}

  

无聊压缩代码:

#include<cstdio>
int main()
{
	int n,m,w;
	while(~scanf("%d",&n))
	{
		m=w=1;
		while(n-->1)
		{
			w+=m;
			m=w-m;
		}
		printf("%d\n",m+w);
	}
}

  

猜你喜欢

转载自www.cnblogs.com/doUlikewyx/p/11700792.html