题目链接:click here~~
【题目大意】给你一个整数序列,求最多选出每个长度为3的且序列元素单调的子序列的个数,并且输出每个子序列的元素,作为一个子序列,每个元素只能选一次,也就是满足一次性,但每个子序列里可以存在相同的元素,
【解题思路】刚开始以为比较简单,就顺着思路写了一遍,第一发W了之后发现此题还是有一定的思维性,之后一直纠结在最多能选出多少子序列,因为考虑到如果序列里相同的元素的个数对最后结果会产生不同的影响,于是就想到了set容器的自动去重。
思想:
1,在判断set.size()大于等于3的情况下,将已经排序(逆序排序,即次数多的元素在前)的元素存到另一个容器里(可以用vector),注意push_back(元素的值)而不是次数
2,删除已经存进的元素,(利用set..erase()),同时判断剩下元素次数是否大于零,是的话重复步骤1,这样一来我们就不用考虑相同元素的影响,因为如果已经选过了,就会立即删除,之后就不会再选,而最后得到的子序列的总个数就是vector的大小。
其实还有其他方法可以解决,暂时没有想到,待更新。。。
代码:
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int num[N];
map <int,int>mapp;
typedef pair<int,int>pii;
set<pii>seet;
vector<int >vec;
int main(){
int t,n,m;
while(scanf("%d",&t)!=EOF){
mapp.clear(),seet.clear(),vec.clear();
for(int i=0; i<t; i++){
scanf("%d",&num[i]);
mapp[num[i]]++;//次数,值
}
map<int,int >::iterator it;
for(it=mapp.begin(); it!=mapp.end(); it++){
seet.insert(pii(it->second,it->first));
}
// set<pii>::iterator itt;
// for(itt=seet.begin(); itt!=seet.end(); itt++)
// {
// cout<<(itt->first)<<" "<<(itt->second)<<endl;
// }
while(seet.size()>=3){
pii ans[3];
for(int i=0; i<3; i++){
ans[i]=*--seet.end();
seet.erase(--seet.end());
vec.push_back(ans[i].second);
}
for(int i=0; i<3; i++){
if(--ans[i].first) seet.insert(ans[i]);
}
sort(vec.rbegin(),vec.rbegin()+3);
}
printf("%d\n",vec.size()/3);
for(int i=0; i<vec.size(); i+=3)
printf("%d %d %d\n",vec[i],vec[i+1],vec[i+2]);
}
return 0;
}
/*
7
7 2 4 3 5 6 1
3
2 2 3
7
1 1 2 3 3 4 5
6
2 3 3 4 5 6
6
2 3 5 5 5 6
*/