素数伴侣

素数伴侣

http://www.nowcoder.com/questionTerminal/b9eae162e02f4f928eac37d7699b352e

先声明,本解法用的不是前面提过的匈牙利解法。那个我还不会,我只是想把自己的解法先捣鼓通了再去学匈牙利算法。
再顺便备注一条,希望能帮助到被“输出为空”这个错误提示恶心到的朋友们:在获取输入的时候,一定要用while(sc.hasNext())循环获取。因为有的题目你不用while,它会每个输入案例都重新启动你的代码,然后输入,但这道题你自己不用while,就没法获取到后面的输入了。因为这,这道题第二个案例提示我输出为空时我好久没想到原因在哪。
言归正传,我的思路是这样:
1.只有奇数+偶数才可能得到素数。
2.获取n个整数时,奇数从前往后放,偶数从后往前放,这样,奇数都在前面,偶数都在后面。
3.每个奇数去匹配后面的偶数,和为素数的都记录下来。
4.如果一个奇数只能与一个偶数A匹配,那就把其他奇数的匹配偶数里的这个偶数A都删掉。如果在删的过程中,某个奇数的匹配偶数个数为0,把这个奇数删掉。
5.最后剩下的,一定是每个奇数至少匹配两个偶数,每个偶数至少可以匹配一个奇数。这样的话,他们匹配的最大数量一定是奇数个数和偶数个数中的较小值。
6.可以将已经处理过的这种1对1的组合单独存放,以免对第4步产生干扰。这样,最大值应该等于第5步中的较小值加上单独存放的个数。
7.返回最大值。
代码如下,欢迎大家提出改进意见和思路漏洞,共同探讨:

import java.util.*;
public class Main{

    public static ArrayList<ArrayList<Integer>> aal;
    public static ArrayList<Integer> only;
    public static int max;

    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()) {
            int sum=sc.nextInt();
            int[] all=new int[sum];
            aal=new ArrayList<ArrayList<Integer>>();
            int loc=0,loc2=sum-1;
            for(int i=0;i<sum;i++){
                int n=sc.nextInt();
                if(n%2==0) {
                    all[loc2--]=n;
                }else {
                    all[loc++]=n;
                }          
            }
            for(int i=0;i<loc;i++) {
                ArrayList<Integer> al=new ArrayList<Integer>();
                al.add(all[i]);
                for(int j=loc;j<sum;j++) {
                    if(isPrime(all[i]+all[j])){
                        al.add(all[j]);
                    }
                }
                if(al.size()>1) {
                    aal.add(al);
                }
            }
            max=0;
            seek();
            System.out.println(max);
        }
    }

    public static boolean isPrime(int n){
        boolean b=true;
        for(int i=2;i<=Math.pow(n, 0.5);i++){
            if(n%i==0){
                b=false;
                break;
            }
        }
        return b;
    }

    public static void seek(){
        only=new ArrayList<Integer>();
        ArrayList<Integer> al;
        do {
            al=null;
            for(int i=0;i<aal.size();i++) {
                if(aal.get(i).size()==2) {
                    al=aal.get(i);
                    aal.remove(i);
                    break;
                }
            }
            if(al==null) {
                break;
            }
            int n=al.get(1);
            only.add(n);
            for(int i=0;i<aal.size();i++) {
                ArrayList<Integer> buf=aal.get(i);
                for(int j=1;j<buf.size();j++) {
                    if(buf.get(j)==n) {
                        buf.remove(j);
                        if(buf.size()==1) {
                            aal.remove(i);
                            i--;
                        }
                        break;
                    }
                }
            }
        }while(true);
        HashSet<Integer> hs=new HashSet<Integer>();
        for(int i=0;i<aal.size();i++) {
            al=aal.get(i);
            for(int j=1;j<al.size();j++) {
                hs.add(al.get(j));
            }
        }
        int len=only.size();
        int len2=aal.size();
        int len3=hs.size();
        if(len2>len3) {
            max=len+len3;
        }else {
            max=len+len2;
        }
    }
}
全部评论
好吧,是有漏洞的。 10 1 3 9 11 35 2 4 6 8 12 这个就不行,而且我也想不出怎么排除这个状况,看来只能用匈牙利了
点赞 回复 分享
发布于 2020-05-11 15:10

相关推荐

mq2:我倒是觉得这种敞亮一点好。能接受就去不能就不去呗。 完了跟现在“正常”公司一样,hr说的天花乱坠,进去一看根本就是996核动力牛马,想走又没应届生身份了。岂不是更糟。
点赞 评论 收藏
分享
野猪不是猪🐗:把你的学校加黑,加粗,斜体,下划线,描边,内阴影,内发光,投影,外发光,再上渐变色,居中,放大到最大字号,再把简历里其它内容删了,就行了
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务