https://ac.nowcoder.com/acm/contest/316/E
链接:https://ac.nowcoder.com/acm/contest/316/E
来源:牛客网
题目描述
当一个正整数能被2或者3或者5或者7整除,我们定义这个数为or2数 给定正整数 ,
求问这个数是否是or2数,如果是,则输出他是第几大的or2数,否则输出Scum
输入描述:
多组数据(不超过1e5组,读到文件结束) 每组数据一行:一个正整数x(1≤x≤1e18)
输出描述:
对于每个输入,输出一行。 如果是or2数,输出or2 c,表示它是第c大的or2数 否则输出字符串Scum
示例1
输入
复制
2 4 11
输出
复制
or2 1 or2 3 Scum
这道题,x的范围为1e18,很明显不能打表,进行离线解决~~
但是我们可以打表找规律,不过这个规律可不好找~~
最后,我们来分析一下问题,这个题要求是输入n,求从1到n有多少个能被2,3,5,7整除的数
那么,能被2整除的数有n/2个,能被3整除的个数有n/3个,能被5整除的个数有n/5个,能被7整除的个数有n/7个
以上个数相加就可得出大致答案了,要想得出正确答案还要查重一下,比如:6能被2整除但是也能被3整除,那在计算的时候6被加入了两次,同样2*5,2*7,3*7,3*5,5*7,也被计算了两次,所以总数sum要减去n/6,n/14,n/21,n/35,,,,,,,,,
本以为这样就完了,,还有问题要考虑,比如:42,42能被2,3,7整除,所以加入三次,但是,还能被6,14,21整除,又减去了三次,所以还要重新加入一次,所以sum要加上n/(2*3*7)+(2*5*7)+(3*5*7)+(2*3*5),加上之后,这个数2*3*5*7==210又被多加入一次,所以要减去n/210
这时候sum就是要求的结果了
代码:
#include<bits/stdc++.h>
using namespace std;
#define mx 220
int main (){
long long n=1;
//一下注释是证明上述的正确性,不信的同学可以自己输出下
/*for(int i=1;i<=mx;i++)
{
if(i%2==0) printf("%d ",i);
}
printf("\n");
for(int i=1;i<=mx;i++)
{
if(i%3==0) printf("%d ",i);
}printf("\n");
for(int i=1;i<=mx;i++)
{
if(i%5==0) printf("%d ",i);
}printf("\n");
for(int i=01;i<=mx;i++)
{
if(i%7==0) printf("%d ",i);
}printf("\n");
for(int i=1;i<=mx;i++)
{
if(i%6==0) printf("%d ",i);
}printf("\n");
for(int i=1;i<=mx;i++)
{
if(i%10==0) printf("%d ",i);
}printf("\n");
for(int i=1;i<=mx;i++)
{
if(i%14==0) printf("%d ",i);
}printf("\n");
for(int i=1;i<=mx;i++)
{
if(i%15==0) printf("%d ",i);
}printf("\n");
for(int i=1;i<=mx;i++)
{
if(i%21==0) printf("%d ",i);
}printf("\n");
for(int i=1;i<=mx;i++)
{
if(i%35==0) printf("%d ",i);
}
printf("\n");
printf("%lld\n",n);
*/
while(~scanf("%lld",&n))
{
if(n%2&&n%3&&n%5&&n%7) {
printf("Scum\n");
continue;
}
printf("or2 ");
long long sum=0;
sum+=n/2;
sum+=n/3;
sum+=n/5;
sum+=n/7;
sum-=n/6;
sum-=n/10;
sum-=n/14;
sum-=n/15;
sum-=n/21;
sum-=n/35;
sum+=n/30;
sum+=n/70;
sum+=n/42;
sum+=n/105;
sum-=n/210;
printf("%lld\n",sum);
}
return 0;
}
今天坐地铁的时候,看见旁边的老外哭的一塌糊涂,边哭边对着电话那头说:你跟我在一起根本就不是因为爱情,你只是为了学英语!
这可能是个真实的故事~~