这是一个公式:
根据大家的数学经验可以知道这是一个计算斐波那契数列的公式,那么假设我们不知道这是一个斐波纳契数列的公式,只知道他是一个简单的数学计算公式,该怎么求这个公式的值呢?答案就是需要使用模拟!而这篇博文,我们就来讨论一些简单的模拟题目,再教给大家一些做模拟题的方法。
Q1:使用公式求斐波那契数列第n项值
这是一个非常简单的模拟,可以直接使用C++头文件cmath
中的库函数完成,这里我们可以看到题目中有两个比较难搞的东西,一个是:
根号可以使用sqrt
函数,而m的n次方可以使用pow
函数(或者位运算),注意,这两个函数的返回值都是double类型的,所以最好使用double类型存储,而且pow函数会有精度误差,所以一定要谨慎使用。
接下来给大家看一下初步的代码:
#include
using namespace std;
// 该函数用于计算斐波那契数列的第n项
double fibonacci(int n) {
// 特判
if(n <= 0) {
return 0;
}
// 模拟
double phi = (1 + sqrt(5)) / 2;
double psi = (1 - sqrt(5)) / 2;
double numerator = pow(phi, n) - pow(psi, n);
double denominator = sqrt(5);
return numerator / denominator;
}
int main() {
int n;
cin >> n; // 读入
// 设置输出精度,以便更好地显示浮点数结果
cout << fixed << setprecision(2); // 这里我们输出两位小数
if (n >= 1) {
double res = fibonacci(n);
cout << "Fibonacci number at index " << n << " is: " << res << endl;
} else {
cout << "No answer" << endl;
}
return 0;
}
输出一下,完全正确!
这里我们定义了一个函数fibonacci
,该函数用于求斐波那契数列的第n项,在函数里面,我们定义了四个变量:phi
、psi
、numerator
和denominator
。
phi
求的是分数分子的左边部分(减号前的部分);
psi
求的是分数分子的右半部分(减号后的部分);
numerator
顾名思义是分子;
denominator
顾名思义就是分母。
最后的返回值就是分数值(也就是分子除以分母)
接下来我们来看一看下一个问题。
Q2:[NOIP2003 普及组] 乒乓球
题目背景
国际乒联现在主席沙拉拉自从上任以来就立志于推行一系列改革,以推动乒乓球运动在全球的普及。其中
题目描述
华华通过以下方式进行分析,首先将比赛每个球的胜负列成一张表,然后分别计算在
比如现在有这么一份记录,(其中
在
你的程序就是要对于一系列比赛信息的输入(
输入格式
每个输入文件包含若干行字符串,字符串有大写的
输出格式
输出由两部分组成,每部分有若干行,每一行对应一局比赛的比分(按比赛信息输入顺序)。其中第一部分是
样例 #1
样例输入 #1
WWWWWWWWWWWWWWWWWWWW
WWLWE
样例输出 #1
11:0
11:0
1:1
21:0
2:1
提示
每行至多
(注:事实上有一个测试点有
【题目来源】
NOIP 2003 普及组第一题
分析
这是一道很经典的签到模拟题,我们可以直接根据题意模拟:
#include
using namespace std;
int win[114514];
int w, l;
int main() {
char s;
for(int i = 1; cin >> s && s != 'E'; ++ i) {
if(s == 'W') win[i] = 1;
else win[i] = 2;
}
for(int i = 1; ; ++ i) {
if(win[i] == 1) ++ w;
if(win[i] == 2) ++ l;
if(win[i] == 0) {
cout << w << ":" << l << endl << endl;
break;
}
if(w - l >= 2 || l - w >= 2)
if(w >= 11 || l >= 11) {
cout << w << ":" << l << endl;
w = 0;
l = 0;
}
}
w = 0;
l = 0;
for(int i = 1; ; ++ i) {
if(win[i] == 1) ++ w;
if(win[i] == 2) ++ l;
if(win[i] == 0) {
cout << w << ":" << l;
break;
}
if(w - l >= 2 || l - w >= 2)
if(w >= 21 || l >= 21) {
cout << w << ":" << l << endl;
w = 0;
l = 0;
}
}
return 0;
}
首先一定要开数组存储胜负次数,因为你不仅要存胜负的场数,还要存胜负的顺序,以此来排分数。其次分数差要大于2,这是因为正规乒乓球比赛,不仅分数要大于11(或21),两者分数相差也要大于2。如果比赛分数达到11-10,比赛会继续。直到一个人比另外一个人多两分。(如13-11)21分制同理,这里不再过多阐述。
其实这两道题目的模拟算是C++当中最简单的,接下来,我会再发表几篇文章用以阐述复杂的模拟算法。
__EOF__