不能被整除的数
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
1
-
描述
-
给你一个数N 再给你3个数a,b,c求1到N内即不能被a,b整除,也不能被c整除的数
-
输入
-
有多组测试数据
每次输一个数N 接下来输入3个数a,b,c
输出1~N不能被a,b,c整除的数字的个数
0<=N<=2*10^9 a,b,c 都不大于N。N=0时不做处理并且结束
输出
-
输出1~N不能被a,b,c整除的数字的个数
每次输出占一行
样例输入
-
1000 5 6 8 20 3 4 5
样例输出
-
600 8
-
分析:初看这题目 枚举肯定不行。于是观察发现 有条公式:n-n/([abc])-(n/a+n/b+n/c-n/[ab]-n/[ac]-n/[bc])
-
为了方便 []表示求公倍数。
-
怎么证明呢:我的理解是 n个数减去不符合条件的
-
n/a 表示1-N能被a整除的数 n/b和n/c也是
-
于是能被a整除的数包含了:只能被a整除,能被ab整数,能被ac整除,能被abc整除;(b和c也一样)
-
于是看表(这里列举的每列不相关,即例如ab表示只能被a和b整除的数)
-
A: a ,ab,bc,abc;
-
B: b ,ab, bc, abc;
-
C: c ,ac ,bc abc;
-
这里重复了各一次的能被两个数整除的数 所以要减掉 即
n/[ab]-n/[ac]-n/[bc];
-
但是怎么知道要减去n/([abc])呢 因为我们用n/两个数的公倍数的 ab ac bc里面包含了abc,并不是上表那个纯不相关的 所以减了3次把三个abc都减掉了 所以要加一个 !
-
(本人智商有限 就个人理解随意写 求高手不要鄙视)
-
-
//AC代码
#include <iostream> using namespace std; int main(){ int gcd(int a,int b); int n,a,c,b; int gab,gac,gbc,sum,tmp; while(cin>>n){ if(n==0) break; cin>>a>>b>>c; gab=a*b/gcd(a,b);gac=a*c/gcd(a,c);gbc=b*c/gcd(b,c); int fuck=a*b/gcd(a,b); tmp=gcd(fuck,c); sum=fuck*c/tmp; cout<<n-n/sum-(n/a+n/b+n/c-n/gab-n/gac-n/gbc)<<endl; } return 0; } int gcd(int a,int b){ int r; if(a<b) { r=a; a=b; b=r; } while(b!=0){ r=a%b; a=b; b=r; } return a; }
-
//最后忘了一点 假设a b c gcd公约数函数
-
求三个数的最小公倍数是先求两个数的公倍数,然后代入公约数,再求出两个数的公倍数
[a*b/gcd(a,b)*c]/gcd(a*b/gcd(a,b),c)
-
-
有多组测试数据