题目描述
若两个正整数的和为素数,则这两个正整数称之为“素数伴侣”,如2和5、6和13,它们能应用于通信加密。现在密码学会请你设计一个程序,从已有的N(N为偶数)个正整数中挑选出若干对组成“素数伴侣”,挑选方案多种多样,例如有4个正整数:2,5,6,13,如果将5和6分为一组中只能得到一组“素数伴侣”,而将2和5、6和13编组将得到两组“素数伴侣”,能组成“素数伴侣”最多的方案称为“最佳方案”,当然密码学会希望你寻找出“最佳方案”。
输入:
有一个正偶数N(N≤100),表示待挑选的自然数的个数。后面给出具体的数字,范围为[2,30000]。
输出:
输出一个整数K,表示你求得的“最佳方案”组成“素数伴侣”的对数。
因为大于2的素数必定由一个奇数和一个偶数构成,因此可以将输入的书分成奇偶两类,“最佳方案”就是找到奇偶配对构成素数最多的一种方案,因此这题目就变成了二分图的最佳匹配问题。这里参考了大神写的匈牙利算法分析,http://blog.csdn.net/dark_scope/article/details/8880547。
具体程序:
#include<iostream>
using namespace std;
unsigned int odd_array[30000], even_array[30000], match[30000], odd_num = 0, even_num = 0;
bool used[30000];
bool If_Prime(int n)
{
for (int i = 2; i <= sqrt(n); i++)
{
if (n % i == 0)
return false;
}
return true;
}
bool find(unsigned int x)
{
for (int n= 0; n < even_num; n++)
{
if (If_Prime(x + even_array[n]) && used[n] == false)
{
used[n] = 1;
if (match[n] == 0 || find(match[n]))
{
match[n] = x;
return true;
}
}
}
return false;
}
int main()
{
unsigned int N, n, m = 0, match_num = 0;
for (int i = 0; i < 30000; i++)
used[i] = match[i] = 0;
cin >> N;
for (int i = 0; i < N; i++)
{
cin >> n;
if (n % 2 == 0)
even_array[even_num++] = n;
else
odd_array[odd_num++] = n;
}
for (m = 0; m < odd_num; m++)
{
memset(used, 0, sizeof(used));
if (find(odd_array[m]))
match_num += 1;
}
cout << match_num << endl;
}