九度笔记之 1357:疯狂地Jobdu序列

题目1357:疯狂地Jobdu序列

时间限制:1 秒

内存限制:32 兆

特殊判题:

提交:529

解决:168

题目描述:

阳仔作为OJ的数据管理员,每一周的题目录入都让其很抓狂,因为题目不是他出的,他控制不了出题的速度……在等题目的时候,阳仔又不敢出去打篮球,所以只能在纸上乱涂乱写,这天,阳仔在纸上写下了这样的序列:

1 2 2 3 3 3 4 4 4 4 5 5 5 5 5 6 6 6 6 6 6 ……

即大小为k的数字,正好会在序列中连续重复k次。写到这里,阳仔兴奋了,但是他不知道这种序列叫什么名字,那就暂时叫它jobdu疯狂序列好了。现在阳仔想让你解决一个问题是,假如给你一个整数n,你能说出这个序列中,第n个元素的大小是多少么? 记住,速度要快哦,亲~

输入:
每个测试文件包含多个测试案例,每个测试案例只有一行,即整数n,1 <= n <= 10^18,代表要查找的第n个元素。
输出:
对于每个测试案例,输出疯狂的jobdu序列中的第n个元素。
样例输入:
1
2
3
4
5
样例输出:
1
2
2
3
3
提示:

输入较大,不建议使用cin读入输入数据。

算法分析

       每个数值的个数构成了一个等差数列,如果第n个数字是数值num则由等差数列求和公式可知:

       (num-1)*(num-1+1)   <   2*n  <=  num*(num+1)

      在算法中多利用数学知识能得到很好的结果 如  题目1354:和为S的连续正数序列

源程序

注意输入数值可能很大,所以用long long 类型,输入用scanf("%lld",&num)

在计算sqrt时,转为 long double类型,

//============================================================================
// Name        : judo1357new.cpp
// Author      : wdy
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
 
#include <iostream>
#include <cmath>
#include <stdio.h>
using namespace std;
long long  getNum(long long n){
    long  long num = std::sqrt((long double)(2*n));
    if(2*n <= num*(num+1))
        return num;
    else
        return num+1;
 
}
void judo(){
    long  long n;
    while(scanf("%lld",&n)!=EOF){
        printf("%lld\n",getNum(n));
    }
}
int main() {
    judo();
    //cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
    return 0;
}
/**************************************************************
    Problem: 1357
    User: KES
    Language: C++
    Result: Accepted
    Time:40 ms
    Memory:1532 kb
****************************************************************/


你可能感兴趣的:(九度笔记之 1357:疯狂地Jobdu序列)