A.密码
阿南是一个破译密码的高手。通过频率分析,破解了很多密码的,他截获了一份敌军消息,该消息有N个数字(<=C),他想将这些数字进行排序,使得常用数字排列在不常用的数字前,例如,X的出现次数比Y多,那么X在Y前;如果二者出现次数一样的话,那么按他们在原消息中的先后顺序定。
INPUT
有多组输入,每组输入第一行输入有2个整数, N (1 ≤ N ≤ 1 000)——消息的长度, C (1 ≤ C ≤ 1 000 000 000), 接下来是N个数字表示的消息,每个数字都小于等于C。
OUTPUT
每组输出一行,对N个数进行排序。
input | output |
5 2 2 1 2 1 2 9 3 1 3 3 3 2 2 2 1 1 9 77 11 33 11 77 54 11 25 25 33 | 2 2 2 1 1 1 1 1 3 3 3 2 2 2 11 11 11 33 33 25 25 77 54
|
这道题用map 函数构造映射 注意要构建映射~~
#include<stdio.h>
#include<map>
#include<iostream>
#include<algorithm>
using namespace std;
struct node{
int num; //定义这个值
int sum; // 值的数量
int rank; // 值第一次出现的位置
} a[1100];
int cmp(node a,node b)
{
if(a.sum==b.sum) return a.rank<b.rank;
else {
return a.sum>b.sum;
}
}
int main()
{
int n,m,i,num,j,edge;
while( scanf("%d %d",&n,&m)!=EOF )
{
memset(a,0,sizeof(a));
j=1;
map<int,int>my;
map<int,int>::iterator k;
for(i=1;i<=n;i++)
{
scanf("%d",&num);
if( my.find(num)==my.end() ){ //对其中的值进行查询
a[j].num=num; //标记值
a[j].rank=j; //标记第一次出现的位置
a[j].sum++; //记录个数
my[num]=j++; //完成映射
}
else {
a[my[num]].sum++;
}
}
edge=j-1;
sort(a+1,a+1+edge,cmp);
int flag=0;
for( i=1; i<=edge; i++) //按顺序输出
{
if(flag==0){printf("%d",a[i].num);a[i].sum--;flag=1;} //注意格式
if(flag!=0) {
for(j=1;j<=a[i].sum;j++)
printf(" %d",a[i].num);
}
}
printf("\n");
}
}