题解 | #素数伴侣#
素数伴侣
http://www.nowcoder.com/practice/b9eae162e02f4f928eac37d7699b352e
匈牙利算法,质数不能是两个偶数相加或两个奇数相加,所以思路是把它们分为偶数和奇数,我看到有的同学用到了矩阵的秩,这个是有问题的,首先有一个判断素数的函数,其次有一个素数的邻接矩阵,左边偶数集合对应矩阵的行,右边奇数对应矩阵的列,还要一个配对数组,这个用来反映奇数集合配对的偶数序号,还要一个访问数组判断奇数集合是否被访问,每遍历一个左边偶数集合的点时,访问数组都要重置。
本题用到通过求最多的素数伴侣会抽象出二分图模型
#include <string>
#include <map>
#include <vector>
#include <cmath>
using namespace std;
bool isprimer(int primer){
if(primer>=2){
int i=2;
for( i =2;i<=sqrt(primer);i++){
if(primer%i!=0) continue;
else return false;
}
if(i>sqrt(primer)) return true;
}
return false;
}
void createmap(const vector<int>&even,const vector<int>&odd,vector<vector<int> >&m){
for(int i = 0;i<even.size();i++){
for(int j = 0;j<odd.size();j++){
if(isprimer(even[i]+odd[j])) m[i][j]=1;
else m[i][j]=-1;
}
}
}
bool match_success (int i ,vector<int> &visit,vector<int> &match,
vector<vector<int>> &m) {
for(int j = 0;j<m[i].size();j++){
if((m[i][j]==1)&&(visit[j]==-1)){
visit[j]=1;
if((match[j]==-1)||match_success(match[j], visit, match, m)){
match[j]=i;
return true;
}
}
}//外层for
return false;
}
int main() {
string str;
int N = 0;
int x = 0;
while (cin >> N) {
int cnt_pair = 0;
vector<int> odd,even;
int Nprev=N;
vector<vector<int>> m(N,vector<int>(N,-1));
vector<int> match(N,-1);
while (N--) {
cin >> x;
if(x%2==0) even.push_back(x);
else odd.push_back(x);
}
createmap(even,odd,m);
for(int i =0;i<even.size();i++){
vector<int> visit(m[i].size(),-1);
if(match_success(i, visit, match, m))
cnt_pair++;
}
cout << cnt_pair << endl;
}
}