链接:
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对名字排序,按照字典序
好了这道题就完成了
代码: