列表

详情


HJ28. 素数伴侣

描述

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

输入:

有一个正偶数 n ,表示待挑选的自然数的个数。后面给出 n 个具体的数字。

输出:

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


数据范围: ,输入的数据大小满足

输入描述

输入说明
1 输入一个正偶数 n
2 输入 n 个整数

输出描述

求得的“最佳方案”组成“素数伴侣”的对数。

示例1

输入:

4
2 5 6 13

输出:

2

示例2

输入:

2
3 6

输出:

0

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C 解法, 执行用时: 2ms, 内存消耗: 296KB, 提交时间: 2021-09-26

#include <stdio.h>
#include <string.h>
#include <math.h>
char used[88], match[88][88];
int even[88], idx_e, odd[88], idx_o, cp[88], cnt, *small, idx_s, *big, idx_b;
int IsPrime(int num)
{
	int i=2, j=sqrt(num);
	for( ; i<=j; i++){
		if(num%i) continue;
		return 0;
	}
	return 1;
}
int DG(int n)
{
	int i;
	for(i=0; i<idx_b; i++){
		if( match[n][i] && !used[i] ){
			used[i] = 1;
			if( cp[i] == -1 ){ cp[i] = n;   cnt++;   return 1; }
			if( DG(cp[i]) ){ cp[i] = n;   return 1; }
		}
	}
	return 0;
}
int main(void)
{
	int i, j, tmp, num;
	for( ; scanf("%d", &num)!=EOF; ){
        if(num & 0x1) return -1008611;
        
		idx_o = idx_e = 0;
		for(i=0; i<num; i++){
			scanf("%d", &tmp);
			if(tmp&1){ odd[idx_o++] = tmp;   continue; }
			even[idx_e++] = tmp;
		}
		
		if(idx_o>idx_e){ small=even;   idx_s=idx_e;   big=odd;   idx_b=idx_o; }
		else{ small=odd;   idx_s=idx_o;   big=even;   idx_b=idx_e; }
		for(i=0; i<idx_s; i++){
			tmp = small[i];
			for(j=0; j<idx_b; j++){
				if( IsPrime( tmp+big[j] ) ){ match[i][j] = 1;   continue; }
				match[i][j] = 0;
			}
		}
		memset(cp, -1, idx_b*sizeof(int));
		for(i=cnt=0; i<idx_s; i++){
			memset(used, 0, idx_b*sizeof(char));
			DG(i);
		}
		printf("%d\n", cnt);
	}
	return 0;
}

C 解法, 执行用时: 2ms, 内存消耗: 316KB, 提交时间: 2021-12-06

#include <stdio.h>
#include <string.h>
#include <math.h>
char used[88], match[88][88];
int even[88], idx_e, odd[88], idx_o, cp[88], cnt, *small, idx_s, *big, idx_b;
int IsPrime(int num)
{
	int i=2, j=sqrt(num);
	for( ; i<=j; i++){
		if(num%i)
            continue;
		return 0;
	}
	return 1;
}
int DG(int n)
{
	int i;
	for(i=0; i<idx_b; i++){
		if( match[n][i] && used[i]==0 ){
			used[i] = 1;
			if(cp[i] == -1){
                cp[i] = n;
                cnt++;
                return 1;
            }
			if(DG(cp[i])){
                cp[i] = n;
                return 1;
            }
		}
	}
	return 0;
}
int main(void)
{
	int i, j, tmp, num;
	for( ; scanf("%d", &num)!=EOF; ){
        if(num & 1)
            return -1;
		idx_o = idx_e = 0;
		for(i=0; i<num; i++){
			scanf("%d", &tmp);
			if(tmp&1)
                odd[idx_o++] = tmp;
            else
			    even[idx_e++] = tmp;
		}
		if(idx_o>idx_e){
            small=even;
            idx_s=idx_e;
            big=odd;
            idx_b=idx_o;
        }
		else{
            small=odd;
            idx_s=idx_o;
            big=even;
            idx_b=idx_e;
        }
		for(i=0; i<idx_s; i++){
			tmp = small[i];
			for(j=0; j<idx_b; j++){
				if(IsPrime(tmp+big[j])){
                    match[i][j] = 1;
                    continue;
                }
				match[i][j] = 0;
			}
		}
		memset(cp, -1, idx_b*sizeof(int));
		for(i=cnt=0; i<idx_s; i++){
			memset(used, 0, idx_b*sizeof(char));
			DG(i);
		}
		printf("%d\n", cnt);
	}
	return 0;
}

上一题