排序专题(hrbeuOJ)

谁是中间的那个

TimeLimit: 1 Second   MemoryLimit: 64 Megabyte

Totalsubmit: 1363   Accepted: 226  

Description

一天,农夫乔伊像往常一样来到了他的牧场,他突然对他的奶牛产奶量产生了兴趣。
他想知道产奶量处于中间的那头奶牛的产奶量是多少,处于中间的意思是说,其中有一半牛的产奶量比它多,另一半牛的产奶量比它少。
    这个问题现在交由你来写程序完成!

Input

仅包括一组测试数据,第一行一个正整数N(1<=N<=10,000),接下来N行,每行一个正整数不会超过10^6,第i+1行的数字代表第i头牛的产奶量。

Output

产奶量处于中间的牛的产奶量。

Sample Input

5
1
2
4
5
3

Sample Output

3

Source

[p][/p]

解题报告:
产奶量从小到大排序,如果 产奶量相同的按顺序从大到小的排列,然后找到中间的位置即可。
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
struct node{
    int num;
    int milk;
}s[10010];
bool cmp(const node &a,const node &b){
    if(a.milk==b.milk){
        if(a.num>b.num)
            return a.num>b.num;
        else
            return a.num<b.num;
    }
    return a.milk<b.milk;
}
int main(){
    int t,i;
    while(scanf("%d",&t)==1){
        for(i=1;i<=t;i++){
            scanf("%d",&s[i].milk);
            s[i].num=i;
        }
        sort(s+1,s+t+1,cmp);
        printf("%d\n",s[(t+1)/2].milk);
    }
    return 0;
}

一问一答

TimeLimit: 1 Second   MemoryLimit: 64 Megabyte

Totalsubmit: 485   Accepted: 133  

Description

现在输入一个序列,这个序列中有N个数字,输入时他们是无序的,而后他们会被写到数据库当中,在数据库当中他们将被按照从小到大的顺序排好。当有人在外部向数据库输入一个数字n时,数据库会返回当中的第n小的数。
现在由你来编写程序模拟这一过程。

Input

包括两部分,第一部分为输入部分,第一行一个正整数N,代表数据库中共存有N个数,接下来N行,每行一个正整数,代表依次向数据库中存储的数字。接下来一行是3个‘#’。下面是询问部分,询问部分第一行一个正整数K,接下来K行每行一个正整数ki,代表要询问第ki小的数。(1<=K,N<=5000),每个插入的数字不超过10,000。

Output

对于每个询问输出一行,代表第ki小的数。

Sample Input

5
7
121
123
7
121
###
4
3
3
2
5

Sample Output

121
121
7
123


解题报告:
从小到大排序即可。
#include <iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int s[120000];
char m[10];
int main(){
    int t,i,n;
    scanf("%d",&t);
    for(i=0;i<t;i++)
        scanf("%d",&s[i]);
    sort(s,s+t);
    getchar();
    gets(m);
    scanf("%d",&t);
    for(i=0;i<t;i++){
        scanf("%d",&n);
        printf("%d\n",s[n-1]);
    }
    return 0;
}

1103 487-3279

TimeLimit: 1 Second   MemoryLimit: 64 Megabyte

Totalsubmit: 302   Accepted: 84  

Description

商业上一般愿意采用易记的电话号码。把电话号码映射成一个容易记住的单词是其中一种方法。比如,你可以把滑铁卢大学的电话号码记为 TUT-GLOP。有些时候,只有一部分数字能用来进行这种字母与数字间的映射。另外一种方法使得电话号码容易被记住,就是将电话号分割成有规律的几块,然后进行记忆。例如,订购匹萨的电话为 310-1010,可以记为一个3,三个10,即3-10-10-10。
电话号码的标准形式为前三后四(例如,888-1200)。下面是一些字母所映射的数字:
A, B, 和C 映射到 2 
D, E, 和F映射到3 
G, H, 和I映射到4 
J, K, 和L映射到5 
M, N, 和O映射到6 
P, R, 和S映射到7 
T, U, 和V映射到8 
W, X, 和Y映射到9 
这里没有数字对应于Q或者是Z。‘-’不是必须的,它可以被任意的移动,添加或者删除。例子中的TUT-GLOP就是电话号码888-4567,例子中的3-10-10-10 就是电话号码310-1010。
两个电话号码相同,当且仅当他们的标准形式相同。
你的公司正在编译一本当地的联系薄。作为质量控制的一部分,你要确定中间是否有重复的电话号码。

Input

输入包括一组测试数据。测试数据的第一行包括一个正整数(不超过100,000),表示电话号码的个数。接下来N行每行一个电话号码,电话号码由数字,字母以及‘-’组成。其中出现的字母均为大写字母(Q和Z不会出现在里面)。

Output

对于每一个出现超过两次的电话号码均输出一行。该行由三部分组成,标准形式的电话号码+一个空格+该电话号码出现的次数。输出的电话号码顺序按照电话号码的字典序从进行排序。如果没有重复出现的电话号码,则输出一行“No duplicates.”

Sample Input

12
4873279
ITS-EASY
888-4567
3-10-10-10
888-GLOP
TUT-GLOP
967-11-11
310-GINO
F101010
888-1200
-4-8-7-3-2-7-9-
487-3279

Sample Output

310-1010 2
487-3279 4
888-4567 3


