题目:http://codeforces.com/contest/962/problem/D
题目大意:给定一串正整数,至少有两个相同的数。重复做以下操作:
找到相同的,最先出现的,最小的,两个数,把位置在前面的数去掉,位置排在后面的那个数翻倍。
例如:
给定字串为[3,4,1,2,2,1,1]
[3,4,1,2,2,1,1] → [3,4,2,2,2,1] → [3,4,4,2,1] → [3,8,2,1].
给定字串为 [1,1,3,1,1]
[1,1,3,1,1] → [2,3,1,1] → [2,3,2] → [3,4]。
第一行一个整数 n (2≤n≤150000) 这一串整数的个数
第二行 你个正整数 a1,a2,…,an (1≤ai≤109)
第一行一个整数 K — 剩下的数的个数
第二行输出这k个数
7 3 4 1 2 2 1 1
4 3 8 2 1
5 1 1 3 1 1
2 3 4
5 10 40 20 50 30
5 10 40 20 50 30
Test 6 Wrong Answer。
原因:寻找最小值,由于单个数据最大值是10^9,设置的初始比较值为10^9+1,然而150000个数据合并后的最大值客达到1.5*10^14.
Test 7 Time limit exceeded.
原因:暴力模拟。O(n^3).
解决办法:使用优先队列。include<queue>
include<bits/stdc++.h>包含了目前c++所包含的所有头文件。
注意: 1.不是标准头文件
2.有的oj不支持
3.编译时间慢
代码:
#include<iostream>
#include<queue>
using namespace::std;
struct a{
long long value;
int order;
};
struct cmp1{
bool operator() (a &t,a &s)
{
if(t.value == s.value)
return t.order > s.order;//序列小的优先级高
else return t.value > s.value;//数值小的优先级高
}
};
struct cmp2{
bool operator() (a &t,a &s)
{
return t.order > s.order;
}
};
int main()
{
priority_queue<a,vector<a>,cmp1 > q1;
priority_queue<a,vector<a>,cmp2 > q2;
a num,temp;
int i,n;
cin>>n;
for(i=0;i<n;i++){
cin>>num.value;
num.order=i;
q1.push(num);
}
while(!q1.empty()){
temp=q1.top();
q1.pop();
//优先级前两个值相同则合并
if(q1.empty() || temp.value!=q1.top().value ){
q2.push(temp);
}
else {
temp=q1.top();
temp.value*=2;
q1.pop();
q1.push(temp);
}
}
cout<<q2.size()<<endl;
while(!q2.empty()){
cout<<q2.top().value<<' ';
q2.pop();
}
return 0;
}
看到大多数人用map写的mark一下回头学一下