素数伴侣C++
题目描述
若两个正整数的和为素数,则这两个正整数称之为“素数伴侣”,如2和5、6和13,它们能应用于通信加密。现在密码学会请你设计一个程序,从已有的 N ( N 为偶数)个正整数中挑选出若干对组成“素数伴侣”,挑选方案多种多样,例如有4个正整数:2,5,6,13,如果将5和6分为一组中只能得到一组“素数伴侣”,而将2和5、6和13编组将得到两组“素数伴侣”,能组成“素数伴侣”最多的方案称为“最佳方案”,当然密码学会希望你寻找出“最佳方案”。
输入:
有一个正偶数 n ,表示待挑选的自然数的个数。后面给出 n 个具体的数字。
输出:
输出一个整数 K ,表示你求得的“最佳方案”组成“素数伴侣”的对数。
数据范围: ,输入的数据大小满足
#include<iostream>
#include<algorithm>
#include <vector>
using namespace std;
vector<int> cx,cy;//分别存储奇数偶数;即求二分图的最大匹配;
vector<int> vx, vy;//记录各自的匹配;
bool visy[100] = {false};//记录偶数的访问情况
bool issu(int x,int y)//判断是否素数;
{
int a = x + y;
for(int i=2;i*i<=a;++i)
{
if (a % i == 0) return false;
}
return true;
}
int path(int step)//对第step个奇数寻找匹配;
{
for(int i=0;i<cy.size();++i)
{
if(issu(cx[step],cy[i])&& !visy[i])//若寻找到一个素数伴侣且未访问过
{
visy[i] = true;
if(vy[i]==-1||path(vy[i]))//若该偶数还没匹配,或它的匹配可以找到另外一个偶数匹配;
{
vx[step] = i;
vy[i] = step;
return 1;
}
}
}
return 0;
}
int math()
{
int p = 0;
for(int i=0;i<cx.size();++i)
{
if(vx[i]==-1)
{
for(int j=0;j<100;++j)visy[j]=false;
p += path(i);//可以直接加的原因是vx,vy更新时候只会更新或增加,不会减小;
}
}
return p;
}
int main()
{
int n, x;
while(scanf("%d",&n)!=EOF)
{
for(int i=0;i<n;++i)
{
scanf("%d", &x);
if (x % 2 == 1)cx.push_back(x);
else cy.push_back(x);
}
vx.assign(cx.size(),-1); vy.assign(cy.size(), -1);
x=math();
cout << x<<endl;
cx.clear();cy.clear();for(int j=0;j<100;++j)visy[j]=false;
}
return 0;
}