牛客网练习赛15-B

链接: https://www.nowcoder.com/acm/contest/83/B
#include<bits/stdc++.h>
//#include<windows.h>
using namespace std;
#define ll long long
#define inf 1e-5
const int inv2=500000004;
const int INF=2147483647;
const int MAX=100010;
const int mod=1e9+7;
struct v2{
    char name[15]="";
    int num0=0;
};
struct Node{
    Node *son[10];
    vector<v2>li;
    Node(){
        for(int i=0;i<10;i++){
            son[i]=NULL;
        }
    }
};
 
bool cmp(const v2 &a,const v2 &b){
    return strcmp(a.name,b.name)<0;
}
Node *root=new Node();
char str[MAX*6];
char name[15];
 
int toInt(char c){
    return c-'0';
}
void dfs(Node *now,int step){
    int i,j;
 
    for(i=9;i>=0;i--){
        if(now->son[i]){
            str[step]=i+'0';
            dfs(now->son[i],step+1);
        }
    }
 
    if(now->li.size()>0){
        sort(now->li.begin(),now->li.end(),cmp);
        for(j=0;j<now->li.size();j++){
            printf("%s ",now->li[j].name);
            printf("%c.",str[0]);
            for(i=1;i<step;i++){
                printf("%c",str[i]);
            }
            for(i=0;i<now->li[j].num0;i++){
                printf("0");
            }
            printf("\n");
        }
    }
    str[step]=0;
}
 
int main(int argc,char *argv[]){
    //freopen("in.txt","r",stdin); //输入重定向,输入数据将从in.txt文件中读取
    //freopen("out.txt","w",stdout); //输出重定向,输出数据将保存在out.txt文件中
    //srand(time(NULL));//有的OJ不能加这句话
    int i,m,j,k,n,len,num0;
    char c;
    v2 temp;
    Node *now,*node;
    scanf("%d",&n);
    for(j=0;j<n;j++){
        scanf("%s",temp.name);
        num0=0;
        str[0]='#';
        getchar();
        for(i=0;;i++){
            scanf("%c",&str[i]);
            if(str[i]=='\n')
                break;
            if(str[i]=='0'){
                num0++;
            }else{
                num0=0;
            }
        }
        len=i-num0;
        k=toInt(str[0]);
        now=root;
        if(now->son[k]){
            now=now->son[k];
        }else{
            node=new Node();
            now=now->son[k]=node;
        }
        for(i=2;i<len;i++){
            k=toInt(str[i]);
            if(now->son[k]){
                now=now->son[k];
            }else{
                node=new Node();
                now=now->son[k]=node;
            }
        }
        temp.num0=num0;
        now->li.push_back(temp);
    }
    memset(str,0,sizeof(str));
    dfs(root,0);
return 0;
}


来源:牛客网

题目描述

第一次期中考终于结束啦!沃老师是个语文老师,他在评学生的作文成绩时,给每位学生的分数都是一个小于10的非负小数。

Amy 8.999999999999999999999999999999999999999990000

Bob 8.9999999999999999999999999999999999999999800

Cat 8.9999999999999999999999999999999999999999899999999

沃老师并不会告诉大家分数的排名,但学生间竞争激烈,大家都想知道自己的作文成绩在班上的排名。
但由于作文分数的小数部分可能超级长,难以用肉眼比较两个数的大小关系,请你帮忙写个程序,把所有学生按照作文分数排序吧〜


输入描述:

输入共有N + 1行。
第一行有一个正整数N,代表班上有几个人。
接下来N行中的第i行,包含一个字符串namei,以及一个小数scorei,分别代表第i个人的名字以及第i个人的作文得分。

输出描述:

输出总共N行,每行由一个名字和一个小数构成,第i行代表着分数第i高的人的名字以及他的作文得分,代表作文得分的小数必须和输入一模一样,也就是原本末尾有多少零,输出也要有相同数量的零。
若分数相同,则名字字典序比较小的放在前面。


这题看似是高精度排序(难道就这么简单?),其实仔细看每个高精度浮点数长度是len=6*1e5,高精度比较的时间是o(len);算上排序要超时的,为了防止高精度压位,数据还特地是6*1e5,要是6*1e4没准优化能混过去。

知道排序不行,正解也很快能想到,字典树的dfs去输出

在输入时候构建字典树,但是有个细节。若分数相同,则名字字典序比较小的放在前面。
 

字典树节点维护10个指针之外,还有一个列表用c++的vector表示,列表是空表示,没有以当前节点结束的字符串

 

注意这句,分数相同意味着浮点数数值相同,相同情况下按照名字字典序输出

那么在程序输入就要处理这块,把每个名字后缀没用的0去掉,同时记录去掉多少0

 

然后怎么样,每次输入完字符串,插入字典树。

每个字符串插入完成后在结束的节点的vector插入数据,有2个数据,刚才记录的去掉多少0,以及人的名字,也就是vector也要维护一个结构体

 

怎么输出,dfs字典树,用后续输出的方式。

迭代输出列表的元素(如果有的话),输出前要sort对名字排序,按照字典序

好了这道题就完成了

 代码:



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值