大一寒假培训(二)

今天是寒假培训的第二天,今天学了快排和桶排。以下是今天做的习题。

nefu 1481 谁考了第k名-排序

Description
在一次考试中,每个学生的成绩都不相同,现知道了每个学生的学号和成绩,求考第k名学生的学号和成绩。
Input
第一行有两个整数,分别是学生的人数n(1≤n≤100),和求第k名学生的k(1≤k≤n)。
其后有n行数据,每行包括一个学号(整数)和一个成绩(浮点数),中间用一个空格分隔。
Output
输出第k名学生的学号和成绩,中间用空格分隔。(注:请用%g输出成绩)
Sample Input
5 3
90788001 67.8
90788002 90.3
90788003 61
90788004 68.4
90788005 73.9
Sample Output
90788004 68.4

#include <bits/stdc++.h>
using namespace std;
typedef struct stu{int num;double grade;
}stu;
stu p[200];
int cmp(stu a,stu b)    //按成绩从大到小的顺序排序
{return a.grade>b.grade;}
int main()
{int n,k;while(cin>>n>>k){for(int i=0;i<n;i++)cin>>p[i].num>>p[i].grade;sort(p,p+n,cmp);printf("%d %g\n",p[k-1].num,p[k-1].grade);}return 0;
}

nefu 1482 奇数单增序列

Description
给定一个长度为N(不大于500)的正整数序列,请将其中的所有奇数取出,并按升序输出
Input
共2行:
第1行为 N;
第2行为 N 个正整数,其间用空格间隔。
Output
增序输出的奇数序列,数据之间以逗号间隔。数据保证至少有一个奇数。
Sample Input
10
1 3 2 6 5 4 9 8 7 10
Sample Output
1,3,5,7,9

