CSU1552: Friends(快速判断大数是不是素数+二分匹配)

1552: Friends

Time Limit: 3 Sec  Memory Limit: 256 MB

Submit: 187  Solved: 43

[Submit][Status][Web
Board
]

Description

On an alien planet, every extraterrestrial is born with a number. If the sum of two numbers is a prime number, then two extraterrestrials can be friends. But every extraterrestrial can only has at most one friend. You are given all number of the extraterrestrials,
please determining the maximum number of friend pair.

Input

There are several test cases.

Each test start with positive integers N(1 ≤ N ≤ 100), which means there are N extraterrestrials on the alien planet.

The following N lines, each line contains a positive integer pi ( 2 ≤ pi ≤10^18),indicate the i-th extraterrestrial is born with pi number.

The input will finish with the end of file.

Output

For each the case, your program will output maximum number of friend pair.

Sample Input

3
2
2
3

4
2
5
3
8

Sample Output

1
2

HINT

当遇到匹配问题时,而且只能用一次,这时应想一下二分最大匹配。

#include<stdio.h>
#include<math.h>
#include <algorithm>
#include<string.h>
#include <time.h>
using namespace std;
#define ll long long
//-----大素数的判断-------
ll mult_mod(ll a,ll b,ll n)
{
    ll s=0;
    while(b)
    {
        if(b&1) s=(s+a)%n;
        a=(a+a)%n;
        b>>=1;
    }
    return s;
}

ll pow_mod(ll a,ll b,ll n)
{
    ll s=1;
    while(b)
    {
        if(b&1) s=mult_mod(s,a,n);
        a=mult_mod(a,a,n);
        b>>=1;
    }
    return s;
}

int Prime(ll n)
{
    ll u=n-1,pre,x;
    int i,j,k=0;
    if(n==2||n==3||n==5||n==7||n==11)  return 1;
    if(n==1||(!(n%2))||(!(n%3))||(!(n%5))||(!(n%7))||(!(n%11)))   return 0;
    for(;!(u&1);k++,u>>=1);
    srand((ll)time(0));
    for(i=0;i<5;i++)
    {
        x=rand()%(n-2)+2;
        x=pow_mod(x,u,n);
        pre=x;
        for(j=0;j<k;j++)
        {
            x=mult_mod(x,x,n);
            if(x==1&&pre!=1&&pre!=(n-1))
                return 0;
            pre=x;
        }
        if(x!=1)  return 0;
    }
    return 1;
}
int n,ok[105][105],mark[105],vist[105];
int DFS(int x)
{
    for(int i=1;i<=n;i++)
    if(ok[x][i]&&vist[i]==0)
    {
        vist[i]=1;
        if(mark[i]==0||DFS(mark[i]))
        {
            mark[i]=x; return 1;
        }
    }
    return 0;
}
int main()
{

    ll a[105];
    while(scanf("%d",&n)>0)
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
        }
        memset(ok,0,sizeof(ok));
        for(int i=1;i<n;i++)
        for(int j=i+1;j<=n;j++)
        if(Prime(a[i]+a[j]))
            ok[i][j]=ok[j][i]=1;

        int ans=0;
        memset(mark,0,sizeof(mark));
        for(int i=1;i<=n;i++)
        {
            memset(vist,0,sizeof(vist));
            ans+=DFS(i);
        }

        printf("%d\n",ans/2);
    }
}
时间: 2024-11-01 01:19:14

CSU1552: Friends(快速判断大数是不是素数+二分匹配)的相关文章

————————————————素数的快速判断方法————————————————————

1:   当n>=6   且n-1和n+1是孪生素数的话那么n一定是6的倍数. 证明:因为n-1和n+1为素数----① 所以n-1和n+1为奇数----② 所以n是偶数是2的倍数--③ 假设n不是3的倍数,得: n=3x+1或n=3x+2, 如果n=3x+1则n-1=3x这和①违背所以n≠3x+1 如果n=3x+2,zen+1=3(x+1)与①违背 所以假设不成立,既n是3的倍数又有②结论则n是6的倍数. 由上面的规律可以推出下面的结论: 如x>=1且n=6x+1或n=6x+1,那么n一定不

埃氏筛法(快速筛选n以内素数的个数)