解题报告:
先把字符转化成数字,然后从小到大排序。如果有重复的再把每个数字分开,不够7位的补0,然后输出即可。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
int num[26]={2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,0,7,7,8,8,8,9,9,9,0};
char s[50];
int h[8];
int ss[100010];
int main(){
    int i,j,t,len,tmp,flag,snum;
    while(scanf("%d",&t)==1){
        for(i=0;i<t;i++){
            scanf("%s",s);
            len=strlen(s);
            tmp=0;
            for(j=0;j<len;j++){
                if(s[j]>='0'&&s[j]<='9')
                    tmp=tmp*10+(s[j]-'0');
                if(s[j]>='A'&&s[j]<='Z')
                    tmp=tmp*10+num[s[j]-'A'];
                }
                ss[i]=tmp;
        }
        sort(ss,ss+t);
        flag=0;snum=1;
        for(i=1;i<=t;i++){
            if(ss[i-1]==ss[i]){
                snum++;
                flag=1;
            }
            else{
                if(flag&&snum>1){
                    int tmp1;
                    tmp1=ss[i-1];
                    j=0;
                    while(tmp1){
                        h[j++]=tmp1%10;
                        tmp1/=10;
                    }
                    for(;j<7;j++)
                        h[j]=0;
                    for(j=6;j>=0;j--){
                        printf("%d",h[j]);
                        if(j==4)
                            printf("-");
                    }
                    printf(" %d\n",snum);
                    snum=1;
                }
            }
        }
        if(!flag)
            printf("No duplicates.\n");
    }
    return 0;
}

DNA排序

TimeLimit: 1 Second   MemoryLimit: 64 Megabyte

Totalsubmit: 372   Accepted: 96  

Description

逆序数可以用来是描述一个序列混乱成度的量。例如,“DAABEC”的逆序数为5,其中D大于它右边的4个数,E大于它右边的1个数,4+1=5;又例如“ZWQM”的逆序数为3+2+1+0=6。
现在有许多长度一样的字符串,每个字符串里面只会出现四种字母(A,T,G,C)。你现在被要求编写程序将这些字符串按照他们的逆序数进行排序。

Input

第一行包括两个正整数,第一个正整数N给出了字符串的长度,第二个正整数M给出了字符串的数量。(1<=N,M<=100)

Output

将输入的字符串按照其逆序数进行排序,如果两个字符串的逆序数相等,则按照输入中两者的先后顺序进行排列。

Sample Input

10 6
AACATGAAGG
TTTTGGCCAA
TTTGGCCAAA
GATCAGATTT
CCCGGGGGGA
ATCGATGCAT

Sample Output

CCCGGGGGGA
AACATGAAGG
GATCAGATTT
ATCGATGCAT
TTTTGGCCAA
TTTGGCCAAA

解题报告:
把每个字符串的逆序数算出来,从小到大排序,如果逆序数相同则按照 两者的先后顺序进行排列。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node{
    char s[110];
    int num1,num2;
}t[110];
bool cmp(const node &a,const node &b){
    if(a.num2==b.num2)
        return a.num1<b.num1;
    return a.num2<b.num2;
}
int main(){
    int i,j,k,a,b;
    while(scanf("%d%d",&a,&b)==2){
        for(i=1;i<=b;i++){
            scanf("%s",t[i].s);
            t[i].num1=i;
            t[i].num2=0;
            for(j=0;j<a;j++){
                for(k=j+1;k<a;k++){
                    if(t[i].s[j]>t[i].s[k])
                        t[i].num2++;
                }
            }
        }
        sort(t+1,t+b+1,cmp);
        for(i=1;i<=b;i++)
            printf("%s\n",t[i].s);
    }
    return 0;
}

统计频率

TimeLimit: 1 Second   MemoryLimit: 64 Megabyte

Totalsubmit: 138   Accepted: 55  

Description

AOA非常喜欢阅读莎士比亚的诗,莎士比亚的诗中有种无形的魅力在吸引着他!他认为莎士比亚的诗之所以写得如此传神,应该是他的构词非常好!所以他想知道,在莎士比亚的书中,每个单词出现的频率各是多少。

Input

输入一个单词列表,每行一个单词,每个单词的长度不会超过30,单词的种类不会超过10,000,单词的总数不会超过1,000,000个。

Output

对于输入的单词列表,输出一个列表,每行一个“单词+空格+该单词出现的频率”,输出列表按照输入中出现的单词的字典序进行排列。

Sample Input


Red Alder
Ash
Aspen
Basswood
Ash
Beech
Yellow Birch
Ash
Cherry
Cottonwood
Ash
Cypress
Red Elm
Gum
Hackberry
White Oak
Hickory
Pecan
Hard Maple
White Oak
Soft Maple
Red Oak
Red Oak
White Oak
Poplan
Sassafras
Sycamore
Black Walnut
Willow

Sample Output


Ash 13.7931
Aspen 3.4483
Basswood 3.4483
Beech 3.4483
Black Walnut 3.4483
Cherry 3.4483
Cottonwood 3.4483
Cypress 3.4483
Gum 3.4483
Hackberry 3.4483
Hard Maple 3.4483
Hickory 3.4483
Pecan 3.4483
Poplan 3.4483
Red Alder 3.4483
Red Elm 3.4483
Red Oak 6.8966
Sassafras 3.4483
Soft Maple 3.4483
Sycamore 3.4483
White Oak 10.3448
Willow 3.4483
Yellow Birch 3.4483


解题报告:
使用map解决
#include<iostream>
#include<string>
#include<cstdio>
#include<map>
using namespace std;
int main(){
    char str[50];
    int count=0;
    map<string,int> counter;
    map<string,int> ::iterator it;
    while(gets(str)!=NULL){
        counter[str]++;
        count++;
    }
    cout.setf(ios::fixed);
    cout.precision(4);
    for(it=counter.begin();it!=counter.end();it++){
        double per = 100*((double)it->second/(double)count);
        cout<<it->first<<" "<<per<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值