csu 1552(米勒拉宾素数测试+二分图匹配)

1552: Friends

Time Limit: 3 Sec  Memory Limit: 256 MB
Submit: 723  Solved: 198
[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

米勒拉宾大素数判断+二分图匹配
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
#define N 505
typedef long long LL;
LL qpow(LL a,LL b,LL r)//快速幂
{
    LL ans=1,buff=a;
    while(b)
    {
        if(b&1)ans=(ans*buff)%r;
        buff=(buff*buff)%r;
        b>>=1;
    }
    return ans;
}
bool Miller_Rabbin(LL n,LL a)//米勒拉宾素数测试
{
    LL r=0,s=n-1,j;
    if(!(n%a))
        return false;
    while(!(s&1)){
        s>>=1;
        r++;
    }
    LL k=qpow(a,s,n);
    if(k==1)
        return true;
    for(j=0;j<r;j++,k=k*k%n)
        if(k==n-1)
            return true;
    return false;
}
bool IsPrime(LL n)//判断是否是素数
{
    LL tab[]={2,3,5,7};
    for(int i=0;i<4;i++)
    {
        if(n==tab[i])
            return true;
        if(!Miller_Rabbin(n,tab[i]))
            return false;
    }
    return true;
}
int n;
int graph[N][N];
int linker[N];
bool vis[N];
LL a[N];
bool dfs(int u){
    for(int i=1;i<=n;i++){
        if(graph[u][i]&&!vis[i]){
            vis[i] = true;
            if(linker[i]==-1||dfs(linker[i])){
                linker[i] = u;
                return true;
            }
        }
    }
    return false;
}
int main()
{
    while(scanf("%d",&n)!=EOF){
        for(int i=1;i<=n;i++){
            scanf("%lld",&a[i]);
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++) graph[i][j] = 0;
        }
        for(int i=1;i<=n;i++){
            for(int j=i+1;j<=n;j++){
                if(IsPrime(a[i]+a[j])){
                    graph[i][j] = graph[j][i] = 1;
                }
            }
        }
        int ans = 0;
        memset(linker,-1,sizeof(linker));
        for(int i=1;i<=n;i++){
            memset(vis,false,sizeof(vis));
            if(dfs(i)) ans++;
        }
        printf("%d\n",ans/2);
    }
    return 0;
}
时间: 2024-10-13 22:27:47

csu 1552(米勒拉宾素数测试+二分图匹配)的相关文章

POJ 1811Prime Test(米勒拉宾素数测试)

直接套用模板,以后接着用 这里还有一个素因子分解的模板 1 #include <map> 2 #include <set> 3 #include <stack> 4 #include <queue> 5 #include <cmath> 6 #include <ctime> 7 #include <vector> 8 #include <cstdio> 9 #include <cctype> 10

Miller_Rabin(米勒拉宾)素数测试

2018-03-12 17:22:48 米勒-拉宾素性检验是一种素数判定法则,利用随机化算法判断一个数是合数还是可能是素数.卡内基梅隆大学的计算机系教授Gary Lee Miller首先提出了基于广义黎曼猜想的确定性算法,由于广义黎曼猜想并没有被证明,其后由以色列耶路撒冷希伯来大学的Michael O. Rabin教授作出修改,提出了不依赖于该假设的随机化算法. 问题描述:对于大整数N,判断其是否为素数. 问题求解: 若N为偶数,直接返回false,若N是奇数,则进行以下几步进行判断: 将N -

Miller_Rabin(米勒拉宾)素数测试算法

首先需要知道两个定理: 1: 费马小定理: 假如p是素数,且gcd(a,p)=1,那么 a(p-1)≡1(mod p). 2:二次探测定理:如果p是素数,x是小于p的正整数,且,那么要么x=1,要么x=p-1. 证明:这是显然的,因为相当于p能整除,也即p能整除(x+1)(x-1). 由于p是素数,那么只可能是x-1能被p整除(此时x=1) 或 x+1能被p整除(此时x=p-1). 接着 如果a^(n-1) ≡ 1 (mod n)成立,Miller-Rabin算法不是立即找另一个a进行测试,而是

米勒-拉宾素性测试学习

之前一直对于这个神奇的素性判定方法感到痴迷而又没有时间去了解.借着学习<信息安全数学基础>将素性这一判定方法学习一遍. 首先证明一下费马小定理. 若p为素数,且gcd(a, p)=1, 则有 a^(p-1) = 1 (mod p) 基于以下定理 若(a, p)=1,{x| (x, p)=1}为模p下的一个完全剩余系,则{ax| (x, p)=1}也为模p下的一个完全剩余系. 又{0, 1, 2, ... p-1}为模p下一个剩余系   因此有, {a*0, a*1, a*2, ... a*(p

米勒-拉宾(MillerRabbin)素性测试算法

首先,在了解米勒-拉宾素性测试之前,我们要先了解费马小定理. 关于费马小定理就不再细说原理和证明了,应用非常广泛. 费马小定理中说  若p是质数  则有 a的(p-1)次方在(mod p)的情况下 恒等于1   数学表达式--->  a^(p-1) ≡ 1 (mod p) 然后我们要注意: p若是质数  则满足费马小定理  但是  满足费马小定理  并不能证明p就是质数 有些数字 满足费马小定理,但是并不是质数  他们叫做伪质数(伪素数的个数是无穷的) 那么 知道了这些  算法就很好理解了 一个

2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 B. Goldbach-米勒拉宾素数判定(大素数)

若干年之前的一道题,当时能写出来还是超级开心的,虽然是个板子题.一直忘记写博客,备忘一下. 米勒拉判大素数,关于米勒拉宾是个什么东西,传送门了解一下:biubiubiu~ B. Goldbach 题目传送门 自己看题意吧,直接贴代码了. 代码: 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<cstdlib> 6 #i

HDU 2138 How many prime numbers (判素数,米勒拉宾算法)

题意:给定一个数,判断是不是素数. 析:由于数太多,并且太大了,所以以前的方法都不适合,要用米勒拉宾算法. 代码如下: #include <iostream> #include <cstdio> #include <algorithm> #include <queue> #include <vector> #include <cstring> #include <map> #include <cctype> u

HDU 4910 Problem about GCD(米勒拉宾)

HDU 4910 Problem about GCD 题目链接 题意:给定一个数字,求出1 - n之间与他互质的数的乘积mod n 思路:看了网上别人找出来的规律,原文链接 然后由于这题的n很大,也没法直接判定,可以这样搞,先去试10^6以内的素数,判断可不可以,如果不行,再利用米勒拉宾判下是否是素数,如果不是的话,把这个数字开根在平方,判断是不是完全平方数,这样做的原因是数字最大10^18,如果没有10^6以内的质因子,又不是质数的话,那么他最多只能包含2个质因子了,那么如果他不是一个完全平方

HDU2138 &amp; 米勒拉宾模板

题意: 给出n个数,判断它是不是素数. SOL: 米勒拉宾裸题,思想方法略懂,并不能完全理解,所以实现只能靠背模板.... 好在不是很长... Code: /*========================================================================== # Last modified: 2016-03-21 10:09 # Filename: miller-rabin.cpp # Description: =================