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,所以我才會好奇,標程到底長啥樣。
看到真相的我哭了
那年院賽,就是被這個題目耗死的