您的位置:首页 > 其它

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

2014-08-28 15:11 239 查看
题目链接:http://acdream.info/problem?pid=1071


神奇的%系列一

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

SubmitStatisticNext
Problem


Problem Description

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

  4 % 2 = 0

  5 % 3 = 2
给你 2 ≤ N ≤ 100000 个数,a[1],a[2]...a[i]...a
(1 ≤ a[i] ≤ 100000)。
问有几个组合 (a[i], a[j]),(i != j, a[i]
> a[j]),使得 a[i] % a[j] != 0。


Input

输入有多组数据。(<= 30)
对于每组数据:
第一行:N(表示 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: