HUD-1001


title: HDU-1001
categories:

  • ACM
  • 易错题
    tags:
  • 大数陷阱
  • 代数式最大化部分溢出
  • 补码
  • 计算机中运算过程
    date: 2020-02-06 09:59:33

这个题的平均通过比率大约为0.25(20200206),平均提交四次才能通过。确实有一个大陷阱,这道题需要我们了解C语言的基本知识和计算机中的运算过程。

  • 题目

    Sum Problem

    *Time Limit: 1000/500 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 677426 Accepted Submission(s): 170938
    *

    Problem Description

    Hey, welcome to HDOJ(Hangzhou Dianzi University Online Judge).

    In this problem, your task is to calculate SUM(n) = 1 + 2 + 3 + … + n.

    Input

    The input will consist of a series of integers n, one integer per line.

    Output

    For each case, output SUM(n) in one line, followed by a blank line. You may assume the result will be in the range of 32-bit signed integer.

    扫描二维码关注公众号,回复: 9811872 查看本文章

    Sample Input

    1
    100
    

    Sample Output

    1
    
    5050
    

C语言中IO和运算过程

例如cin>>a;在屏幕上输入5然后点回车,存储过程为将5的补码存到a对应的地址,然后对这个补码进行运算。

例如2*a+1先计算2*a存到一个地方b,然后运算b+1。运算过程为一步一步的,每一步都保存结果,这样就导致了在运算过程中可能导致临时的结果溢出,例如本题中计算1+2+3+···+N有好多种算法(循环累加和公式法),我们都会下意识的用比较简单的n*(n+1)/2,题目中告诉我们n*(n+1)/2在有符号整形的范围之内,但是计算n*(n+1)的时候要保存一个临时结果,这个结果是有可能比有符号整形大的,所以最终结果不准确。

解决方法

调整运算顺序将增大运算和减小运算交错排布

n*(n+1)/2调整为n/2*(n+1)(n为偶数)或(n+1)/2*n(n+1为偶数)

#include <stdio.h>
#include<iostream>
using namespace std; 
int main(){    
	int a;
	while(cin>>a){
		if(a%2==0)
		cout<<a/2*(a+1)<<endl<<endl;
		else
		cout<<(a+1)/2*a<<endl<<endl; 
	}
    return 0;
}

消除运算过程中的减小运算(将公式法改为累加法)

#include <stdio.h>
#include<iostream>
using namespace std; 
int main(){    
	int a;
	while(cin>>a)
	{
		int sum=0;
		for(int i=1;i<=a;i++)
		sum+=i;
		cout<<sum<<endl<<endl;
	}
    return 0;
}
发布了25 篇原创文章 · 获赞 1 · 访问量 499

猜你喜欢

转载自blog.csdn.net/qq_43985303/article/details/104212262
HUD