作者:llllllw_wlllllll | 来源:互联网 | 2024-12-25 13:08
本次考试于2016年10月25日上午7:50至11:15举行,主要涉及数学专题,特别是斐波那契数列的性质及其在编程中的应用。本文将详细解析考试中的题目,并提供解题思路和代码实现。
本次考试时间为2016年10月25日上午7:50至11:15,题目涵盖了数学专题,尤其是斐波那契数列的相关内容。以下是详细的题目解析和解题思路。
试题包:下载链接
题目:查看PDF
第一题:斐波那契数列的gcd性质
题目描述略显复杂,但核心在于利用斐波那契数列的性质求解gcd问题。通过观察数据,可以发现gcd(f[i], f[j]) = f[gcd(i, j)]。根据这个规律,我们可以使用矩阵快速幂来高效计算斐波那契数列。
1. 我们先来看看几个有关斐波那契数列的引理。
Gcd(F[n+1],F[n])=1;
F[m+n]=F[m-1]F[n]+F[m]F[n+1];
Gcd(F[n+m],F[n])=Gcd(F[n],F[m]);
由以上三个引理有:Gcd(F[n],F[m])=F[Gcd(n,m)];
证明略,具体实现如下:
#include
#include
#include
const int mod = 19491001;
int n;
int tx, ty;
struct data {
long long x1, x2, x3, x4;
data (long long x1 = 1, long long x2 = 0, long long x3 = 0, long long x4 = 1) : x1(x1), x2(x2), x3(x3), x4(x4) {};
};
int gcd(int a, int b) {
if (b == 0) return a;
return gcd(b, a % b);
}
data operator * (data a, data b) {
data c;
c.x1 = (a.x1 * b.x1 + a.x2 * b.x3) % mod;
c.x2 = (a.x1 * b.x2 + a.x2 * b.x4) % mod;
c.x3 = (a.x3 * b.x1 + a.x4 * b.x3) % mod;
c.x4 = (a.x3 * b.x2 + a.x4 * b.x4) % mod;
return (c);
}
data qpow(data x, int v) {
data ans;
while (v > 0) {
if (v & 1) ans = ans * x;
x = x * x;
v >>= 1;
}
return (ans);
}
int main () {
freopen("fibonacci.in", "r", stdin);
freopen("fibonacci.out", "w", stdout);
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d %d", &tx, &ty);
int ans = gcd(tx, ty);
data cur(0, 1, 1, 1);
cur = qpow(cur, ans - 2);
long long tans = ((cur.x2 + cur.x4) % mod + mod) % mod;
printf("%I64d\n", tans);
}
return 0;
}
该题代码实现较为复杂,主要是矩阵乘法的实现不够简洁,后续可以优化。
第二题:黄金分割与斐波那契数列
题目要求找到最接近黄金分割数的两个斐波那契数的比例。通过打表发现,对于较大的n,直接使用斐波那契数列即可解决问题。具体实现如下:
#include
#include
#include
unsigned long long f[100];
unsigned long long n;
int main () {
freopen("gold.in", "r", stdin);
freopen("gold.out", "w", stdout);
f[1] = 1;
f[2] = 1;
for (int i = 3; i <= 93; i++) f[i] = f[i-1] + f[i-2];
f[94] = 0 - 1;
//for (int i = 1; i <= 94; i++) printf("%I64u\n", f[i]);
scanf("%I64u", &n);
for (int i = 2; i <= 93; i++) {
if (f[i] <= n && f[i+1] > n) {
printf("%I64u/%I64u\n", f[i-1], f[i]);
}
}
return 0;
}
该题的关键在于理解斐波那契数列与黄金分割的关系,通过打表验证后,可以直接得出结论。
第三题:哈希表与LCP
题目要求对每个号码进行变化并存入哈希表中,之后进行判重和暴力LCP计算。具体实现尚未完成,预计得分较低。标答如下:
首先枚举每一个号码,将它按照题目中所给的允许变化的方案进行变化,将变化结果存在哈希表里,之后利用哈希进行判重,如果出现变化后的值与变化前的相同,对两个点进行暴力LCP并连边,最后使用SPFA求解。
第四题:行列互不影响的纸牌问题
题目描述为行列之间的关系,实际上是一个环形均分纸牌问题。设每行1的个数为n堆纸牌,每列1的个数为m堆纸牌,最终目标是使每一行和每一列的纸牌数量相等。
方法一:枚举从第k个位置开始,依次向后推,最后取最小值。时间复杂度O(n^2),预计得分70分。
方法二:设bi的前缀和为si,当sk是s1~sn中位数时,上式有最小值。把si排序后,令sk=s[(n+1)/2],计算代价即可。时间复杂度O(nlogn),预计得分100分。