广州工业大学2016校赛 F 我是好人4 dfs+容斥

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

3 4 2 3 5 7 1 2 13 854 101 143 282 538 922 946 286 681 977 892 656 907

Sample Output

228571428 500000000 968701719

HINT

提示:数据是随机生成的,尔等尽可随意乱搞

思路:根据容斥原理;偶数就减,奇数就加;

   dfs需要优化:lcm>1e9;return;

   把0删掉,如果有整除的删掉;

#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<queue>
#include<algorithm>
#include<stack>
#include<cstring>
#include<vector>
#include<list>
#include<set>
#include<map>
using namespace std;
#define ll long long
#define mod 1000000007
#define inf 999999999
int scan()
{
    int res = 0 , ch ;
    while( !( ( ch = getchar() ) >= ‘0‘ && ch <= ‘9‘ ) )
    {
        if( ch == EOF )  return 1 << 30 ;
    }
    res = ch - ‘0‘ ;
    while( ( ch = getchar() ) >= ‘0‘ && ch <= ‘9‘ )
        res = res * 10 + ( ch - ‘0‘ ) ;
    return res ;
}
ll a[55];
ll ans;
int y,len;
ll maxx=1e9;
ll gcd(ll x,ll y)
{
    if(x%y==0)
    return y;
    else
    return gcd(y,x%y);
}
void dfs(ll lcm,int pos,int step)
{
    if(lcm>maxx)
    return;
    if(pos==len)
    {
        if(step==0)
        return;
        if(step&1)
        ans+=(maxx/lcm);
        else
        ans-=(maxx/lcm);
        return;
    }
    dfs(lcm*a[pos]/gcd(lcm,a[pos]),pos+1,step+1);
    dfs(lcm,pos+1,step);
}
int main()
{
    int x,i;
    scanf("%d",&x);
    while(x--)
    {
        scanf("%d",&y);
        int lenn=0;
        for(i=0;i<y;i++)
        {
            scanf("%lld",&a[i]);
            if(a[i])
            a[lenn++]=a[i];
        }
        sort(a,a+lenn);
        len=0;
        for(int i=0;i<lenn;i++) {
               int  f = 0;
            for(int j=0;j<len;j++) {
                if(a[i]%a[j]==0) f=1;
            }
            if(!f) a[len++] = a[i];
        }
        ans=0;
        dfs(1,0,0);
        printf("%lld\n",maxx-ans);
    }
    return 0;
}

时间: 2024-10-06 12:15:26

广州工业大学2016校赛 F 我是好人4 dfs+容斥的相关文章

ACM学习历程—广东工业大学2016校赛决赛-网络赛F 我是好人4(数论)

题目链接:http://gdutcode.sinaapp.com/problem.php?cid=1031&pid=5 这个题目一看就是一道数论题,应该考虑使用容斥原理,这里对lcm进行容斥. 不过直接上去是T,考虑到序列中同时存在i和ki的话,其实只需要考虑i,所以先对序列中为倍数的对进行处理. 这里的容斥用了hqw的写法. 代码: #include <iostream> #include <cstdio> #include <cstdlib> #includ

ACM学习历程—广东工业大学2016校赛决赛-网络赛E 积木积水(最值问题 || 动态规划)

题目链接:http://gdutcode.sinaapp.com/problem.php?cid=1031&pid=4 这个题目自然会考虑到去讨论最长或者最短的板子. 笔上大概模拟一下的话,就会知道,假设最长的板子是r,0和n+1位置上都是高度为0的板子,那么对于[0, r-1]中的最长板子rr,rr到r这一短应该都是被深度为a[rr]的水覆盖.同样的[0, rr-1]中的最长板子rrr,rrr到rr这一段应该是被a[rrr]覆盖,以此类推可以搞定r的前面一段,同理搞定后一段. 关于最值这一块,

ACM学习历程—广东工业大学2016校赛决赛-网络赛D 二叉树的中序遍历(数据结构)

