ACM-NEFU新生訓練2-排序和CMP
阿新 • • 發佈:2020-12-22
A.誰考了第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; struct student { int num; double grade; }s[100]; int cmp(student s1,student s2) { return s1.grade>s2.grade; } int main() { int n,k; cin>>n>>k; for(int i=0;i<n;i++) { cin>>s[i].num>>s[i].grade; } sort(s,s+n,cmp); printf("%d %g",s[k-1].num,s[k-1].grade); return 0; }
B.奇數單增序列
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 main() { int n,num[500],flag=1; cin>>n; for(int i=0;i<n;i++) { cin>>num[i]; } sort(num,num+n); for(int i=0;i<n;i++) { if(num[i]%2) { if(!flag)printf(","); printf("%d",num[i]); flag=0; } } return 0; }
C.成績排序
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;
struct student
{
char name[30];
int grade;
}a[50];
int cmp(student s1,student s2)
{
if(s1.grade!=s2.grade) return s1.grade>s2.grade;
else return strcmp(s1.name,s2.name)<0;
}
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i].name>>a[i].grade;
}
sort(a,a+n,cmp);
for(int i=0;i<n;i++)
{
cout<<a[i].name<<" "<<a[i].grade<<endl;
}
return 0;
}
D.沒必要的排序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
Code
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,k,cnt=0,tmp;
while(cin>>n>>k)
{
cnt=0;
for(int i=0;i<n;i++)
{
cin>>tmp;
if(tmp)cnt++;
}
if(cnt<k)cout<<cnt<<endl;
else cout<<k<<endl;
}
return 0;
}
E.沒必要的排序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
Hint
排序會超時
思路
hint都有了,必然桶排序
Code
#include <bits/stdc++.h>
using namespace std;
int a[100010];
typedef long long ll;
int main()
{
memset(a,0,sizeof(a));
int n,k,tmp;
ll ans=0;
scanf("%d %d",&n,&k);
for(int i=0;i<n;i++)
{
scanf("%d",&tmp);
a[tmp]++;
}
tmp=ans=0;
for(int i=100000;i>=1;i--)
{
for(int j=a[i];j>0;j--)
{
ans+=i;
k--;
if(k==0)break;
}
if(k==0)break;
}
cout<<ans<<endl;
return 0;
}
F.老和尚的導員
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
Code
#include <bits/stdc++.h>
using namespace std;
struct score
{
int num;
int c;
int xxds;
int gdsx;
int yy;
int sum;
}p[100];
int cmp(score h1, score h2)
{
if(h1.sum!=h2.sum)return h1.sum>h2.sum;
if(h1.c != h2.c)return h1.c > h2.c;
if(h1.xxds!=h2.xxds)return h1.xxds>h2.xxds;
if(h1.gdsx!=h2.gdsx)return h1.gdsx>h2.gdsx;
if(h1.yy!=h2.yy)return h1.yy>h2.yy;
}
int main()
{
int n;
while(cin>>n)
{
for(int i=0;i<n;i++)
{
p[i].num=i+1;
cin >> p[i].c >> p[i].xxds >> p[i].gdsx >> p[i].yy;
p[i].sum= p[i].c + p[i].xxds + p[i].gdsx + p[i].yy;
}
sort(p,p+n,cmp);
for(int i=0;i<n;i++)
{
cout<<p[i].num<<" "<<p[i].sum<<endl;
}
}
return 0;
}
G.健忘的老和尚
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
Code
#include <bits/stdc++.h>
using namespace std;
struct score
{
int grade;
char name[110];
}p[10000];
int cmp(score h1, score h2)
{
return h1.grade>h2.grade;
}
int main()
{
int n,m,o;
while(cin>>n>>m>>o)
{
for(int i=0;i<n;i++)
{
getchar();
cin>>p[i].name>>p[i].grade;
}
sort(p,p+n,cmp);
for(int i=m-1;i>=0;i--)
{
cout<<p[i].name<<endl;
}
for(int i=n-1;i>=n-o;i--)
{
cout<<p[i].name<<endl;
}
}
return 0;
}
H.戲說三國
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
Code
#include <bits/stdc++.h>
using namespace std;
struct haohan
{
double sum;
double zy;
double dy;
double wy;
char name[21];
}p[1010];
int cmp(haohan p1, haohan p2)
{
return p1.sum>p2.sum;
}
int main()
{
int t,n;
double a,b,c;
cin>>t;
for(int i=0;i<t;i++)
{
cin>>n>>a>>b>>c;
for(int j=0;j<n;j++)
{
cin>>p[j].name>>p[j].zy>>p[j].dy>>p[j].wy;
p[j].zy*=b/100;
p[j].dy*=a/100;
p[j].wy*=c/100;
p[j].sum=p[j].zy+p[j].dy+p[j].wy;
}
sort(p,p+n,cmp);
printf("Case #%d:\n",i+1);
for(int j=0;j<n;j++)
{
printf("%s %.4lf %.4lf %.4lf %.4lf\n",p[j].name,p[j].sum,p[j].zy,p[j].dy,p[j].wy);
}
}
return 0;
}
I.相約摩洛哥
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
Code
#include <bits/stdc++.h>
using namespace std;
struct team
{
char name[11];
int ta,tb,tc;
int actime;
int num;
}t[100010];
int cmp(team t1,team t2)
{
if(t1.num!=t2.num)return t1.num>t2.num;
return t1.actime < t2.actime;
}
int main()
{
int n,a,b,c;
while(cin>>n)
{
for(int i=0;i<n;i++)
{
cin>>t[i].name>>t[i].ta>>t[i].tb>>t[i].tc;
}
for(int i=0;i<n;i++)
{
cin>>a>>b>>c;
t[i].actime=0;
t[i].num=0;
if(t[i].ta!=-1)
{
t[i].ta+=20*(a-1);
t[i].num++;
t[i].actime+=t[i].ta;
}
if(t[i].tb!=-1)
{
t[i].tb+=20*(b-1);
t[i].num++;
t[i].actime+=t[i].tb;
}
if(t[i].tc!=-1)
{
t[i].tc+=20*(c-1);
t[i].num++;
t[i].actime+=t[i].tc;
}
}
sort(t,t+n,cmp);
for(int i=0;i<n;i++)
{
cout << t[i].name << " " << t[i].num << " " << t[i].actime << endl;
}
}
return 0;
}
J.結構體排序題一
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)
Code
#include<bits/stdc++.h>
using namespace std;
struct node
{
int x;
int y;
}a[110];
int rey,rex;
int cmp(node t1,node t2)
{
if(rex)
{
if(t1.x!=t2.x) return t1.x<t2.x;
if(rey) return t1.y<t2.y;
else return t1.y>t2.y;
}
else
{
if(t1.x!=t2.x) return t1.x>t2.x;
if(rey) return t1.y<t2.y;
else return t1.y>t2.y;
}
}
int main()
{
int n;
while(cin>>rex>>rey>>n)
{
for(int i=0;i<n;i++)
{
cin>>a[i].x>>a[i].y;
}
sort(a,a+n,cmp);
for(int i=0;i<n;i++)
{
printf("(%d,%d)\n",a[i].x,a[i].y);
}
}
return 0;
}
K.最強編碼同學票數統計
Description
為了找出林大2020新生中最擅長編寫程式碼的同學,學校發起了一場投票。通過同學報名、前期遴選等環節,共提名了100名同學作為選舉人進行評選,假設他們的編號從1到100。現在學院已經採集到了n名同學的投票結果,請你找出得票最多的程式設計師獲得的票數(注:就是讓你找相同數字的個數的最大值)。
Input
輸入:
第一行一個數n(1≤n≤100) , 代表有多少位同學投票。
第二行n個數:a1,a2⋯an, ai(1≤ai≤100)代表第i位同學投票所選的林大最擅長編碼的那個程式設計師的編號。輸入資料有多組!
Output
輸出:
每組資料的輸出佔一行 , 輸出得票最多的那個同學獲得的票數(相同編號的個數的最大值)。
Sample Input
輸入樣例1:
6
1 2 4 7 7 7
4
5 5 5 5
Sample Output
輸出樣例1:
3
4
Code
#include<bits/stdc++.h>
using namespace std;
int a[110];
int main()
{
int n;
while(cin>>n)
{
memset(a,0,sizeof(a));
for(int i=1;i<=n;i++)
{
int tmp;
cin>>tmp;
a[tmp]++;
}
int ans=0;
for(int i=1;i<=100;i++)
{
ans=max(ans, a[i]);
}
cout<<ans<<endl;
}
return 0;
}