素数伴侣

题目描述
若两个正整数的和为素数,则这两个正整数称之为“素数伴侣”,如2和5、6和13,它们能应用于通信加密。现在密码学会请你设计一个程序,从已有的N(N为偶数)个正整数中挑选出若干对组成“素数伴侣”,挑选方案多种多样,例如有4个正整数:2,5,6,13,如果将5和6分为一组中只能得到一组“素数伴侣”,而将2和5、6和13编组将得到两组“素数伴侣”,能组成“素数伴侣”最多的方案称为“最佳方案”,当然密码学会希望你寻找出“最佳方案”。

输入:

有一个正偶数N(N≤100),表示待挑选的自然数的个数。后面给出具体的数字,范围为[2,30000]。

输出:

输出一个整数K,表示你求得的“最佳方案”组成“素数伴侣”的对数。

方法一:

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
//二分图匹配,匈牙利算法
vector<int> evenArr, oddArr;
int match[101];
int book[101]; 
bool IsPrime(int n)
{
    int n_sqrt = sqrt(n);
    for(size_t i = 2; i <= n_sqrt; i++)
        if(n%i == 0)
            return false;
    return true;
}
bool dfs(int u)//深度优先搜索
{
    for(int i = 0; i < oddArr.size(); i++)
    {
        if(book[i] == 0 && IsPrime(evenArr[u] + oddArr[i]))
        {
            book[i] = 1;//标记点i已经访问过
            //如果点i未被配对或者找到了新的配对
            if(match[i] == -1 || dfs(match[i]))
            {
                //更新配对关系;
                match[i] = u;
                return true;
            }
        }
    }
    return false;
}
int main()
{
    int n;
    while(cin>>n)
    {
        int ele, sum = 0;
        for(int i = 0; i < n; i++)
        {
            cin >> ele;
            if(ele % 2 == 0)
                evenArr.push_back(ele);//偶数
            else
                oddArr.push_back(ele);//奇数
        }
        for(int i = 0; i < n; i++) 
            match[i] = -1; 
        for(int i = 0; i < evenArr.size(); i++)
        {
            for(int j = 0; j < oddArr.size(); j++) 
                book[j] = 0;//清空上次搜索时的标记
            if(dfs(i)) 
                sum++;//寻找增广路径,如果找到,配对数加1
        }
        cout << sum << endl;
        evenArr.clear();
        oddArr.clear();
    }
    return 0;
}

方法二:

#include <iostream>
#include <vector>
#include<cmath>
using namespace std;
vector<int> cx(100, -1);
vector<int> cy(100, -1);
vector<int> visit(100, 0); 
int t[100][100] = { 0 };
//判断是否是素数
bool isprime(int n)
{
    int m = sqrt(n);
    int flag = 0;
    for (int i = 2; i <= m; i++)
    {
        if (n % i == 0)
        {
            return false;
        }
    }
    return true;
}
//寻找增广路径
int dfs(int u)
{
    for(int i = 0; i < cx.size();i++)
    {
        if (t[u][i] && !visit[i])
        {
            visit[i] = 1;
            if (cy[i] == -1 || dfs(cy[i])) ////
            {
                cx[u] = i; ////
                cy[i] = u;
                return 1;
            }
        }
    }
    return 0;
}

int main()
{
    int N;
    vector<int> cj;
    vector<int> co;
    while (cin >> N)
    {
        int tmp;
        int ans = 0;
        for (int i = 0; i < N; i++)
        {
            cin >> tmp;
            if (tmp % 2 != 0) 
                cj.push_back(tmp); 
            else 
                co.push_back(tmp); 
        }
        for (int i = 0; i < cj.size(); i++)
            for (int j = 0; j <co.size(); j++)
            {
                if (isprime(cj[i] + co[j])) 
                    t[i][j] = 1; 
            } 
        //匈牙利算法
        for (int i = 0; i < cj.size(); i++)
        {
            if(cx[i] == -1)
            {
              for(int j = 0; j < visit.size();j++) 
                  visit[j] = 0;
              ans += dfs(i);
            }
        }
        cout << ans << endl;      
        for(int i = 0; i < 100;i++) 
           for(int j = 0; j < 100;j++) 
               t[i][j] = 0;
        for(int i =0; i < 100;i++) 
            cx[i] = cy[i] = -1;
        cj.clear(); 
        co.clear(); 
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zrh_CSDN/article/details/81411672