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

来源:互联网 发布:西安财经行知学院地址 编辑:程序博客网 时间:2024/04/28 18:04

广工校赛时遇到这道题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 1000000000ll 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);    }}
0 0
原创粉丝点击