import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); long n = Long.parseLong(br.readLine().trim()); long calNum = 0, start = 1; while(calNum < n){ calNum += start; start ++; } System.out.println(start - 1); } }更快地,这道题还可以用数学方法求解,时间复杂度O(1),我们可以很容易发现,1有1项,2有2项,3有3项,...,k有k项,根据高斯求和公式,只需判断什么时候k*(k+1)/2>=n即可。
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; public class Main{ public static void main(String[] args) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); long n = Long.parseLong(br.readLine()); long k = (long)Math.sqrt(n<<1); if(k*(k + 1) >= n<<1) System.out.println(k); else System.out.println(k + 1); } }
//AC代码 #include<iostream> #include<cmath> using namespace std; int main(){ long long int n; cin>>n; long long int num; long double x = sqrt(2*n+1/4)-1.0/2; num = x+1; cout<<num<<endl; return 0; }求解二元一次方程:n<=(x+1)*x/2,result = x+1
等差数列求和sum=1+2+3+...+i=i(i+1)/2就是排完i之后数列中拥有元素的个数,如果n大于i(i+1)/2而又小于等于(i+1)(i+2)/2,那么答案肯定是i+1,所以以此实现了helper1函数,也当然是对过大的n会超时啦。
然后假设n=i(i+1)/2,那么答案就是i,也就是i约等于sqrt(2n)。对于n=i(i+1)/2,i肯定是等于sqrt(2n)向下取整,但是如果n>i(i+1)/2,答案就可能是sqrt(2n)向下取整或向上取整了。。想了想,其实结合helper1就OK了,即:先用i=floor(sqrt(2n))求得一个最接近答案的i,然后如果i(i+1)/2大于n,那么答案就是i;否则答案是i+1。
最终实现helper2函数:
#include<iostream>
#include<algorithm>
using namespace std;
void helper1(long long n){
// 只能90%通过,最后一个超时,意料之中
long long i=1;
long long sum=0;
while(n>sum){
sum = (i*(i+1))>>1;
i++;
}
cout<<i-1;
}
void helper2(long long n){
double res = sqrt(double(n<<1));
long long small = floor(res);
if (((small*(small+1))>>1)<n) cout<< small+1;
else cout<<small;
//long long small = floor(res);
//long long big = ceil(res);
//if (res-small>big-res) cout<<big;
//else cout<<small;
}
int main(){
long long n;
while(cin>>n){
helper2(n);
}
}
不过,其实当n越大,答案就越不容易出错。。严谨的证明我还是智商有限。。所以helper2中那段注释掉的代码虽然能通过所有样例。。但看看就好=。=
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
long n = sc.nextLong();
int i;
for( i=0;n>0;i++)
n-=i;
System.out.println(i-1);
}
sc.close();
}
}
n=int(input()) x=(2*n+0.25)**0.5+0.5 print(int(x) if int(x)-x!=0 else int(x)-1)
package com.qiye; import java.util.Scanner; public class CrazySequence { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); long x = scanner.nextLong(); long i= 1; long sum = 0; while (true){ if(x <= sum){ break; } sum += i; i ++; } System.out.println(i - 1); } }
//等差数列不等式
import java.util.*;
public class Main{
public static void main(String[] arg){
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
Cal(sc);
}
}
public static void Cal(Scanner sc){
long n=sc.nextLong();
long sum=0;
for (long i=1;i<=n;i++){
if(i*i+i>2*n && (i-1)*(i-1)+i-1<2*n){
System.out.println(i);
return ;
}
if(i*i+i>2*n ){
System.out.println(i-1);
return ;
}
}
}
}
从1向上遍历结果会超时,可以用中学二次方程的公式解出,再向上取整即可。
//i从1开始循环试探,当 i*(i+1)/2 >= input 的时候,说明此时的 i 已经到达输入的 //序列数,即此时的i为此输入对应值,然而算法复杂度过大; // 经分析:i*(i+1)/2 <= (i+1)*(i+1)/2 ,而i+1 < Math.sqrt(input*2)情况下, //i*(i+1)/2 < (i+1)*(i+1)/2 < input,不可能满足if条件 //无需该部分多余计算,故从Math.sqrt(input*2)开始循环,降低了计算复杂度 var input = parseInt(readline()), start = parseInt(Math.sqrt(input*2)) for(var i=start;;i++){ if(input <= i*(i+1)/2){ console.log(i) break } }
#用等差数列求和的方法确定n在哪一个区间范围。 class Solution: n=int(input()) ans=0 t=int((2*n)**(0.5)) for i in range(t-1,t+1): if i*(i+1)/2<=n and (i+1)*(i+2)/2>n: if i*(i+1)/2<n: ans=i+1 else: ans=i break print ans
#等差数列求和公式import math