题目链接: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 != 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;
}