刷题总结(1)

题目描述

给出一个数n,求1到n中,有多少个数不是2 5 11 13的倍数。

输入描述

本题有多组输入每行一个数n,1<=n<=10^18.

输出描述

每行输出输出不是2 5 11 13的倍数的数共有多少。

示例

输入

15

输出

4

AC代码

#include <stdio.h>
int main()
{
    long n;
    while(~scanf("%ld",&n)) //该处是牛客网oj处理多组输入时需要加的
    {
        long long a1 = n / 2 + n / 5 + n / 11 + n / 13; //2、5、11、13倍数的个数
        long long a2 = n / 10 + n / 22 + n / 26 + n / 55 + n / 65+ n / 143;//(2,5)、(2,11)、(2,13)、(5,11)、(5,13)、(11,13)两数倍数的个数
        long long a3 = n / 110 + n / 130 + n / 286 + n / 715;   //(2,5,11)、(2,5,13)、(2,11,13)、(5,11,13)三数倍数的个数
        long long a4 = n / 1430;    //(2,5,11,13)四数倍数的个数
        long a = a1 - a2 + a3 - a4; //该句理解见文章最后
        printf("%ld\n",n - a);
    }
    return 0;
}

总结

开始做这道题时,想着直接遍历1~n,然后依次判断不能整除2、5、11、13,则计数器加1,实现如下:

int count = 0;
for(int i = 0; i < n; i++)
{
    if((i%2!=0)&&(i%5!=0)&&(i%11!=0)&&(i%13!=0))
    {
        count++;
    }
}

但是这种方法的复杂度为O(N),在牛客网oj时超时,不能通过,所以换成了如上方法。

对于表达式a1-a2+a3-a4的理解:

2 5 11 13
2 5 11 13
4 10
6 15
8
10
12
14

如上是当n为15时,各个数的倍数,由上面可知

a1 = 7 + 3 + 1+ 1

但仔细观察便可发现其中10算了两次,10即是2的倍数又是5的倍数,所以必须减去一次两数倍数,这便有了a2

a2 = 1 + 0 + 0 + 0 + 0 + 0

于是有a1 - a2,同理可推测整个式子。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1.两数之和 AC代码 思路 刚开始就是用双层for循环写,然后秉承着谦虚的态度看了题解,发现真的有O(N)的算法...
    Jingtianer阅读 846评论 0 2
  • 在C语言中,五种基本数据类型存储空间长度的排列顺序是: A)char B)char=int<=float C)ch...
    夏天再来阅读 3,426评论 0 2
  • 生活大爆炸版石头剪刀布 题目描述 石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头。如果两个人出拳一样,...
    bbqub阅读 487评论 0 0
  • 刚刚下过雨,地上还有积水,草坪里的花儿草儿显得格外的嫩,体育馆前也异常热闹了。小女孩穿着粉红色得衣服,甩着小手儿欢...
    三角山阅读 166评论 0 1
  • 风儿很喧嚣 吹散了乌云,湖面荡漾 我站在门口等风,一不留神,有什么东西横扫了夜 那些树不曾说话,在风中,沙沙 白天...
    木桥南阅读 176评论 0 2