中南林业科技大学第十一届程序设计大赛D 有趣的数字

链接:https://www.nowcoder.com/acm/contest/124/D
来源:牛客网
题目描述
最近TreeDream沉迷于数字游戏中,发现了一种有趣的数字,有趣的数字定义如下:
给定一组n个数,a[1],a[2],a[3],…,a[n], 初始全为0,现在,在这组数上进行x操作;
x 操作定义如下:
x从1~n依次增加,每次把x的下标的倍数的数进行反转,0变成1,1变成0,操作完后,如果a[i]为0,那么i则是有趣的数。
现在对于给定的n(n<=1e15),求这时候有趣的数的个数。
例如:
n = 3
x = 1 时 :a[1] = 1, a[2] = 1, a[3] = 1;
x = 2 时 :a[1] = 1, a[2] = 0, a[3] = 1;
x = 3 时 :a[1] = 1, a[2] = 0, a[3] = 0;
此时,3个数中,有两个数为0,故有趣的数的个数为2;
输入描述:
多组样例,每个样例占一行,每一行输入一个数n,表示有n个数。(n<=1e15)
输出描述:
每个样例输出一行,一行输出一个数,表示有趣的数的个数。
示例1
输入
3
输出
2

这题算是比较有思考性的一道题,因为数据很大,暴力肯定过不了的,所以分析,1只可能被1整除,所以1只会变化一次,同理我们只要先找出每一个数变化多少次就可以得出最后是1还是0,但是这样子也是很暴力,因为数据特别大,所以利用这个结论再打表找规律,前3个数结果等于n-1,接下来5个数结果等于n-2…以此类推

代码:

#include <cstdio>
#include <algorithm>
using namespace std;
int main(void){
    while(~scanf("%lld",&n)){
        long long flat=3;
        long long temp=n;
        while(n>0){
            n-=flat;
            flat+=2;   
        }
        printf("%lld\n",temp-(flat-2)/2);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/westbrook1998/article/details/80384384