D. 唐纳德和他的数学老师
Time limit per test: 1.0 seconds
Memory limit: 256 megabytes
唐纳德是一个数学天才。有一天,他的数学老师决定为难一下他。他跟唐纳德说:「现在我们来玩一个游戏。这个游戏总共 n 轮,每一轮我都会给你一个数(第 i 轮给出的数是 ai )。你每次要回答一个数,是我给出的这个数的质因数,并且你说出的数不能重复。」
因为数学老师是刻意为难,所以这个游戏很有可能不可能进行到最后。但是聪明的数学老师早就已经知道这个游戏最多能进行几轮了。现在他把问题抛给了你,想看看你知不知道。
注意, 1 不是质数。
Input
输入具有如下形式:
na1 a2 … an
第一行一个整数 n ( 1≤n≤3 000 )。
第二行 n 个整数用空格隔开, a1,a2,…,an ( 2≤ai≤106 )。
Output
输出游戏最多能进行几轮。
Examples
input
3 7 6 3
output
3
input
5 2 2 2 2 2
output
1
先建邻接表,给每个数和他的质因数连边。
然后依次匈牙利算法给数,不成了就break输出答案了。
找质因数随便拉了个模板。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
#define LL long long
const int maxn = 1000055+55;
int head[maxn],nxt[maxn],sz=0;
int to[maxn];
void add(int u,int v)
{
nxt[sz]=head[u];
to[sz]=v;
head[u]=sz++;
}
void findAllZYS(int n,int x)
{
for(int i=2;i*i<=n;i++)
{
if(n%i==0) //若n可以被i整除,则将i加入质因子数组p中
{
add(x,i);
while(n%i==0) //n除尽该质因子i,这样就可以保证下面循环的i一定是质因子
{
n/=i;
}
}
}
if(n>1) //应对“n=103”这种情况
{
add(x,n);
}
}
int fa[maxn];
int flag[maxn];
bool find(int x)
{
for(int i=head[x];~i;i=nxt[i]){
int v=to[i];
if(!flag[v]){
flag[v]=1;
if(fa[v]==0||find(fa[v])){
fa[v]=x;
return true;
}
}
}
return false;
}
int main()
{
int n;
scanf("%d",&n);
sz=0;
for(int i=1;i<=n;i++) head[i]=-1;
for(int i=1;i<=n;i++){
int x;scanf("%d",&x);
findAllZYS(x,i);
}
int i;
for(i=1;i<=n;i++){
memset(flag,0,sizeof flag);
if(!find(i)){
break;
}
}
printf("%d\n",i-1);
}