1. 程式人生 > 其它 >TheZealous的賽前水題日常之 洛谷 P1068 [NOIP2009 普及組] 分數線劃定(排序+模擬)

TheZealous的賽前水題日常之 洛谷 P1068 [NOIP2009 普及組] 分數線劃定(排序+模擬)

【題目】

戳這裡

【審題】

1.取前floor(m*1.50)個最大的之後還要帶上與第floor(m*1.50)個分數相同的元素

2.相同成績,id小的靠前

【分析】

1.對成績和編號進行排序,成績按逆序排序

2.排序後第floor(m*1.50)個人的成績一定是基準線

3.從第floor(m*1.50)+1個人開始列舉,找出與第floor(m*1.50)個人成績相同的人數sum

4.輸出前sum+floor(m*1.50)個人的成績

【程式碼實現】

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,m;
 4 struct
stu 5 { 6 int id,gra; 7 }a[10005]; 8 bool cmp(stu a,stu b) 9 { 10 if(a.gra==b.gra) return a.id<b.id; 11 else return a.gra>b.gra; 12 } 13 int main() 14 { 15 scanf("%d %d",&n,&m); 16 m=(int)m*1.5; 17 for(int i=1;i<=n;i++) 18 { 19 scanf("%d%d",&a[i].id,&a[i].gra);
20 } 21 sort(a+1,a+1+n,cmp); 22 int sum=0; 23 printf("%d ",a[m].gra); 24 for(int i=m+1;i<=n;i++) 25 { 26 if(a[i].gra==a[m].gra) sum++;//這裡之前寫的計數方式問題很大,還是經yinz提點才明白沒有必要每次和前一個元素比較,基準值直接設為a[m].gra即可 27 else break; 28 } 29 printf("%d\n",sum+m); 30 for
(int i=1;i<=sum+m;i++) 31 { 32 printf("%d %d\n",a[i].id,a[i].gra); 33 } 34 return 0; 35 }