您的位置:首页 > 其它

gdut 2016校赛决赛 Problem F 我是好人4

2016-05-25 12:32 302 查看
广工校赛时遇到这道题10E大的数打表肯定不行,起初我想到了直接相除,然后减去他们的最小公倍数,当然只限于有两个数,三个数的话就有点懵了,不知道怎么加减,四个数更别提了,而题目是50个数,当时还不知道容斥原理,怎么想也想不明白到底应该怎么写,比赛时这道题的AC的人也特别的少。赛完百度了下才知道容斥原理这个词,即:

A1并A2并A3并…..An = A1+A2+..An- ( A1交A2 + A1A3 + A1交A4 +…. An-1交An ) + (A1交A2交A3 + A1交A2交A4 + ….An-2交An-1交An) - (-1)^n*(A1交A2交A3交…An);

利用这个原理将所有情况加减一遍就算出来了。

Problem F: 我是好人4

Description

众所周知,我是好人!所以不会出太难的题,题意很简单

给你n个数,问你1000000000(含1e9)以内有多少个正整数不是这n个数任意一个的倍数

最后友情提供解题代码(我真是太好人了)

void solve(int p[], int n)

{

int ans = 0;

for (int i = 1; i <= 1e9; i++)

{

int fl = 0;

for (int j = 0; j < n; j++)

{

if (i % p[j] == 0)

{

fl = 1;

break;

}

}

if (fl == 0)ans++;

}

printf(“%d\n”, ans);

}

Input

第1行是一个整数T,表示共T组数据。 接下来是T组数据,每组数据第1行是正整数n(n<=50),接下来是n个正整数(小于等于1000),任意两数用1个空格隔开,最前数前面与最后数后面无空格

Output

输出T行,对应T组数据。(T<=10) 每行输出这样的正整数有多少个

Sample Input

342 3 5 71213854 101 143 282 538 922 946 286 681 977 892 656 907

Sample Output

228571428500000000968701719

代码:

#include<stdio.h>
#include<string.h>
#define ll long long
#define maxn 1000000000
ll a[60],b[60],k,s=0;
ll gcd(ll c, ll d)
{
return d?gcd(d,c%d):c;
}
ll lcm(ll c,ll d)
{
return c*d/gcd(c,d);
}
void dfs(ll qi,ll shu,ll mo)
{
if(qi==k)
{
if(mo)
{
if(mo&1)
s-=maxn/shu;
else
s+=maxn/shu;
}
return;
}
if(shu%a[qi]==0) return;
dfs(qi+1,shu,mo);
shu=lcm(a[qi],shu);
if(shu<=maxn)
dfs(qi+1,shu,mo+1);
}
int main()
{
ll N;
scanf("%lld",&N);
while(N--)
{
k=0;
ll j,n,i;
scanf("%lld",&n);
for(i=0; i<n; i++)
scanf("%lld",&b[i]);
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
{
if(j==i||b[j]==-1)
continue;
if(b[i]==-1)
break;
if(b[i]%b[j]==0)
{
b[i]=-1;
break;
}
}
}
memset(a,0,sizeof(a));
int f=0;
for(i=0; i<n; i++)
{
if(b[i]!=-1)
a[k++]=b[i];
if(b[i]==1)
f=1;
}
s=maxn;
if(f)
{
printf("0\n");
continue;
}
dfs(0 ,1 ,0 );
printf("%lld\n",s);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: