质数相关
描述
两个数a和 b (a<b)被称为质数相关,是指a × p = b,这里p是一个质数。一个集合S被称为质数相关,是指S中存在两个质数相关的数,否则称S为质数无关。如{2, 8, 17}质数无关,但{2, 8, 16}, {3, 6}质数相关。现在给定一个集合S,问S的所有质数无关子集中,最大的子集的大小。
输入
第一行为一个数T,为数据组数。之后每组数据包含两行。
第一行为N,为集合S的大小。第二行为N个整数,表示集合内的数。
输出
对于每组数据输出一行,形如"Case #X: Y"。X为数据编号,从1开始,Y为最大的子集的大小。
数据范围
1 ≤ T ≤ 20
集合S内的数两两不同且范围在1到500000之间。
小数据
1 ≤ N ≤ 15
大数据
1 ≤ N ≤ 1000
- 样例输入
-
3 5 2 4 8 16 32 5 2 3 4 6 9 3 1 2 3
- 样例输出
-
Case #1: 3 Case #2: 3 Case #3: 2
#include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> #include<vector> using namespace std; const int maxn=1010; const int maxm=500010; int link[maxn],used[maxn],a[maxn]; vector<int>G[maxn]; bool p[maxm]; void prime() { for(int i=2;i<=500000;i++){ if(!p[i]) { for(int j=i+i;j<=500000;j+=i) p[j]=true; } } } bool find(int u) { for(int i=0;i<G[u].size();i++){ int v=G[u][i]; if(used[v]) continue; used[v]=1; if(!link[v]||find(link[v])){ link[v]=u; return true; } } return false; } int main() { int i,j,n,T,ans=0,Case=0; prime(); scanf("%d",&T); while(T--){ ans=0; memset(link,0,sizeof(link)); scanf("%d",&n); for(i=1;i<=n;i++) G[i].clear(); for(i=1;i<=n;i++) scanf("%d",&a[i]); sort(a+1,a+n+1); for(i=1;i<=n;i++) for(j=i+1;j<=n;j++){ int tmp=a[j]/a[i]; if(tmp*a[i]==a[j]&&!p[tmp]){ G[i].push_back(j); G[j].push_back(i); } } for(i=1;i<=n;i++){ memset(used,0,sizeof(used)); if(find(i)) ans++; } printf("Case #%d: ",++Case); printf("%d\n",n-ans/2); } return 0; }