题目链接:http://gdutcode.sinaapp.com/problem.php?cid=1031&pid=3 这算是一个胡搞类型的题目.当然肯定是有其数据结构支撑的. 唯一的限制就是不能出现连续的两个’#’. 因为如果我从左到右构造这棵树,那么假设我构造到第i个, 如果i+1是数字,那么把前i个构成的子树作为i+1的左儿子即可. 如果i+1是’#’,那么把’#’当成i的右儿子即可. 所以只要没有两个连续的’#’,自然能通过上面的方法构造. 但是如果出现两个连续的’#’,自然前一个’#’

ACM学习历程—广东工业大学2016校赛决赛-网络赛C wintermelon的魔界寻路之旅(最短路 &amp;&amp; 递推)

题目链接:http://gdutcode.sinaapp.com/problem.php?cid=1031&pid=2 题目由于要找对称的路径,那么狠明显可以把右下角的每一块加到左上角对应的每一块上.然后就变成从左上角走到对角线的最短路径的个数. 先跑一遍最短路径得到p(i, j)从起点到(i, j)的最短路径. 然后就是找最短路径的个数.显然cnt(i, j)是它周围点能通过最短路径到它的cnt的和.这一处可以使用记忆化搜索来完成. 代码: #include <iostream> #

GG的匹配串 ______(广东工业大学2015校赛初赛)

Description 2015年广东工业大学ACM校赛要来~\(≧▽≦)/~辣辣辣,作为校赛的出题人之一,GG想出了一道水题来考考大家.相信小伙伴们都学过字符串匹配,于是字符串匹配的水题就诞生辣!GG给出了一段长度为N的大写字母序列,现在他要你修改这一段字母序列,使得这段字母序列上最前面的K个字母组成的序列与最后面的K个字母组成的序列一一匹配. 例如对于序列"ATUUUUAC"和K = 2,可以通过将第二个字母修改为"C",使得最前面的两个字母与最后面的两个字母都

河南工业大学2017校赛题解

问题 A: 饶学妹的比赛 题意: 给你一场比赛每人提交的记录,计算最后的排名 题解: 模拟+排序 代码: 1 #include <map> 2 #include <set> 3 #include <cmath> 4 #include <queue> 5 #include <stack> 6 #include <cstdio> 7 #include <string> 8 #include <vector> 9 #

2015广东工业大学ACM校赛 I 游戏王 (状压dp)

Problem I: 游戏王 Description 小学的时候,Stubird非常喜欢玩游戏王,有一天,他发现了一个绝佳的连锁组合,这个连锁组合需要6张卡, 可是他一张都没有,但是他的那些朋友们有,不过当然,他们不会白给,不过也不排除有人和他交情好,送给他了. 不过他们有成全别人的美德,当他们看到Stubird已经有某些他们喜欢的卡的时候,他们会给他优惠,或者更贵也说不定 嘛不过,你可以把有的卡片藏起来,不告诉他们,来获得更低的价格. 问他最少需要多少钱才可以集齐所有的卡. Input 第一行

北邮校赛 F. Gabriel&#39;s Pocket Money(树状数组)

F. Gabriel's Pocket Money 2017- BUPT Collegiate Programming Contest - sync 时间限制 2000 ms 内存限制 65536 KB 题目描述 For centuries, Heaven has required its young angels to live and study among humans in order to become full-fledged angels. This is no different

广工2016校赛决赛

重现补的题目. Problem A: Krito的讨伐 思路:不要求一次性杀光一个节点里面的所有怪物. 所以我们可以用一个优先队列.优先去杀那些我们当前可以挑战的,然后注意下处理一个房间可能有多个怪物或者无怪物.当我们杀完第x个房间的怪物时候,那么就把x的下一层的怪物加入队列,如果x的下一层出现了空房间[即房间不存在怪物],那么再把该房间当做新的x,继续加入新x的下一层直到出现了有怪物的房间位置. #define _CRT_SECURE_NO_DEPRECATE #include<iostrea