问题描述
求1+2+3+…+n的值。
输入格式
输入包括一个整数n。
输出格式
输出一行,包括一个整数,表示1+2+3+…+n的值。
样例输入
4
样例输出
10
样例输入
100
说明:有一些试题会给出多组样例输入输出以帮助你更好的做题。
一般在提交之前所有这些样例都需要测试通过才行,但这不代表这几组样例数据都正确了你的程序就是完全正确的,潜在的错误可能仍然导致你的得分较低。
样例输出
5050
数据规模与约定
1 <= n <= 1,000,000,000。
说明:请注意这里的数据规模。
本题直接的想法是直接使用一个循环来累加,然而,当数据规模很大时,这种“暴力”的方法往往会导致超时。此时你需要想想其他方法。你可以试一试,如果使用1000000000作为你的程序的输入,你的程序是不是能在规定的上面规定的时限内运行出来。
本题另一个要值得注意的地方是答案的大小不在你的语言默认的整型(int)范围内,如果使用整型来保存结果,会导致结果错误。
如果你使用C++或C语言而且准备使用printf输出结果,则你的格式字符串应该写成%I64d以输出long long类型的整数。
求解:
NO.1
看到题目很容易就会想到for循环求解,但是由于运行时间的限制,不能这样做
所以要采用等差数列的求和公式
还有一个点需要get到,那就是数据特别大,不能定义为int型,那就定义为long吧。
提交代码如下:
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
long sum = n + (n*(n-1))/2;
System.out.println(sum);
}
测试结果如下:
后五个测试数据竟然都是错误的,是什么原因呢? 应该是数据溢出了。
NO.2
先来看看,int、long这些数据类型可表示的范围吧,如果测试数据为1,000,000,000 那就绝对溢出了!
数据类型 大小 范围 默认值
byte(字节) 8 -128 - 127 0
shot(短整型) 16 -32768 - 32768 0
int(整型) 32 -2147483648-2147483648 0
long(长整型) 64 -9233372036854477808-9233372036854477808 0
float(浮点型) 32 -3.40292347E+38-3.40292347E+38 0.0f
double(双精度) 64 -1.79769313486231570E+308-1.79769313486231570E+308 0.0d
char(字符型) 16 ‘ \u0000 - u\ffff ’ ‘\u0000 ’
boolean(布尔型) 1 true/false false
那么如何表示超出long范围的数据呢? 这里就要用到BigDecimal了。
简要说一下BigDecimal的用法:
1.BigDecimal的构造方法
BigDecimal(int) 创建一个具有参数所指定整数值的对象。
BigDecimal(double) 创建一个具有参数所指定双精度值的对象。
BigDecimal(long) 创建一个具有参数所指定长整数值的对象。
BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象。
BigDecimal a =new BigDecimal("1.22"); //String
BigDecimal b =new BigDecimal(20); //int
System.out.println("a values is:"+a);
注意:
正确输出:1.2199999999999999733546474089962430298328399658203125
JDK解释:
- 参数类型为double的构造方法的结果有一定的不可预知性。有人可能认为在Java中写入newBigDecimal(0.1)所创建的BigDecimal正好等于 0.1(非标度值 1,其标度为1),但是它实际上等于0.1000000000000000055511151231257827021181583404541015625。这是因为0.1无法准确地表示为 double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样,传入到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。
- 另一方面,String 构造方法是完全可预知的:写入 newBigDecimal(“0.1”) 将创建一个 BigDecimal,它正好等于预期的 0.1。因此,比较而言, 通常建议优先使用String构造方法。
当double必须用作BigDecimal的源时,请注意,此构造方法提供了一个准确转换;它不提供与以下操作相同的结果:先使用Double.toString(double)方法,然后使用BigDecimal(String)构造方法,将double转换为String。要获取该结果,请使用static valueOf(double)方法。
2.BigDecimal常用方法描述
add(BigDecimal) BigDecimal对象中的值相加,然后返回这个对象。
- subtract(BigDecimal) BigDecimal对象中的值相减,然后返回这个对象。
- multiply(BigDecimal) BigDecimal对象中的值相乘,然后返回这个对象。
- divide(BigDecimal) BigDecimal对象中的值相除,然后返回这个对象。
- toString() 将BigDecimal对象的数值转换成字符串。
- doubleValue() 将BigDecimal对象中的值以双精度数返回。
- floatValue() 将BigDecimal对象中的值以单精度数返回。
- longValue() 将BigDecimal对象中的值以长整数返回。
- intValue() 将BigDecimal对象中的值以整数返回。
示例demo:
BigDecimala=newBigDecimal("1.11");
BigDecimalb=newBigDecimal("2.22");
a.add(b);
System.out.println("a + b = "+a);
提交代码如下:
import java.math.BigDecimal;
import java.util.Scanner;
/**
* @author 作者 : Cactus
* @version 创建时间:2018-2-13 下午12:14:29
*/
public class Main {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
BigDecimal m1 = new BigDecimal(n);
BigDecimal m2 = new BigDecimal(n-1);
BigDecimal m3 = new BigDecimal(2);
m2 = m2.multiply(m1);
m2 = m2.divide(m3);
m2 = m2.add(m1);
System.out.println(m2);
}
}
测试结果如下: