CF1072C Cram Time

思路:

首先二分找到使x * (x + 1) / 2 <= a + b最大的x,然后令p = min(a, b), q = max(a, b),按照x,x - 1, ..., 1的顺序选取数字把p填满,把剩下未选择的数字放到q中即可。

实现:

 1 #include <iostream>
 2 #include <set>
 3 #include <vector>
 4 using namespace std;
 5 
 6 typedef long long ll;
 7 
 8 inline bool check(ll x, ll a, ll b)
 9 {
10     return x * (x + 1) / 2 <= a + b;
11 }
12 
13 int main()
14 {
15     ll a, b;
16     while (cin >> a >> b)
17     {
18         ll l = 1, r = 200000, ans = -1;
19         while (l <= r)
20         {
21             ll m = l + r >> 1;
22             if (check(m, a, b))
23             {
24                 l = m + 1;
25                 ans = m;
26             }
27             else
28             {
29                 r = m - 1;
30             }
31         }
32         set<int> st;
33         int x = min(a, b);
34         for (int i = ans; i >= 1; i--)
35         {
36             if (i > x) continue;
37             st.insert(i);
38             x -= i;
39         }
40         set<int> st2;
41         for (int i = 1; i <= ans; i++)
42         {
43             if (!st.count(i)) st2.insert(i);
44         }
45         if (a > b) swap(st, st2);
46         cout << st.size() << endl;
47         for (auto it: st) cout << it << " ";
48         cout << endl;
49         cout << st2.size() << endl;
50         for (auto it: st2) cout << it << " ";
51         cout << endl;
52     }
53     return 0;
54 }
原文地址:https://www.cnblogs.com/wangyiming/p/9834017.html