题目3 : 质数相关
时间限制:
2000ms
单点时限:
1000ms
内存限制:
256MB
-
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 <cstring> #include <cstdio> #include <cstdlib> #include <cmath> #include <iostream> #include <algorithm> using namespace std; bool isprime[500000+5]; int t,n; int a[20]; int p[20]; bool pcount[20][20]; bool cmp(int x, int y){ return x < y; } void initg(){ memset(isprime,false,sizeof(isprime)); isprime[1] = isprime[0] = true; for(int i = 2; i <= 500000; i++){ if(!isprime[i]){ for(int j = i + i; j <= 500000; j += i) isprime[j] = true; } } } int qu[22]; int head,rear; bool ispos[22]; int main(){ initg(); scanf("%d",&t); for(int item = 1; item <= t; item ++){ scanf("%d",&n); for(int i = 0; i < n; i ++){ scanf("%d",&a[i]); } sort(a,a+n,cmp); memset(pcount,false,sizeof(pcount)); int tmp; for(int i = 0; i < n; i++){ for(int j = i+1; j < n; j++){ if(a[j] % a[i] == 0){ tmp = a[j] / a[i]; if(!isprime[tmp]){ pcount[i][j] = pcount[j][i] = true; } } } } int total = 0; int ans_tmp; int total_ans; memset(ispos,false,sizeof(ispos)); for(int i = 0; i < n; i++){ if(!ispos[i]){ head = rear = 0; memset(p,-1,sizeof(p)); p[i] = 0; qu[rear++] = i; ispos[i] = true; while(head != rear){ int now = qu[head++]; for(int j = 0; j < n; j++){ if(pcount[now][j] && !ispos[j]){ qu[rear++] = j; ispos[j] = true; if(p[now] == 0) p[j] = 1; else p[j] = 0; } } } total_ans = 0; ans_tmp = 0; for(int j = 0; j < n; j ++){ if(p[j] == 1) total_ans++; if(p[j] == 0) ans_tmp ++; } if(total_ans > ans_tmp) total+=total_ans; else total+=ans_tmp; } } printf("Case #%d: %d\n",item,total); } return 0; }
描述
两个数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