【组合】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;
}


posted @ 2014-08-20 18:47  kewowlo  阅读(149)  评论(0编辑  收藏  举报