1.题目链接。题目大意:题目中本来有n个数据,但是任意选两个数据相加得到新的数据,现在把产生的数据和原来的数据混合在一起,让你找出来原来的n个数据。
2.分析一下,由于这些数据都是整数,所以我们首先对数据排序,那么前边两个最小的一定是原来数组中的数据,那么我们就可以通过这两个数据找出全部的数据,本来是自己模拟一下就知道了,我们可以用一个vis数组来标记数据,比如说,我们首先发现的是a[0],a[1],用一个vec存起来,然后求和一下vis[a[0]+a[1]]++,这样标记一下,然后找a[3],看看a[3]是不是被vis过,如果没有,就说明这个数据是原始数据,否则就vis--,以此类推。但是数据是1e9,数据显然是不可行的,所以我们用一个map<int,int>mp映射一下。然后解决了。当然了,这个题不难,还可以用优先队列维护一下,也是可以的。
using namespace std;
const int maxn = 150000;
int ab[maxn];
vector<int>a;
int main()
{
int n, m;
while (~scanf("%d", &m))
{
if (m == 0)
puts("0");
else
{
n = (sqrt(8 * m + 1) - 1) / 2 + 0.5;
for (int i = 1; i <= m; i++)
{
scanf("%d", ab + i);
}
sort(ab + 1, ab + m + 1);
a.clear();
a.push_back(ab[1]);
a.push_back(ab[2]);
map<int, int>mp;
mp[ab[1] + ab[2]]++;
for (int i = 3; i <= m; i++)
{
if (mp[ab[i]] > 0)
mp[ab[i]]--;
else
{
a.push_back(ab[i]);
for (int j = 0; j + 1 < a.size(); j++)
{
mp[a[j] + ab[i]]++;
}
}
}
printf("%d\n", n);
for (int i = 0; i < n; i++)
{
printf("%d", a[i]);
if (i == n - 1)printf("\n");
else printf(" ");
}
}
}
}