给你一个数n,请问n以内有多少个素数?(n <= 10e7) 一般来说,要是对一个整数进行素数判断,首先想到的是写个函数判断是否为素数,然后调用这个函数,时间复杂度为O(n^(½)),但是要求n以内的素数就略显吃力了. 要是求n以内的素数个数的话,可以用埃式筛选.预处理一下. 先看下面的代码: 1 /* 2 |埃式筛法| 3 |快速筛选素数| |15-7-26| 4 */ 5 #include <iostream> 6 #include <cstdio> 7 using na

POJ2109 高精度(含大数开方)+二分

1 高精度(含大数开方)+二分 一个技巧和三点注意: 技巧:假设k^n=p;(k的n次方),那么p的位数/n得到的是k的位数!例如:n=7,p=4357186184021382204544,p的位数为22,用22/7的结果向上取整,得到4,即为k的位数,也就是说k的取值范围是1000~9999.(引自code_pang)不利用这一点,高精度+直接二分,也会超时.用这一个技巧合理缩小二分的范围. 注意:看code的main中的注释. (二分思想不熟练,因为二分算法很高效,所以一定要暴力点直接确定l

vuex中filter的使用 &amp;&amp; 快速判断一个数是否在一个数组中

vue中filter的使用 computed: mapState({ items: state => state.items.filter(function (value, index, arr) { return index < 5 }) }), 如上所示,对于vuex,我们在使用mapState获取state时, 可以使用filter来过滤其中的元素,在filter的回调函数中接受三个参数,第一个是value,即每一个元素的值: 第二个是index, 即每一个元素所在的index, 第三个

python读取一个文件的每一行判断是否为素数,并把结果写到另一个文件中

刚刚学习python的菜鸟,这道题包括:文件的读写,python的参数调用,异常的使用,函数的使用 创建一个文本文件inti_prime.txt 执行命令:python Prime.py init_prime.txt result_prime.txt 会生成一个result_prime.txt文件 1 #-*- coding:UTF-8 -*- 2 #读取一个文件的每一行,每一行为一个数字 3 #判断数字是不是素数 4 #并打印结果到另外一个文件 5 #输入文件名和输出文件名用参数的形式 6 i

hdu2444 The Accomodation of Students(判断二分匹配+最大匹配)

//判断是否为二分图:在无向图G中,如果存在奇数回路,则不是二分图.否则是二分图. //判断回路奇偶性:把相邻两点染成黑白两色,如果相邻两点出现颜色相同则存在奇数回路.也就是非二分图. # include <stdio.h> # include <string.h> # include <algorithm> using namespace std; int vis[210],map[210][210],cott[210]; int c[210]; int flag,n

js快速判断IE浏览器(兼容IE10与IE11)

在很多时候,我们一般采用navigator.userAgent和正则表达来判断IE浏览器版本,下面介绍用IE浏览器中不同特性来判断IE浏览器   1 判断IE浏览器与非IE 浏览器 IE浏览器与非IE浏览器的区别是IE浏览器支持ActiveXObject,但是非IE浏览器不支持ActiveXObject.在IE11浏览器还没出现的时候我们判断IE和非IE经常是这么写的 ? 1 2 3 function isIe(){        return window.ActiveXObject ? tr

如何利用一些小工具快速判断电脑是否中毒

在这个网上支付流行的时代,人们最害怕的事情莫过于电脑病毒了.以前不装杀毒软件"裸奔"是一件再平常不过的事情.现在估计很少有人敢这么干了,生怕自己网银里的钱被别人神不知鬼不觉的偷走了.今天,我就写一篇新手小白文来告诉大家如何快速判断自己的电脑是否已经中毒. 在讨论如何判断电脑是否中毒之前,我们先来说一下病毒常见的一些的特征. 1. 计算器里运行的各种程序我们都可以找到相对应的进程.病毒的进程名通常会比较奇怪.比如一串奇怪的随机名,再比如伪装成一些系统进程名.举个栗子,svchost.ex

快速幂+大数取模

快速幂+大数取模 快速幂,其实就是求(a^b)% p,(其中a,b,p都比较大在int范围内)这类问题. 首先要知道取余的公式:(a*b)%p=(a%p*b%p)%p. 那么幂不就是乘机的累积吗,由此给出代码: int fast(int a,int b,int p) {   long long a1=a,t=1; while(b>0) { if(b&1)          /如果幂b是奇数多乘一次,因为后边会除2变偶数,(7/2=3) t=(t%p)*(a1%p)%p; a1=(a1%p)*