ACdream 神奇的%系列一 (素数筛)

题目链接:http://acdream.info/problem?pid=1071


神奇的%系列一

Time Limit: 6000/3000MS (Java/Others) Memory Limit: 65536/32768KB (Java/Others)
Problem Description

在计算机的世界里,%不是百分比,而是除法取余哟!

比如:
  4 % 2 = 0
  5 % 3 = 2

给你 2 ≤ N ≤ 100000 个数,a[1],a[2]...a[i]...a[n] (1 ≤ a[i] ≤ 100000)

问有几个组合 (a[i], a[j]),(i != ja[i] > a[j]),使得 a[i] % a[j] != 0

Input

输入有多组数据。(<= 30)

对于每组数据:

第一行:N(表示 N 个数)

第二行:个元素 a[i]  

Output

输出有几个组合 (a[i],a[j]),使得 a[i] % a[j] != 0

Sample Input
3
1 1 1
4
1 2 3 4
5
1 2 2 4 6
Sample Output
0
2
1


思路:类似于素数筛,求出所有合数的组合。用b数组保存每个数字出现的次数;


#include <stdio.h>
#include <string.h>

int main()
{
    int a[100001];
    int n;
    long long ans;
    while(scanf("%d",&n)!=EOF)
    {
        ans = 0;
        int i,j;
        memset(a,0,sizeof(a));
        int maxn = 0;
        for(i=0;i<n;i++)
        {
            int num;
            scanf("%d",&num);
            a[num]++;
            if(num>maxn)
                maxn = num;
        }
        for(i=1;i<=maxn;i++)
        {
            if(a[i])
            {
                ans+=(a[i]*(a[i]-1))/2; //如果相同的数字有多个,则算出自己与自己的组合数
                for(j=2;i*j<=maxn;j++)
                {
                    if(a[i*j])
                    {
                        ans+=(a[i]*a[i*j]);//计算出合数之间的组合数
                    }
                }
            }
        }
        printf("%lld\n",(long long) n*(n-1)/2-ans);//总组合数减去合数组合数
    }

    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值