这几道题是排序的升级版,主要用到的就是Sort函数。只有最后一道题相比较而言比较难一些,其余的都差不多。
P1583 魔法照片
链接:https://www.luogu.org/problemnew/show/P1583
该题就是按照题目的要求进行排序,就是稍微别扭一点。
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
struct Node{
int w,id;
}P[2005];
bool cmp(Node A, Node B){
if(A.w == B.w)return A.id < B.id;
else return A.w > B.w;
}
int E[11];
int main(){
int n, m;
int i;
scanf("%d %d", &n, &m);
for(i = 1; i <= 10; i++)scanf("%d", &E[i]);
for(i = 0; i < n; i++){
scanf("%d",&P[i].w);
P[i].id = i + 1;
}
sort(P, P+n, cmp);
for(i = 0; i < n; i++){
P[i].w += E[i % 10 + 1];
}
sort(P, P+n, cmp);
for(i = 0; i < m;i++){
if(i != 0)printf(" ");
printf("%d", P[i].id);
}
return 0;
}
P1051 谁拿了最多奖学金
链接:https://www.luogu.org/problemnew/show/P1051
题解:本题就是根据奖学金的判断条件,累加在数组里,然后Sort排序就行了。
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct student{
string name;
int money, id;
}stu[105];
int sum;
bool cmp(student A, student B){
if(A.money == B.money)return A.id < B.id;
else return A.money > B.money;
}
int main(){
int n, mark, classes, article;
char cadre, home;
cin>>n;
int i;
long long total = 0;
for(i = 0; i < n; i++){
sum = 0;
cin>>stu[i].name;
scanf("%d %d %c %c %d", &mark, &classes, &cadre, &home, &article );
if(mark > 80 && article > 0)sum += 8000;
if(mark > 85 && classes > 80)sum += 4000;
if(mark > 90) sum += 2000;
if(mark > 85 && home == 'Y' )sum += 1000;
if(classes > 80 && cadre == 'Y')sum += 850;
stu[i].money = sum;
total += sum;
stu[i].id = i + 1;
}
sort(stu, stu + n, cmp);
cout<<stu[0].name<<endl;
cout<<stu[0].money<<endl;
cout<<total<<endl;
total = 0;
return 0;
}
P1093 奖学金
链接:https://www.luogu.org/problemnew/show/P1093
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct Student{
int num, sum, Chinese;
}stu[302];
bool cmp(Student A, Student B){
if(A.sum == B.sum){
if(A.Chinese == B.Chinese)return A.num < B.num;
else return A.Chinese > B.Chinese;
}
else return A.sum > B.sum;
}
int main(){
int math, English, n;
scanf("%d", &n)
int i;
for(i = 0; i < n; i++){
stu[i].sum = 0;
cin>>stu[i].Chinese>>math>>English;
stu[i].sum = stu[i].Chinese + math + English;
stu[i].num = i + 1;
}
sort(stu, stu+n, cmp);
for(i = 0; i < 5; i++){
cout<<stu[i].num <<' '<<stu[i].sum<<endl;
}
return 0;
}
P1309 瑞士轮
链接:https://www.luogu.org/problemnew/show/P1309
题解:本题最开始我利用多次排序每次,然后第一名和第二名比赛,第三名和第四名比赛。。。赢的成绩加一,在排序,按照之前的方法,一共执行R次,但是只能通过60%,所以需要跟换思路。用到了归并排序,把输的和赢的分成两组,然后在合并。这就是归并的思想。
不能通过的样例:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct Person{
int s, w, id;
}P[200002];
bool cmp(Person A, Person B){
if(A.s == B.s){
return A.id < B.id;
}
else return A.s > B.s;
}
int main(){
int N, R, Q, i;
scanf("%d %d %d", &N, &R, &Q);
for(i = 1; i <= N * 2; i++){
scanf("%d", &P[i].s);
P[i].id = i;
}
for(i = 1; i <= N * 2; i++){
scanf("%d", &P[i].w);
}
while(R--){
sort(P + 1, P+ N*2 + 1, cmp);
for(i = 1; i <= N*2 - 1; i += 2){
if(P[i].w > P[i + 1].w)P[i].s += 1;
else P[i+1].s += 1;
}
}
sort(P+1, P + N*2 +1, cmp);
printf("%d\n", P[Q].id);
return 0;
}
通过的样例:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct Person{
int s, w, id;
}P[200002],Win[100002], Lose[100002];
bool cmp(Person A, Person B){
if(A.s == B.s){
return A.id < B.id;
}
else return A.s > B.s;
}
int main(){
int N, R, Q, i;
scanf("%d %d %d", &N, &R, &Q);
for(i = 1; i <= N * 2; i++){
scanf("%d", &P[i].s);
P[i].id = i;
}
for(i = 1; i <= N * 2; i++){
scanf("%d", &P[i].w);
}
sort(P+1, P + N * 2 + 1, cmp);
while(R--){
int l = 0, y = 0;
for(i = 1; i <= 2 * N; i += 2){
if(P[i].w > P[i + 1].w){
Win[++y] = P[i];
Win[y].s++;
Lose[++l] = P[i + 1];
}
else {
Win[++y] = P[i + 1];
Win[y].s++;
Lose[++l] = P[i];
}
}
merge(Win+1, Win + y + 1, Lose + 1, Lose + l + 1, P + 1, cmp);
}
printf("%d\n", P[Q].id);
return 0;
}