密码 stl函数的应用 注意map的使用 2012-10-7

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");
      }
}













  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值