1776: Press the switch
Description
达达的家里有一串长度为n的灯泡,编号1,2,3,4.....n-1,n。每一个灯泡都有一个开关,达达每次选一个数a,把编号为a的倍数的灯泡的开关都按一遍。
假定灯刚开始都开着,他做了m次这样的事,问他爸妈打他没有?偶,不不不,问最后有几个灯开着。
Input
多组测试数据,第一行输入一个n(1<=n<=1e12)
第二行数输入一个数m(0<=m<=2)
接下来输入m个数ai(1<=ai<=min(1000,n))
Output
输出最后结果
Sample Input
100 1 2 5 2 2 3 100000000000 1 1
Sample Output
50 2 0
解题思路:因为m就三种情况,m=0时,毫无疑问输出n;当m=1的时候,就是n-n/a(n/a说明从1到n有几个是被a整除,这个应该很好理解);当m=2时,就是n-(n/a+n/b-(n/(a*b)/gcd(a,b))*2),后面括号的是按了2次,说明是亮的,为什么要乘以2,因为我们多算了2次。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int gcd(int a,int b)
{
if(a<b) swap(a,b);
if(b) return gcd(b,a%b);
return a;
}
int main(void)
{
ll n;
while(~scanf("%lld",&n))
{
int m;
scanf("%d",&m);
if(m==0)
{
printf("%lld\n",n);
continue;
}
if(m==1)
{
int a;
scanf("%d",&a);
printf("%lld\n",n-n/a);
}
else if(m==2)
{
int a,b;
scanf("%d%d",&a,&b);
int e=gcd(a,b);
int d=a*b/e;
printf("%lld\n",n-(n/a+n/b-n/d*2));
}
}
return 0;
}