欧拉计划 Problem 35 题解
- 题干
- 思路
- code
- 暴力
- 筛法
- rotate函数使用
- 语法
- 示例代码
题干
思路
一个很自然的思路就是暴力找,遍历一百万之内的所有数,也可以先把一百万以内所有的素数筛出来然后从中取选。这里我使用的是暴力算法。
code
暴力
#include <bits/stdc++.h>using namespace std;using ll = long long;bool check(int x) {if (x < 2) return false;for (int i = 2; i * i <= x; ++i) {if (x % i == 0) return false;}return true;
}void solve() {// 2 3 5 7 11 13 17 31 37 71 73 79 97 /*113 131 197 199 311 337 373 719 733 919 971 991 1193 1931 3119 3779 7793 7937 9311 9377 11939 19391 19937 37199 39119 71993 91193 93719 93911 99371 193939 199933 319993 331999 391939 393919 919393 933199 939193 939391 993319 999331 */// 共55个满足条件的int ans = 13;for (int i = 100; i <= 1000000; ++i) {string k = to_string(i);string s = k;if (!check(stoi(k))) continue; // 看一下初始数字是不是素数 不是就直接看下一个int sum = 1;s = s.substr(1) + s[0];while (s != k) {if (check(stoi(s))) ++sum;s = s.substr(1) + s[0];}if (sum == k.size()) {cout << i << " ";++ans;}}cout << "\n";cout << ans << "\n";}int main() {ios::sync_with_stdio(false);cin.tie(nullptr);int tt = 1; // cin >> tt;while (tt--) {solve();}return 0;
}
筛法
#include <bits/stdc++.h>using namespace std;using ll = long long;const int N = 1e6 + 1;int b[N];
bool a[N];int k = 1;
void EulerScreen() { // 欧拉筛一百万以内的素数memset(a, true, sizeof(a));a[1] = false; // 1 不是素数for (int i = 2; i <= N - 1; ++i) {if (a[i]) b[k++] = i; for (int j = 1; j <= k && i * b[j] <= N - 1; ++j) {a[i * b[j]] = false;if (i % b[j] == 0) break;}}
}// 检查是否是圆周素数
bool check(int x) {string s = to_string(x);int n = s.size();for (int i = 0; i < n; ++i) {if (!a[stoi(s)]) return false;rotate(s.begin(), s.begin() + 1, s.end());}return true;
}void solve() {int ans = 0;EulerScreen();for (int i = 1; i <= k - 1; ++i) {if (check(b[i])) {cout << b[i] << " ";++ans;}}cout <<"\n";cout << ans << "\n";}int main() {ios::sync_with_stdio(false);cin.tie(nullptr);int tt = 1; // cin >> tt;while (tt--) {solve();}return 0;
}
rotate函数使用
std::rotate
是 C++ 标准库中一个函数,用于将指定范围内的元素按照一定规则进行循环移动。
将 [first, last) 范围内的元素进行旋转,使得 middle 指向的元素变为新的第一个元素,其余元素按顺序向后移动,原本的第一个元素移到最后。
语法
std::rotate(first, middle, last);
其中参数含义如下
first:
要旋转的范围的起始迭代器。middle:
新范围的第一个元素(原本是范围中的某个元素)。middle:
新范围的第一个元素(原本是范围中的某个元素)。
示例代码
#include <bits/stdc++.h>using namespace std;using ll = long long;void solve() {vector<int> v = {1, 3, 5, 6, 8};rotate(v.begin(), v.begin() + 1, v.end());for (int x : v) {cout << x << " ";}// 输出3 5 6 8 1cout << "\n";
}int main() {ios::sync_with_stdio(false);cin.tie(nullptr);int tt = 1; // cin >> tt;while (tt--) {solve();}return 0;
}