ZCMU----1776
2016-12-19 15:35
197 查看
1776: Press the switch
Time Limit: 1 Sec Memory Limit:128 MB
[Submit][Status][Web
Board]
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/a个灯被关掉了
m=2 有n/a,n/b个灯被关掉了,但有n/(a*b/gcd(a,b)个灯被关掉了两次(相当于被打开了),要记得*2呦
【注意】要考虑n的范围,int是不够的,要用long long
【代码】#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
#define cl(A) memset(A,0,sizeof A);
int GCD(int a,int b)
{
if(a>b) GCD(b,a);
if(a==0) return b;
return GCD(b%a,a);
}
int main()
{
LL n;
int m;
while(~scanf("%lld%d",&n,&m)){
int a,b;
if(m == 0)
printf("%lld\n",n);
else
if(m==1){
scanf("%d",&a);
LL tmp = n / a;
printf("%lld\n",n-tmp);
}
else{
scanf("%d%d",&a,&b);
int g = GCD(a,b);
LL tmp = n/(a*b/GCD(a,b))*2; ///被关掉了两次,所以要*2
LL tmp1 = n/a;
LL tmp2 = n/b;
printf("%lld\n",n-tmp1-tmp2+tmp);
}
}
return 0;
}