爱思创 180312 Merge Equals 题解
Merge Equals
练习使用 结构体优先队列
思路:
先定义结构体,要存初始位置和数值,并定义比大小规则:数值小优先,数值相同位置靠前者优先 注意:在优先队列中小值优先要使用大于号
struct node
{
long long id, x;
friend bool operator < (node a, node b)
{
if(a.x != b.x) return a.x > b.x;
return a.id > b.id;
}
};
再建一个记录答案的数组 \(a\)(开int60分)和优先队列 \(q\)
priority_queue<node> q;
long long a[1000005];
(输入就不用讲了吧?)
接下来要模拟题目要求的过程:
找到最小的数值x(x重复出现了2次或2次以上),删除第1次出现的x,将第2次出现的x改为2*x(数值在原来基础上乘以2),直到序列中没有哪个数值重复出现2次或2次以上。
中间需用 \(cnt\) 记录删除了几个数
int cnt = 0;
while(!q.empty())
{
node x1 = q.top(), x2;//取数1
q.pop();
if(!q.empty())//小心:如果队列里只有一个数,说明操作完成
{
x2 = q.top();
q.pop();
}
else
{
break;
}
if(x1.x == x2.x)//如果最小的两个数相等
{
a[x1.id] = -1;//数1删除
cnt ++;//删除数量加1
a[x2.id] *= 2;//数2乘2
q.push(node{x2.id, a[x2.id]});//把数2乘2的结果再次放进优先队列
}
else
{
q.push(x2);//否则说明数1只有一个,不用管。数2放回去
}
}
最后输出答案:
cout << n - cnt << endl;//总数 - 删除数 就是剩了几个数
for(int i = 1; i <= n; i ++)
{
if(a[i] != -1) cout << a[i] << ' ';
}
完整代码
#include<bits/stdc++.h>//不介意我使用万能头吧?
using namespace std;
struct node
{
long long id, x;
friend bool operator < (node a, node b)
{
if(a.x != b.x) return a.x > b.x;
return a.id > b.id;
}
};
priority_queue<node> q;
long long a[1000005];
int main()
{
int n, x;
cin >> n;
for(int i = 1; i <= n; i ++)
{
cin >> a[i];
q.push(node{i, a[i]});
}
int cnt = 0;
while(!q.empty())
{
node x1 = q.top(), x2;
q.pop();
if(!q.empty())
{
x2 = q.top();
q.pop();
}
else
{
break;
}
if(x1.x == x2.x)
{
a[x1.id] = -1;
cnt ++;
a[x2.id] *= 2;
q.push(node{x2.id, a[x2.id]});
}
else
{
q.push(x2);
}
}
cout << n - cnt << endl;
for(int i = 1; i <= n; i ++)
{
if(a[i] != -1) cout << a[i] << ' ';
}
return 0;
}
hello, I'm yuzihang, if you need to copy this, please quote this url: https://www.cnblogs.com/yuzihang/articles/16726295.html

浙公网安备 33010602011771号