【组合】HDU 3908 Triple
题意:
在n个数中选出三个数使得 两两互质或不互质
直接求两两互质和不互质的个数比较麻烦
所以求出不满足条件的组合
先记录下b[i]:表示与第i个数互质的数的个数
c[i]表示与第i个数不互质的个数
b[i]*c[i]则表示选择了第i个数有这么多种情况不符合条件
sum+=b[i]*c[i](i=1...n)
每种情况出现了两次所以 sum/2
所以
ans=C(n,3)-sum/2;
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <string> #include <iostream> #include <algorithm> using namespace std; #include <queue> #include <stack> #include <vector> #include <deque> #include <set> #include <map> #define IN freopen ("in.txt" , "r" , stdin); #define OUT freopen ("out.txt" , "w" , stdout); typedef long long LL; const int MAXN = 1001;//点数的最大值 const int MAXM = 20006;//边数的最大值 const int INF = 11521204; const int mod=6; int a[802],b[888],c[888]; int gcd(int a,int b) { if(b==0) return a; return gcd(b,a%b); } int C(int n,int k) { int sum=1; for(int i=1; i<=k; i++) sum=sum*(n-i+1)/i; return sum; } int main() { int t,n; //IN; scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i=0; i<n; i++) { scanf("%d",&a[i]); b[i]=c[i]=0; } int sum=0; for(int i=0; i<n; i++) { for(int j=0; j<n; j++) { if(i==j) continue; if(gcd(a[j],a[i])==1) b[i]++; else c[i]++; } } for(int i=0; i<n; i++) sum+=b[i]*c[i]; printf("%d\n",C(n,3)-sum/2); } return 0; }