HDU 6168 Numbers
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6168
题目大意:将a[i] + a[j] n >= j > i >= 1的结果放在b数组中。现在将a,b的数据混在一块,请将原始的a数据顺序输出,题目保证有且仅有一组解,并且a数组是非递减的。
解题思路:首先可以发现,混合数组c中c[0] c[1] 一定是在a中的,然后我们将c排序,考虑一个c[x] ,如果c[x] = a[i] + a[j],a[i] a[j]现在都已经确定在a中,并且这样的c[x]第一次出现,那么这个c一定是a中两个数相加而来的,如果这个c找不到对应的a[i] a[j],那么他就是a中的元素。那么我们就可以用一个访问标记来判断是否a[i] + a[j]已经被使用过。但是这样子复杂度会达到0(mn^2). 事实上,对c排序后,对于一个c[x]来说,我们只需看a[i] + a[j]的最小值是否和c[x]相等即可。所以我们可以用一个优先队列来维护已知的a中的数据所能够形成得和。
注意0个数据和1个数据时候的输出。。。
代码:
const int maxn = 2e5 + 5; ll a[maxn]; int tot = 0, m; ll b[505]; struct node{ ll v; int i, j; bool operator < (const node &t) const{ if(v != t.v) return v > t.v; else{ if(i != t.i) return i > t.i; else return j > t.j; } } }; priority_queue<node> q; void solve(){ if(m == 0){ printf("0\n\n"); return; } if(m == 1){ printf("1\n%d\n", a[0]); return; } sort(a, a + m); b[0] = a[0]; b[1] = a[1]; tot = 2; node u; u.v = a[0] + a[1]; u.i = 0; u.j = 1; q.push(u); for(int i = 2; i < m; i++){ ll x = a[i]; bool flag = false; if(q.empty()) { b[tot] = x; int len = tot; for(int j = 0; j < len; j++) { node tmp; tmp.v = x + b[j]; tmp.i = j; tmp.j = tot; q.push(tmp); } tot++; continue; } node u = q.top(); if(u.v != x) { b[tot] = x; int len = tot; for(int j = 0; j < len; j++) { node tmp; tmp.v = x + b[j]; tmp.i = j; tmp.j = tot; q.push(tmp); } tot++; } else q.pop(); } sort(b, b + tot); printf("%d\n", tot); for(int i = 0; i < tot; i++){ printf("%lld", b[i]); if(i < tot - 1) printf(" "); else puts(""); } } int main(){ while(scanf("%d", &m) != EOF){ for(int i = 0; i < m; i++) scanf("%lld", &a[i]); solve(); } }
题目:
Numbers
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 289 Accepted Submission(s):
148
Problem Description
zk has n numbers a1,a2,...,an
. For each (i,j) satisfying 1≤i<j≤n, zk generates a new number (ai+aj)
. These new numbers could make up a new sequence b1,b2,...,bn(n−1)/2
.
LsF wants to make some trouble. While zk is sleeping, Lsf mixed up sequence a and b with random order so that zk can't figure out which numbers were in a or b. "I'm angry!", says zk.
Can you help zk find out which n numbers were originally in a?
LsF wants to make some trouble. While zk is sleeping, Lsf mixed up sequence a and b with random order so that zk can't figure out which numbers were in a or b. "I'm angry!", says zk.
Can you help zk find out which n numbers were originally in a?
Input
Multiple test cases(not exceed 10).
For each test case:
∙ The first line is an integer m(0≤m≤125250), indicating the total length of a and b. It's guaranteed m can be formed as n(n+1)/2.
∙ The second line contains m numbers, indicating the mixed sequence of a and b.
Each ai is in [1,10^9]
For each test case:
∙ The first line is an integer m(0≤m≤125250), indicating the total length of a and b. It's guaranteed m can be formed as n(n+1)/2.
∙ The second line contains m numbers, indicating the mixed sequence of a and b.
Each ai is in [1,10^9]
Output
For each test case, output two lines.
The first line is an integer n, indicating the length of sequence a;
The second line should contain n space-seprated integers a1,a2,...,an(a1≤a2≤...≤an) . These are numbers in sequence a.
It's guaranteed that there is only one solution for each case.
The first line is an integer n, indicating the length of sequence a;
The second line should contain n space-seprated integers a1,a2,...,an(a1≤a2≤...≤an) . These are numbers in sequence a.
It's guaranteed that there is only one solution for each case.
Sample Input
6
2 2 2 4 4 4
21
1 2 3 3 4 4 5 5 5 6 6 6 7 7 7 8 8 9 9 10 11
Sample Output
3
2 2 2
6
1 2 3 4 5 6
Source