C++竞赛技巧 打表
·
1. 概念
算法竞赛中的 “打表”,是预计算并存储结果到数组 / 哈希表,后续直接查询的优化技巧,核心是用空间换时间,防止超时,下面是适用场景。
2. 使用场景
2. 1 应对重复计算:同一问题多次需要相同结果时,避免重复运算浪费时间。
斐波那契数列(不打表)
#include <iostream>
using namespace std;
const int MOD = 1e9 + 7;
// 单次计算第n项:时间复杂度O(n)
int fib(int n) {
if (n == 0) return 0;
int a = 0, b = 1;
for (int i = 2; i <= n; i++) {
int c = (a + b) % MOD;
a = b;
b = c;
}
return b;
}
int main() {
int T, n;
cin >> T;
while (T--) {
cin >> n;
cout << fib(n) << endl;
}
return 0;
}
斐波那契数列(打表)
2.2 降低时间复杂度:把高复杂度计算(如 O (n²))提前预处理,查询时仅需 O (1) 或 O (logn)。
素数判断(试除)
#include <iostream>
#include <cmath>
using namespace std;
// 单次判断素数:时间复杂度O(√x)
bool isPrime(int x) {
if (x < 2) return false;
for (int i = 2; i <= sqrt(x); i++) {
if (x % i == 0) return false;
}
return true;
}
int main() {
int T, x;
cin >> T;
while (T--) {
cin >> x;
cout << (isPrime(x) ? "Yes" : "No") << endl;
}
return 0;
}
素数判断(埃氏筛)
#include <iostream>
#include <vector>
using namespace std;
const int MAX = 1e6;
vector<bool> prime(MAX + 1, true);
// 预处理打表:时间复杂度O(n log log n),n=1e6
void initPrime() {
prime[0] = prime[1] = false;
for (int i = 2; i * i <= MAX; i++) {
if (prime[i]) {
for (int j = i * i; j <= MAX; j += i) {
prime[j] = false;
}
}
}
}
int main() {
initPrime(); // 只预处理一次
int T, x;
cin >> T;
while (T--) {
cin >> x;
cout << (prime[x] ? "Yes" : "No") << endl; // 查询O(1)
}
return 0;
}
3. 注意事项
在做题过程中,打表一般是优化部分代码,同时也可以用打表试探数据
更多推荐


所有评论(0)