#include <bits/stdc++.h>
using namespace std;
int num1[500],num2[500];
int main()
{int n,j;while(cin>>n){j=0;for(int i=0;i<n;i++)    //输入数据cin>>num1[i];for(int i=0;i<n;i++) //将奇数从num1数组中取出,放到num2数组if(num1[i]%2)num2[j++]=num1[i];sort(num2,num2+j);    //默认从小到大排序for(int i=0;i<j;i++){if(i==j-1)cout<<num2[i]<<endl;elsecout<<num2[i]<<',';}}return 0;
}

nefu 1483 成绩排序

Description
给出班里某门课程的成绩单,请你按成绩从高到低对成绩单排序输出,如果有相同分数则名字字典序小的在前。
Input
第一行为n (0 < n < 20),表示班里的学生数目;
接下来的n行,每行为每个学生的名字和他的成绩, 中间用单个空格隔开。名字只包含字母且长度不超过20,成绩为一个不大于100的非负整数。
Output
把成绩单按分数从高到低的顺序进行排序并输出,每行包含名字和分数两项,之间有一个空格。
Sample Input
4
Kitty 80
Hanmeimei 90
Joey 92
Tim 28
Sample Output
Joey 92
Hanmeimei 90
Kitty 80
Tim 28

#include <bits/stdc++.h>
using namespace std;
typedef struct stu{char name[20];int grade;
}stu;
stu p[20];
bool cmp(stu a,stu b)   //先按成绩排序,若成绩相同,则按名字字典顺序排序
{if(a.grade==b.grade) return strcmp(a.name,b.name)<0;else return a.grade>b.grade;
}
int main()
{int n;while(cin>>n){for(int i=0;i<n;i++)cin>>p[i].name>>p[i].grade;sort(p,p+n,cmp);for(int i=0;i<n;i++)cout<<p[i].name<<' '<<p[i].grade<<endl;}return 0;
}

没什么好说的,基础的结构体快排。

nefu 1659 没必要的排序1

Description
羽裳有n个数,她想知道前k大的数的和为多少
Input
首先输入两个数n,k,代表有n个数,求前k大的和,接下来输入n个数,这n个数或是0或是1.
1<=k<=n<=1000
Output
输出一个数,为前k大的和
Sample Input
5 3
0 0 1 0 1
Sample Output
2

#include <bits/stdc++.h>
using namespace std;
int num[1000];
int main()
{int n,k,sum;while(cin>>n>>k){for(int i=0;i<n;i++)cin>>num[i];sort(num,num+n,greater<int>());        //按照从大到小排序sum=0;for(int i=0;i<k;i++)sum+=num[i];cout <<sum<<endl;}return 0;
}

nefu 1650 没必要的排序2

Description
羽裳有n个数,她想知道前k大的数的和是多少
Input
输入n,k代表有n个数,求前k大的和,之后输入n个数,第i个数为a[i]
1<=n<=10000000(1e7)
1<=k<1000
对任意的i
1<=a[i]<=100000(1e5)
Output
输出一个数ans,ans是前k大数的和
Sample Input
2 1
99999 1
Sample Output
99999

前一道题的加强版。
说实话做这道题的时候,想用快排直接做,结果直接TLE了。
后来想了想,考虑用桶排做,果然对了。

#include <bits/stdc++.h>
using namespace std;
int a[100001]={0}; //创建一个1e7的桶
int main()
{long long ans;int n,k,x,z;while(cin>>n>>k){for(int i=1;i<=100000;i++)a[i]=0;for(int i=0;i<n;i++){    //输入数据,并把它放进桶中cin>>x;a[x]++;}ans=z=0;for(int i=100000;i>0;i--){    //从大到小累加,发现加多之后,把多余部分去除if(a[i]){z+=a[i];ans+=a[i]*i;if(z>=k){ans-=i*(z-k);break;}}}cout<<ans<<endl;}return 0;
}

中间加和的时候还可以这样

if(a[i]){        //这个方法好在每次只加a[i]和k-z的最小值,不会出现多加的情况ans+=min(a[i],k-z)*i;z+=a[i];if(z>=k)  break;
}

nefu 554 老和尚的导员

Description
等小和尚回来后,老和尚居然没有睡觉。老和尚表示他的导员的excel表格坏掉了(老和尚居然有导员?好吧……据说是方丈),而且老和尚的导员要老和尚将寺中所有和尚的期末考试成绩按降序排列来发奖学金(和尚还有奖学金?)
不用多说,为了继续睡午觉,这个任务理所当然的落在了小和尚身上。所有……你继续帮忙吧。
Input
寺中主要考试科目有C语言,线性代数,高等数学和英语四个科目(怎么当和尚都这么累),输入的第一行是和尚的人数N(N<=100),第二行至第N+1行分别为C语言a[i],线性代数b[i],高等数学c[i]和英语的成绩d[i](0 <= a[i],b[i],c[i],d[i] <= 100)。
Output
现需要你将和尚们的成绩以总成绩降序排列,输出数据的每行有两个数字,第一个数字为和尚的编号(输入时的第一个和尚成绩即为和尚1,第二个为和尚2),第二个数字为和尚的总成绩(如果总成绩相同,则按C语言的成绩排列,如在相同,则按线性代数输出编号,以此类推。)
Sample Input
5
98 50 27 65
58 52 24 16
98 96 90 89
31 65 98 78
65 67 66 90
Sample Output
3 373
5 288
4 272
1 240
2 150

#include <bits/stdc++.h>
using namespace std;
typedef struct stu{int num,sum;int c;       //C语言成绩int xd;      //线代成绩int gs;       //高数成绩int yy;       //英语成绩
}stu;
stu a[100];
bool cmp(stu a,stu b)   //函数以return为结束,所以可以不必写else
{if(a.sum!=b.sum)    return a.sum>b.sum;        //先按总成绩排序if(a.c!=b.c)        return a.c>b.c;            //总成绩相同,按C语言成绩排序if(a.xd!=b.xd)      return a.xd>b.xd;        //C语言成绩相同,按线代成绩排序if(a.gs!=b.gs)      return a.gs>b.gs;       //线代成绩相同,按高数成绩排序return a.yy>b.yy;     //高数成绩相同,按英语成绩排序
}
int main()
{int n;while(cin>>n){for(int i=0;i<n;i++){cin>>a[i].c>>a[i].xd>>a[i].gs>>a[i].yy;a[i].num=i+1;    //对每个和尚进行标号a[i].sum=a[i].c+a[i].xd+a[i].gs+a[i].yy; //求总成绩}sort(a,a+n,cmp);    //调用cmp函数,按照cmp函数的要求排序for(int i=0;i<n;i++)cout << a[i].num << " " << a[i].sum <<endl;}return 0;
}

nefu 556 健忘的老和尚

Description
当小和尚排完名单后,老和尚突然一拍脑袋:“导员把每个人的人名都给我了,可我忘记告诉你了。”好吧……我们可怜的小和尚看来要费二遍事了(好像之前的任务都是你帮他做的,好吧,你真可怜)
Input
输入数据为多组,输入的第一行为和尚的人数N,可以得到奖学金的人数M,和需要补考的人数O(在这里可以满足M+O<=N,即得到奖学金的和尚一定不用参加补考)。之后的N行每行都有一个字符串(即为和尚的名字,长度小于100)和尚考试的总分a[i](0 <= a[i] <= 1000)。
Output
前M行,每行是获得奖学金的小和尚的名字;
后O行,每行是补考的小和尚的名字;
由于老和尚觉得很对不起小和尚,所以他决定这次简单些,所以无论是奖励还是惩罚都按照总成绩从低到高输出和尚的名字即可。
Sample Input
5 1 2
a 192
aa 212
ab 351
bab 128
bbaa 654
Sample Output
bbaa
bab
a

#include <bits/stdc++.h>
using namespace std;
typedef struct stu{char name[100];int grade;
} stu;
stu a[100];
bool cmp(stu a,stu b)       //按照成绩从低到高排序
{return a.grade<b.grade;}
int main()
{int n,m,o;swhile(cin>>n>>m>>o){for(int i=0;i<n;i++)cin>>a[i].name>>a[i].grade;sort(a,a+n,cmp);for(int i=n-m;i<n;i++)        //题目要求先输出有奖学金的,再输出补考的cout<<a[i].name<<endl;for(int i=0;i<o;i++)cout<<a[i].name<<endl;}return 0;
}

nefu 873 戏说三国

Description
东汉末年,宦官当权,民不聊生。灵帝中平元年,张角兄弟发动黄巾起义,官军闻风丧胆。为抵抗黄巾,幽州太守刘焉出榜招兵。榜文前,刘备、关羽、张飞三兄弟萍水相逢。三人都有为国效力之心,于是桃园结为异姓兄弟,开始了一段三国浪漫传奇……
如果我问你三国中谁最聪明你一定会说是诸葛亮,我要问你谁武功最高,保不准你就要说关羽。是啊,我们的刘备对于优秀的手下向来十分满意。可是有一天,刘备在无意间在朋友圈里看到了梁山的宋江正在进行英雄排座次,最可气的是这条动态已经被转发评论了无数次了……这一下可气坏了刘备,他决定也来一次,蜀中文武百官大排名。
为了公平起见,诸葛亮帮他制定一条评分标准:每个官员有一个智育、德育、武育三个分数,分别以b%,a%,c%的比率计入加权总分,按总分降序排列,总分相同按智育折合后的分数降序,智育相同按德育,依次类推最终决定排名。(保证没有排名一样的两个人)
Input
输入第一行t(1<=t<=1000)表示输入的组数。接下来每组第一行1个整数n(1<=n<=100000)三个实数a,b,c(a+b+c=100)接下来n行每行包括英雄的名字,字符串s(1<=len<=20,全为小写字母) 智育、德育、武育的分数(整数)。(1~100)
Output
每组第一行输出是第几组输出Case #t:接下来输出n行每行包括英雄的名字,总分,智育、德育、武育折合后的分数(保留四位小数)。
Sample Input
1
3 20.00 20.00 60.00
zhugeliang 90 80 0
zhangfei 0 0 100
guanyu 10 100 100
Sample Output
Case #1:
guanyu 82.0000 2.0000 20.0000 60.0000
zhangfei 60.0000 0.0000 0.0000 60.0000
zhugeliang 34.0000 18.0000 16.0000 0.0000

#include <bits/stdc++.h>
using namespace std;
typedef struct hero{char name[20];int num;double zy,dy,wy,sum;
}hero;
hero a[100000];
bool cmp(hero a,hero b)
{if(a.sum!=b.sum)  return a.sum>b.sum;      //先按照总分排序 if(a.zy!=b.zy)       return a.zy>b.zy;        //总分相同,按智育排序 if(a.dy!=b.dy)     return a.dy>b.dy;        //智育相同,按德育排序 return a.wy>b.wy;        //德育相同,按武育排序
}
int main()
{int t,n;double b,c,d;while(cin >> t){for(int i=0;i<t;i++){cin >> n >> b >> c >> d;for(int j=0;j<n;j++){cin >> a[j].name >> a[j].zy >> a[j].dy >> a[j].wy;a[j].num=i+1;a[j].zy*=c/100;a[j].dy*=b/100;a[j].wy*=d/100; //计算折合过的分数a[j].sum=a[j].zy+a[j].dy+a[j].wy;              //计算总分}sort(a,a+n,cmp);printf("Case #%d:\n",a[i].num);for(int j=0;j<n;j++)printf("%s %.4f %.4f %.4f %.4f\n",a[j].name,a[j].sum,a[j].zy,a[j].dy,a[j].wy);}}return 0;
}

这题有一个坑,加权的比率不是a%,b%,c%,而是b%,a%,c%,导致我第一次直接WA。

nefu 874 相约摩洛哥

Description
2015年5月ACM全球总决赛在摩洛哥卡萨布兰卡举行,到时会有来自世界各地的acm大牛齐聚摩洛哥。
作为本次大赛的举办方负责人阿焜和阿祥被分配给了一个重要的任务,就是在比赛中统计大家的排名。
acm大赛排名规则(摘自百度百科):
最后的获胜者为正确解答题目最多且总用时最少的队伍。每道试题用时将从竞赛开始到试题解答被判定为正确为止,其间每一次提交运行结果被判错误的话将被加罚20分钟时间,未正确解答的试题不记时。例如:A、B两队都正确完成两道题目,其中A队提交这两题的时间分别是比赛开始后1:00和2:45,B队为1:20和2:00,但B队有一题提交了2次。这样A队的总用时为1:00+2:45=3:45而B队为1:20+2:00+0:20=3:40,所以B队以总用时少而获胜。
请你帮他俩完成这项任务吧!(保证没有成绩完全相同两支队伍)
Input
多组输入,每组一个正整数n(1<=n<=100000),代表有n个队伍参赛。接下来的n行,每行分别有一个字符串(只包含小写英文字母)作为队伍名,长度1<=len<=10;ABC三道题的ac时间(以分钟为单位),时间为-1表示该题没有ac。接下来又有n行,表示每道题的提交次数,用3个正整数表示。
Output
输出排行榜。n行,每行一个队伍的名字、解题数和总用时。
Sample Input
3
team 30 10 20
behappy 20 20 90
newbee 15 16 17
1 1 1
1 1 10
1 1 1
Sample Output
newbee 3 48
team 3 60
behappy 3 310

#include <bits/stdc++.h>
using namespace std;
typedef struct team{char name[10];int a[3],b[3];int time,ac;
}team;
team q[100000];
bool cmp(team a,team b) //先按ac的题目数排序,再按照罚时排序
{if(a.ac==b.ac)   return a.time<b.time;else            return a.ac>b.ac;
}
int main()
{int n;while(cin >> n){for(int i=0;i<n;i++)cin >> q[i].name >> q[i].a[0] >> q[i].a[1] >> q[i].a[2];for(int i=0;i<n;i++)cin >> q[i].b[0] >> q[i].b[1] >> q[i].b[2];for(int i=0;i<n;i++){q[i].time=q[i].ac=0;for(int j=0;j<3;j++){if(q[i].a[j]!=-1){       //题目要求若时间不为-1,则表示这题acq[i].time+=q[i].a[j];q[i].time+=20*(q[i].b[j]-1);q[i].ac++;}}}sort(q,q+n,cmp);for(int i=0;i<n;i++)cout << q[i].name << " " << q[i].ac << " " << q[i].time << endl;}return 0;
}

题目复杂了些,但并不难。

nefu 1297 结构体排序题一

Description
现在给定一组二维平面上面的点的坐标,保证它的坐标是int类型的整数且大于等于0小于等于99.请你按照数据所给要求进行排序.
首先先以横坐标进行排序,若横坐标相同则按纵坐标排序,降序或升序将以0和1的形式表示,0表示降序,1表示升序.
比如,若数据开头给出0 1的要求,则表示先以横坐标降序排列,若横坐标相同则按纵坐标升序排列.
再比如,若数据开头给出1 1的要求,则表示先以横坐标升序排列,若横坐标相同则按纵坐标升序排列.
保证点的数量大于等于3小于等于99
Input
第1行包含三个数字,第一个数字和第二个数字分别表示横坐标和纵坐标的排序要求,0表示降序,1表示升序,第三个数字n表示有几个点需要排序.
余下第2~n+1行每行各有两个类型为n个点的坐标,例如第2行第一个数字表示第一个点横坐标,第二个数字表示第一个点的纵坐标.
Output
输出n行坐标,一行表示一个点,格式如下:
(x0,y0)
Sample Input
0 0 4
1 1
1 2
2 1
2 2
1 1 4
2 2
2 1
1 2
1 1
Sample Output
(2,2)
(2,1)
(1,2)
(1,1)
(1,1)
(1,2)
(2,1)
(2,2)

#include <bits/stdc++.h>
using namespace std;
typedef struct point{int x,y;
}point;
point z[100];
//四个函数均为先按x排序,再按y排序
bool cmp1(point a,point b)  //按照x升序,y升序排序
{if(a.x==b.x) return a.y<b.y;else          return a.x<b.x;
}
bool cmp2(point a,point b)  //按照x升序,y降序排序
{if(a.x==b.x) return a.y>b.y;else          return a.x<b.x;
}
bool cmp3(point a,point b)  //按照x降序,y升序排序
{if(a.x==b.x) return a.y<b.y;else          return a.x>b.x;
}
bool cmp4(point a,point b)  //按照x降序,y降序排序
{if(a.x==b.x) return a.y>b.y;else          return a.x>b.x;
}
int main()
{int a,b,n;while(cin>> a >> b >> n){for(int i=0;i<n;i++)cin >> z[i].x >> z[i].y;if(a==0&&b==0)sort(z,z+n,cmp4);if(a==0&&b==1)sort(z,z+n,cmp3);if(a==1&&b==0)sort(z,z+n,cmp2);if(a==1&&b==1)sort(z,z+n,cmp1);for(int i=0;i<n;i++)printf("(%d,%d)\n",z[i].x,z[i].y);}return 0;
}

大一寒假培训(二)——快排与桶排相关推荐

  1. 大一寒假培训(三)——暴力枚举及妙用

    大一寒假培训(三) 经过两天的培训之后,第三天也到来了.今天讲的是暴力枚举.好像没什么可讲的(悄咪咪地说) 接下来还是今天的练习 nefu 8 二倍的问题 Description 给定2到15个不同的 ...

  2. NEFU 大一寒假培训【一】二维数组、结构体

    主题:二维数组.结构体 A 二维矩阵对角线和 Description 计算m×m的方阵的对角线所有元素的和 Input 输入数据有多组,每组第1行为m (2<=m<=10),接下来有m行m ...

  3. 大一寒假培训(七)——队列与优先队列

    文章目录 队列的定义 队列的基本操作 周末舞会 取纸牌游戏 海港(NOIP2016普及组真题) Blash数集-队列-set 优先队列 优先队列的定义 优先队列的定义方法 用结构体定义优先队列(重载函 ...

  4. 2020大一寒假培训三 (暴力)

    比例简化 Problem:J Time Limit:1000ms Memory Limit:65535K Description 在社交媒体上,经常会看到针对某一个观点同意与否的民意调查以及结果.例如 ...

  5. NEFU 大一寒假训练十二(set)2020.02.18

    Summary 可能是昨天的题少了一些,今天的题多了一堆,还疯狂TLE /(ㄒoㄒ)\~~ Information No. Title AC/Submit A 明明的随机数-set 60/101 B ...

  6. 常用技巧 —— 桶排

    [概述] 桶排的思想是一种比较重要的技巧,在 由于桶排的特殊性,桶排仍需进行模拟装桶的过程,而且有时由于数据范围无法开很大的数组,需要使用 map 与其结合 关于桶排:点击这里 [例题] Romaji ...

  7. 【LeetCode笔记】215. 数组中的第K个最大元素(Java、快排、堆排、并发快排)

    文章目录 题目描述 思路 & 代码 快排 基于 Fork / Join 的并发快排 针对 topK 的快排优化 堆排 基本堆排 结合题目的堆排 二刷 题目描述 大名鼎鼎的TOP K,主要考察排 ...

  8. NEFU 大一寒假训练六(二分查找)题目预测

    说明 预测原理还是基于这篇文章:NEFU OJ 比赛试题预测 (Python) 为防止格式更正导致文章进入待审核状态,所以今天晚上就不修正格式了 如果有格式问题请自行理解,问题产生主要与Markdow ...

  9. [转载]高一语文必修一寒假作业二

    [转载]高一语文必修一寒假作业二 2012年01月15日 高一语文必修一寒假作业二 一.(每小题3分,共15分) 1.下列加黑字读音全部正确的一项是() A.岑(cén)寂 勾(gōu)当 蕴藉(jí ...

最新文章

  1. 小程序云开发数据库在网站读取
  2. Mac安装双系统-win10
  3. 如何排查模组无法识别SIM卡?
  4. Typescript04---模块、命名空间
  5. octave安装 缺java_Octave信号包安装
  6. [集训队作业2018] 三角形(贪心,堆,线段树合并)
  7. LG-Transformer:全局和局部建模Transformer结构新作
  8. sbt笔记二 Running
  9. snipaste如何滚动截图_每天都在用的QQ截图,居然升级了这么多实用功能!
  10. Python获取列表中字符串最长位置处的索引值
  11. opencv读取视频,读取摄像头
  12. 基于FPGA的冗余链路高速切换解决方案
  13. 源码编译Redis Desktop Manager参考
  14. 机器算法基础——回归分析
  15. 实时计算与SparkSteaming的对比
  16. 怎么开发联机小游戏_微信小游戏创意大赛火热进行中,小游戏联机对战引擎免费用...
  17. 速度来看mac电脑怎么彻底关闭系统更新
  18. libsvm for matlab安装与测试
  19. WSL 错误 System has not been booted with systemd as init system (PID 1). Can‘t operate
  20. 使用Bouncy Castle实现RSA加密

热门文章

  1. python lib库_python标准库pathlib常见操作
  2. 番外篇(1)模块次序表、代数环及其检测算法
  3. 【手写】一些情景题 记录
  4. Android平台证件识别系统
  5. Microsoft CMT 系统
  6. qt5.13.2版本安装+qt官网下载地址
  7. 河北大学计算机科学与技术考研,计算机专业考研经验贴(重)
  8. 网络安全通识全解|第12期 《网络安全审查办法》解读
  9. python3基础(廖雪峰)
  10. 瑞利散射 拉曼散射 米散射_使用Cartopy的时移散射图可视化