最小素数对
题目描述
任意一个偶数(大于2)都可以由2个素数组成,组成偶数的2个素数有很多种情况,本题目要求输出组成指定偶数的两个素数差值最小的素数对。
输入
输入一个偶数
输出
输出两个素数。
样例输入
20
样例输出
7
13
PS:初次见到这个题目的时候我是想先把所有的情况都求出来都放到结构体数组中,然后通过排序把最小素数对排在数组最开头,最后输出即可
这里需要值得注意的是,两个数都要判断是否是素数,不能因为判断了一个就不判断另外一个。
最后看了大佬的代码之后才明白自己的想法完全多余了,不仅麻烦而且冗杂不过先附上我的代码
#include <bits/stdc++.h>
using namespace std;
struct node
{
int x, y, z;
bool operator<(const node d) const
{
if (z != d.z)
return z < d.z;
return x > d.x;
}
} w[10000];
int judge(int x)
{
int m = sqrt(x);
for (int i = 2; i <= m; ++i)
if (x % i == 0)
return true;
return false;
}
int main()
{
int n;
while (~scanf("%d", &n))
{
int cnt = 0;
for (int i = 2; i <= n / 2; ++i)
{
if (!judge(i) && !judge(n - i))
{
w[++cnt].x = i;
w[cnt].y = n - i;
w[cnt].z = n - 2 * i;
}
}
sort(w + 1, w + cnt + 1);
printf("%d\n%d\n", w[1].x, w[1].y);
}
return 0;
}
大佬的代码极其简单,而且非常易于理解,用的是更新的思想不断地用新值覆盖老值,其实这里还隐藏了另外一种思想,既然从头开始需要不断地向后遍历,因为最后出现的是最好的,那么我们可以反过来,正所谓正难则反吗,我们反过来只需要遍历一次就break跳出就行,就不用像正向遍历多次
有时候为了代码的运行速度,我们尽量不要用函数,因为函数很慢,如果非要用的话,那就定义在循环外面,那样函数只需要运行一次,否则在循环里面,每执行一次就计算函数一次,大佬的代码就省去了sqrt函数,所以非常的简洁高效
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5 + 5;
bool ju(int x)
{
for (int i = 2; i * i <= x; ++i)
{
if (x % i == 0)
return false;
}
return true;
}
int main()
{
int n, ans1, ans2;
scanf("%d", &n);
for (int i = 2; i <= n / 2; ++i)
{
if (ju(i) && ju(n - i))
{
ans1 = i, ans2 = n - i;
}
}
printf("%d\n%d\n", ans1, ans2);
return 0;
}
如果你认定一件喜欢,低着头好好做就好,总是抬起头听各种人的建议,容易耽误手里的活。你十分相信他们的建议都是为你好, 只是,他们忘了, 他们不是你,但是,你应该始终记得你是谁,你有什么,你要什么。 |
---|