UVA 10325 The Lottery( 容斥原理)
The Sports Association of Bangladesh is in great problem with their latest lottery `Jodi laiga Jai'. There
are so many participants this time that they cannot manage all the numbers. In an urgent meeting they
have decided that they will ignore some numbers. But how they will choose those unlucky numbers!!!
Mr. NondoDulal who is very interested about historic problems proposed a scheme to get free from
this problem.
You may be interested to know how he has got this scheme. Recently he has read the Joseph's
problem.
There are N tickets which are numbered from 1 to N. Mr. Nondo will choose M random numbers
and then he will select those numbers which is divisible by at least one of those M numbers. The
numbers which are not divisible by any of those M numbers will be considered for the lottery.
As you know each number is divisible by 1. So Mr. Nondo will never select 1 as one of those M
numbers. Now given N, M and M random numbers, you have to nd out the number of tickets which
will be considered for the lottery.
Input
Each input set starts with two Integers N (10 N < 231) and M (1 M 15). The next line will
contain M positive integers each of which is not greater than N.
Input is terminated by EOF.
Output
Just print in a line out of N tickets how many will be considered for the lottery.
Sample Input
10 2
2 3
20 2
2 4
Sample Output
3
10
题意: 给定一个数n 再给m个数(m<15) 假设这m个数为 a[0],a[1].....a[m-1];
求1~n中非数组a的数的倍数的数,就是把1~n中数组a的数的倍数筛掉,剩下的数的个数就是结果。
暴力跑会超时,利用容斥原理,比如n=10,m=2,a[0]=2,a[1]=3,把1到20中所有2的倍数筛掉,
先令ans=n=20,ans=ans-n/2=10。再把1到20中所有3的倍数筛掉,ans=ans-n/3=4。
那么现在问题来了,这么筛选的话会导致2和3的公倍数进行了二次筛选,也就是6,12,18这三个数,
所以要把这三个数加回来,ans=ans+n/(2*3)=7,得出最终结果。以此类推,数的个数为奇数就减,
数的个数为偶数就加,这就是容斥原理。
注意 :本题给的数不一定为质数,也可能为合数,上述容斥原理适用于质数,
在本题中进行容斥原理时要用他们的最小公倍数lcm。
比如n=10,m=2,a[0]=2,a[1]=4,这组数据,可验证本题要用lcm,而不是a[0]*a[1]。
第一种方法:搜索遍历
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b)
{
if(b==) return a;
return gcd(b,a%b);
}
ll lcm(ll a,ll b)
{
return a/gcd(a,b)*b;
}
ll n,m,a[],ans=;
void dfs(ll hav,ll cur,ll num)
{
if(hav>n||cur>=m)
return ;
for(int i=cur;i<m;i++) //注意区分这里的i和主函数里的i 混了就错了
{
ll temp=lcm(hav,a[i]);
if(num&)
ans=ans-n/temp;
else
ans=ans+n/temp;
dfs(temp,i+,num+);
}
}
int main()
{
while(cin>>n>>m)
{
memset(a,,sizeof(a));
for(int i=;i<m;i++)
cin>>a[i];
ans=n;
for(int i=;i<m;i++)
{
ans=ans-n/a[i];
dfs(a[i],i+,);
}
cout<<ans<<endl;
}
}
注意在上述代码中,不可以将主函数中的
for(int i=0;i<m;i++)
{
ans=ans-n/a[i];
dfs(a[i],i+1,2);
}
改为
for(i=0;i<m;i++)
{
dfs(a[i],i,1);
}
因为这样枚举情况会变多,原意指的是对于这m个数来说,一定包含这个数,dfs枚举是否包含其他数。
这个是初始化ans=n的,至于初始化ans=0怎么做还没弄懂,求高人指点。
感觉这个搜索应该还有另一种写法用select[i]=1,dfs,select[i]=0这样。
第二种方法:二进制枚举
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b)
{
if(b==) return a;
return gcd(b,a%b);
}
ll lcm(ll a, ll b)
{
return a/gcd(a,b)*b;
}
int main()
{
ll n,m,a[];
while(cin>>n>>m)
{
memset(a,,sizeof(a));
for(int i=;i<m;i++)
cin>>a[i];
ll ans=;
for(int i=;i<(<<m);i++)
{
ll tmp=,flag=;
for(int j=;j<m;j++)
{
if(i&(<<j))
{
tmp=lcm(tmp,a[j]); //注意是a[j]
//if(tmp>n) 这两句话可有可无 n/tmp=0;
//break;
flag++;
}
}
if(flag&)
ans=ans-n/tmp;
else
ans=ans+n/tmp;
}
cout<<ans<<endl;
}
return ;
}
UVA 10325 The Lottery( 容斥原理)的更多相关文章
- UVA.10325 The Lottery (组合数学 容斥原理 二进制枚举)
UVA.10325 The Lottery (组合数学 容斥原理) 题意分析 首先给出一个数n,然后给出m个数字(m<=15),在[1-n]之间,依次删除给出m个数字的倍数,求最后在[1-n]之 ...
- 容斥原理——uva 10325 The Lottery
首先推荐一篇介绍容斥原理很好的博客http://www.cppblog.com/vici/archive/2011/09/05/155103.html 题意:求1~n中不能被给定m个数中任意一个数整除 ...
- UVA 10325 - The Lottery(容斥)
以前做过的一个题,忘记/gcd了,看来需要把以前的东西看一下啊. #include <cstdio> #include <cstring> #include <iostr ...
- UVA.11806 Cheerleaders (组合数学 容斥原理 二进制枚举)
UVA.11806 Cheerleaders (组合数学 容斥原理 二进制枚举) 题意分析 给出n*m的矩形格子,给出k个点,每个格子里面可以放一个点.现在要求格子的最外围一圈的每行每列,至少要放一个 ...
- UVA 10325 lottery 容斥原理
题目链接 给出m个数, 求1-n的范围内, 无法整除这m个数之中任何一个数的数的个数. 设m个数为a[i], 对任意的i, n/a[i]是n中可以整除a[i]的数的个数, 但是这样对于有些数重复计算了 ...
- UVA 11806 Cheerleaders (容斥原理
1.题意描述 本题大致意思是讲:给定一个广场,把它分为M行N列的正方形小框.现在给定有K个拉拉队员,每一个拉拉队员需要站在小框内进行表演.但是表演过程中有如下要求: (1)每一个小框只能站立一个拉拉队 ...
- UVa 11806 拉拉队(容斥原理)
https://vjudge.net/problem/UVA-11806 题意: 在一个m行n列的矩形网格里放k个相同的石子,有多少种方法?每个格子最多放一个石子,所有石子都要用完,并且第一行.最后一 ...
- UVa 11806 Cheerleaders (数论容斥原理)
题意:给定一个n*m的棋盘,要放k个石子,要求第一行,最后一行,第一列,最后一列都有石子,问有多少种放法. 析:容斥原理,集合A是第一行没有石子,集合B是最后一行没有石子,集合C是第一列没有石子,集合 ...
- uva 10325基础容斥
题目:给你一个数n以及m个数字,问1~n中不能被这m个数字整除的数字的个数. 分析:容斥原理.组合数学.数字1-n中能被a.b整除的数字的个数分别是n/a,n/b: 则1-n中能被a或b整数的数字个数 ...
随机推荐
- 【poj1009】 Edge Detection
http://poj.org/problem?id=1009 (题目链接) 不得不说,poj上的水题还是质量非常高的= =,竟然让本大爷写了一下午. 转自:http://blog.sina.com.c ...
- CODEVS 1258 关路灯
写动归终于能不看题解一次A了!(其实交了两次,一次80一次A) 我练功发自真心! 题目描述 Description 多瑞卡得到了一份有趣而高薪的工作.每天早晨他必须关掉他所在村庄的街灯.所有的街灯都被 ...
- Erlang练习题----shopping
直接就上代码了: -module(shop). -export([cost/1,total/1]). cost(orange) -> 5; cost(newspaper) -> 8; co ...
- IOS基础之 (十二) 类的扩展
对OC类的扩展总结如下,共有4个: 1.子类 subClass 作用:可以使用类的继承来增添父类的变量和方法. 写法:在.h文件中 @interface Student : Person 2.分类 C ...
- HD1561The more, The Better(树形DP+有依赖背包)
The more, The Better Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
- ps 倒影制作
首先打开PS并打开一张素材,这里我选择了山水图片,制作山峰在水中的倒影效果. 然后按下[Crrl+J]复制这个图层,如图: 接着按下[Ctrl+T]或者是[编辑][自由变换],打开[自由变换] ...
- Windows 2008远程多用户登录的配置方法(转载)
在使用Windows2008远程登录功能时,如果需要进行多用户登录,可以采用以下配置方法: 首先要启用远程桌面这一功能:右击“我的电脑”→属性→远程配置→远程桌面,就可以配置相应的远程桌面功能了.下 ...
- springmvc中@PathVariable和@RequestParam的区别(百度收集)
http://localhost:8080/Springmvc/user/page.do?pageSize=3&pageNow=2 你可以把这地址分开理解,其中问号前半部分:http://lo ...
- 如何快速读懂大型C++程序代码
要搞清楚别人的代码,首先,你要了解代码涉及的领域知识,这是最重要的,不懂领域知识,只看代码本身,不可能搞的明白.其次,你得找各种文档:需求文档(要做什么),设计文档(怎么做的),先搞清楚你即将要阅读是 ...
- 10 steps to becoming the developer everyone wants
You thought it was all about programming skills. But you were wrong! Great code is fine, yet command ...