1. 程式人生 > >CSU 1519: Sum of Integers

CSU 1519: Sum of Integers

這個題目,是我目前遇到過的最神坑的題,沒有之一!

題目是這樣的:

Description

Given two integers A, B (A < B), we can select some different integers (at least one) arbitrarily from A, A+1, ..., B-1, B and sum them. Question: How many different sums can we get?
For example, if select some integers from 1, 2, 3 and sum them, we can get six different sums: 1 (itself), 2 (itself), 3 (itself or 1+2), 4 (1+3), 5 (2+3), 6 (1+2+3). If select some integers from 2, 3, 4 and sum them, we can get seven different sums: 2 (itself), 3 (itself), 4 (itself), 5 (2+3), 6 (2+4), 7 (3+4), 9 (2+3+4).

Input

The first line contains the number of test cases T (0 < T ≤ 200).
For each test case, there is only one line with two integers A, B (0 < A < B < 10^9) separated by a single space.

Output

For each test case, output the number of different sums in one line.

Sample Input

2
1 3
2 4

Sample Output

6
7
使用我們中南的OJ的同學一定要注意了,你在OJ上面看到的肯定是B<109,不過其實是10^9,相信你也已經猜到了。

神坑的是,標程居然是這樣的:

#include <iostream>
#include <cstring>
#include <cstdio>
using namespacestd;
int main()
{
    long long a,b,ans;
    int t;
    scanf("%d",&t);
    while (t--)
    {
        scanf("%lld%lld"
,&a,&b); ans=(b-a+1)*(a+b)/2-a-a+2; printf("%lld\n",ans); } }

在我陷入絕境之後,出於好奇,把標程拿去提交了一下,果然AC了。

可是,輸入1 3 5,輸出的居然是8!

明顯只有3,4,5,3+4,3+5,4+5,3+4+5這7種!

無語。。。。。

無語。。。。

無語。。。

無語。。

。。。

。。

好了,說說我的思路吧。

首先,如果取1個數,那麼大小就是從a到b

如果取2個數,那麼大小就是a+a+1到b-1+b

。。。。。。

如果取b-a+1個數,就只能是a+a+1+...+b

答案就是這些區間的並的長度。

程式碼1:

#include<iostream>
using namespacestd;
 
int main()
{
    int t;
    cin >> t;
    int a, b;
    int sum, dif;
    while (t--)
    {
        cin >> a >> b;
        sum = (a + b)*(b - a + 1) / 2 - a + 1;
        for (int i = 1; i <= b - a; i++)
        {
            dif = (a + a + i)*(i + 1) / 2 - (b + b - i + 1)*i / 2 - 1;
            if (dif > 0)sum -= dif;
        }
        cout << sum << endl;
    }   
    return 0;
}

然而超時了(這是在我發現其實109是10^9之前寫的程式碼)

既然如此,就只能把這個for迴圈消掉了,也就是把公式求出來。

程式碼2:

#include<iostream>
#include<math.h>
using namespacestd;
 
int main()
{
    int t;
    cin >> t;
    long long a, b;
    long long sum, delta;
    long long x;
    while (t--)
    {
        cin >> a >> b;
        sum = (a + b)*(b - a + 1) / 2 - a + 1;
        delta = (b - a)*(b - a) - 4 * (a - 1);
        if (delta <= 0)sum -= (1 - (b - a)*(b - a))*(b - a) / 6 + (a - 1)*(b - a);
        else
        {
            x = int((b - a - sqrt(delta)) / 2);
            sum -= (x*(x + 1)*(x + x + 1) / 3 - (b - a)*x*(x + 1) + (a - 1)*(x + x + 1));
        }
        cout << sum << endl;
    }
    return 0;
}
我幾乎確定這個程式碼不會有任何問題,但是依然是wrong answer,所以我才會好奇,標程到底長啥樣。

看到真相的我哭了大哭

那年院賽,就是被這個題目耗死的難過