A Boring Game
Jeff wants to perform the operations so as to make the absolute value of the difference between the sum of elements before performing the operations and the sum of elements after performing the operations as small as possible. Help him find the minimum absolute value of the difference.
輸入:
In the first line is a number?TT?(T≤100T≤100) indicating the cases following. In each case, the first line contains an integer?nn?(1≤n≤20001≤?n?≤?2000). The next line contains?2n2n?real numbers?a1,a2,…,a2na1,a2,…,a2n?(0≤ai≤100000?≤?ai?≤?10000), given with exactly three digits after the decimal point. The numbers are separated by spaces. 輸出:
Print?TT?lines. In each line print a single real number — the required difference with exactly three digits after the decimal point.
樣例:
1 3 1.500 1.750 2.000 3.000 4.000 5.000 樣例輸出:
0.250
題目大意:給定2n個小數,并執行n次操作,每次操作同時操作兩個數,把其中的一個向上取整,另一個向下取整。問,在執行完操作以后數列的和與執行操作以前數列的和差值最小是多少。
題解:
這個題實際上也并不難,但比賽時候很多人沒做出來。
思路是這樣的,因為x.000這樣的數不論向上取整還是向下取整都是一樣的,所以我們可以不考慮這些數的求和,而僅僅是統計這些數的個數,假設他們的總數為cnt。
而對于其他的小數來說,如果向上取整,那么相當于+1,如果向下取整,相當于不加。
因此我們用所有小數部分的和表示操作以前的數的和,例如sum1 = 0.500+0.750 = 1.250
而用向上取整的小數的個數代表操作后的小數的和,例如sum2 = 1或sum2 = 2或sum2 = 0
這樣的話差值就是sum1-sum2了,我們只要求出sum2中可以向上取整的小數個數的范圍就行了。
顯然,范圍是max(0,n-cnt) 到 min(n,2*n-cnt)
AC代碼:
#include <iostream> #include <cstdio> using namespace std; const double INF = 1e9; double iabs(double x) {return x>0?x:-x;} int main() {int T;scanf("%d",&T);while(T--){int cnt = 0;double sum = 0;int n;scanf("%d",&n);for(int i = 0;i < 2*n;i++){double d;scanf("%lf",&d);double x = d - int(d);if(x < 0.000001) cnt++;sum += x;}double ans = INF; for(int i = max(0,n-cnt);i <= min(2*n-cnt,n);i++){ans = min(ans,iabs(sum - (double)i));}printf("%.3lf\n",iabs(ans));}return 0; }
總結
以上是生活随笔為你收集整理的A Boring Game的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大众汽车宣布明年开始将在挪威取缔燃油车,
- 下一篇: 等差区间 线段树+GCD