林大 OJ(24.2)

目录

1.谁考了第k名-排序

!!输出%g和数据类型的长度

2.基数排序

3.小数排成绩

4.n个0或1求前k个数大小

5.前k个大的数的和(没必要排序)

6.老和尚多个成绩排名次

7.小和尚找奖学金和补考

8.刘备排加权名次

!!cout输出控制精度

9.做题时长

10.坐标按xy排序


1.谁考了第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

!!输出%g和数据类型的长度

分析:%g用于打印浮点型数据时,会去掉多余的零,至多保留六位有效数字(不同于%e的默认保留小数点后6位)

short

所占字节数:2  
位数:16        
最小值:-32768          
最大值:32767
int

所占字节数:4  
位数:32        
最小值:-2147483648    
最大值:2147483647
unsigned int

所占字节数:4  
位数:32        
最小值:0              
最大值:4294967295
long

所占字节数:4  
位数:32        
最小值:-2147483648    
最大值:2147483647
unsigned long

所占字节数:4  
位数:32        
最小值:0              
最大值:4294967295
 

float

所占字节数:4  
位数:32        
最小值:1.17549e-38    
最大值:3.40282e+38
double

所占字节数:8  
位数:64        
最小值:2.22507e-308    
最大值:1.79769e+308

https://blog.csdn.net/mars_xiaolei/article/details/100536467
 

#include <bits/stdc++.h>

using namespace std;

typedef struct stu
{
    int id;
    double cg;

};

bool cmp(const stu &s1, const stu &s2)
{
    return s1.cg < s2.cg;
}



main()
{
    int n,k;
    cin>>n>>k;
    struct stu stu[n];
    int i;
    for(i=0; i<n; i++)
    {
        cin>>stu[i].id;
        cin>>stu[i].cg;
    }
//     for(i=0;i<n;i++)
//    {
//        cout<<stu[i].id<<" ";
//        cout<<stu[i].cg<<endl;
//    }
    sort(stu,stu+n,cmp);
//         for(i=0;i<n;i++)
//    {
//        cout<<stu[i].id<<" ";
//        cout<<stu[i].cg<<endl;
//    }
//
//    cout<<"**************";
    cout<<stu[k-1].id<<" "<<stu[k-1].cg;
}

2.基数排序

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
分析:要注意count的范围,是先放入数组之后++,循环时要记录的是i<count

#include <bits/stdc++.h>

using namespace std;

main()
{
    int x,i,n;
    cin>>n;
    int a[n];
    int count=0;
    for(i=0;i<n;i++)
    {
        cin>>x;
        if(x%2==1)
        {
            a[count]=x;
            count++;
        }
    }
     for(i=0;i<count;i++)
    {
       cout << a[i] <<",";
    }
}

3.小数排成绩

Description
期末考试结束,要给各门课程按成绩进行排序,进行奖学金评定。
给你本学期各门课程成绩,编写排序函数将每门课程成绩排序(从大到小)输出!
Input
输入数据有很多行,每行10个数。
Output
将每行数从大到小输出,保留2位小数。
Sample Input
16 20 34 43 54 65 72 85.5 96 98.5
Sample Output
98.50 96.00 85.50 72.00 65.00 54.00 43.00 34.00 20.00 16.00

分析:scanf中,%lf的数据类型是double,%f的数据类型是float

           sort的形式是sort(start,end+1,greater<>()),less的可以不写

           在while中cin>>a[i]最开始的时候报错了,到后来又没有报错了,有点奇怪,没有找到为什么

#include <bits/stdc++.h>

using namespace std;


main()
{
    double x;
    double a[11];
    int i;

    //while(scanf("%lf",&x)!=EOF)
    while(cin>>a[0])
    {
        //a[0]=x;
        for(i=1; i<=9; i++)
        {
//            cin>>x;
//            a[i]=x;
              cin>>a[i];

        }
        for(i=0; i<=9; i++)
        {
            cout<<a[i]<<" ";
        }
        cout<<endl;
        sort(a,a+10,greater<double>());
        for(i=0; i<=9; i++)
        {
//         cout<<a[i]<<" ";
            printf("%.2f",a[i]);
            cout<<" ";
        }




    }
}

4.n个0或1求前k个数大小

羽裳有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

分析:数有几个1,在k和1的个数之间取最小值即可


#include <bits/stdc++.h>

using namespace std;

main()
{
    int count=0,n,k;
    cin>>n>>k;
    int i,x;
    for(i=0;i<n;i++)
    {
        cin>>x;
        if(x==1) count++;

    }
    count=count<k?count:k;
    cout<<count;
}

5.前k个大的数的和(没必要排序)

羽裳有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
分析:本来想用选择排序排最大的k个,后来看到提示说没必要排序才想到直接用循环找到前k个数就好,确实没必要排序,但是最后发现还是要用到选择排序的

      在这次题目中用到了swap函数,swap(a,b)就可以直接换了

      还有想用max函数,但是发现复杂的都差不多就没用max(a,b)

#include <bits/stdc++.h>

using namespace std;

main()
{
    int n,k,i,j,sum,smax,x;
    cin>>n>>k;
    int a[n];
    smax=-1;
    sum=0;
    for(i=0; i<n; i++)
    {
        cin>>a[i];
    }
    for(j=0; j<k; j++)
    {
        for(i=0; i<n-j; i++)
        {
            if(a[i]>smax)
            {
                smax=a[i];
                x=i;
            }

        }
        sum+=smax;
        swap(a[x],a[n-j]);
        smax=-1;


    }
    cout<<sum;

}

6.老和尚多个成绩排名次


Problem:F
Time Limit:1000ms
Memory Limit:65536K
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
分析:最开始用的cmp运行的时间很长,于是去看了下答案,发现我的cmp有点太冗余了,一直在if和else,而答案里面直接用几行else if就解决了

#include <bits/stdc++.h>

using namespace std;

typedef struct stu
{
    int id;
    int a,b,c,d;
    int sum;
};


//bool cmp(const stu &s1,const stu &s2)
//{
//  if(s1.sum==s2.sum)
//  {
//      if(s1.a==s2.a)
//      {
//          if(s1.b==s2.b)
//          {
//              if(s1.c==s2.c)
//              {
//                  return s1.d>s2.d;
//              }
//              else return s1.c>s2.c;
//          }
//          else return s1.b>s2.b;
//      }
//      else return s1.a>s2.a;
//  }
//
//  else return s1.sum>s2.sum;
//}

bool cmp(const stu &s1,const stu &s2)
{
    if(s1.sum!=s2.sum) return s1.sum>s2.sum;
    else if(s1.a!=s2.a) return s1.a>s2.a;
    else if(s1.b!=s2.b) return s1.b>s2.b;
    else if(s1.c!=s2.c) return s1.c>s2.c;
    else return s1.d>s2.d;
}


main()
{
   int  n;
   cin>>n;
   struct stu stu[n];
   int i;
   for(i=0;i<n;i++)
   {
       stu[i].id=i+1;
       cin>>stu[i].a>>stu[i].b>>stu[i].c>>stu[i].d;
       stu[i].sum=stu[i].a+stu[i].b+stu[i].c+stu[i].d;

   }
   sort(stu,stu+n,cmp);
    for(i=0;i<n;i++)
   {
       cout<<stu[i].id<<" "<<stu[i].sum<<endl;

   }

}

7.小和尚找奖学金和补考

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

分析:按结构体把人数按成绩排序好(由于要求输出的是按从低到高,所以从小到大排序),因为能拿到奖学金的人一定不用补考,所以只要输出前m个和后n个的名字

#include <bits/stdc++.h>

using namespace std;

typedef struct stu
{
    string name;
    int grade;
};


bool cmp(const stu &s1,const stu &s2)
{
    return s1.grade<s2.grade;
}


main()
{
    int n,m,o;
    cin>>n>>m>>o;
    struct stu stu[n];
    int i;
    for(i=0;i<n;i++)
    {
        cin>>stu[i].name>>stu[i].grade;
    }
    sort(stu,stu+n,cmp);
    for(i=n-m;i<n;i++)
    {
        cout<<stu[i].name<<endl;
    }
    for(i=0;i<o;i++)
    {
        cout<<stu[i].name<<endl;
    }
}

8.刘备排加权名次

东汉末年,宦官当权,民不聊生。灵帝中平元年,张角兄弟发动黄巾起义,官军闻风丧胆。
为抵抗黄巾,幽州太守刘焉出榜招兵。榜文前,刘备、关羽、张飞三兄弟萍水相逢。
三人都有为国效力之心,于是桃园结为异姓兄弟,开始了一段三国浪漫传奇……
如果我问你三国中谁最聪明你一定会说是诸葛亮,我要问你谁武功最高,保不准你就要说关羽。
是啊,我们的刘备对于优秀的手下向来十分满意。
可是有一天,刘备在无意间在朋友圈里看到了梁山的宋江正在进行英雄排座次,最可气的是这条动态已经被转发评论了无数次了……
这一下可气坏了刘备,他决定也来一次,蜀中文武百官大排名。
为了公平起见,诸葛亮帮他制定一条评分标准:
每个官员有一个智育、德育、武育三个分数,分别以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

!!cout输出控制精度


分析:题目很简单,在输出的时候出了一点点问题,用cout输出的时候控制输出位数用的是setprecision(),但是一直输出的是整数,最后在网上查了一下才发现是setprecision控制的是全部的数值,0省略了,所以小数点后的0要加上fixed

#include <bits/stdc++.h>

using namespace std;



typedef struct stu
{
    string name;
    double a,b,c,sum;
};

bool cmp(const stu &s1,const stu &s2)
{
    if(s1.sum!=s2.sum) return s1.sum>s2.sum;
    else if(s1.a!=s1.a) return s1.a>s2.a;
    else if(s1.b!=s1.b) return s1.b>s2.b;
    else s1.c>s2.c;
}

main()
{
    int n;
    double a1,b1,c1;
    int t;
    cin>>t;
    int count=0;
    while(t--)
    {
       count++;
       cin>>n>>a1>>b1>>c1;
       struct stu stu[n];
       int i;
       for(i=0;i<n;i++)
       {
           cin>>stu[i].name>>stu[i].a>>stu[i].b>>stu[i].c;
           stu[i].a=stu[i].a*a1/100*1.0;
           stu[i].b=stu[i].b*b1/100*1.0;
           stu[i].c=stu[i].c*c1/100*1.0;
           stu[i].sum=stu[i].a+stu[i].b+stu[i].c;


       }
       for(i=0;i<n;i++)
       {
           cout<<fixed<<setprecision(4)<<stu[i].name<<" "<<stu[i].sum<<" "
           <<stu[i].a<<" "<<stu[i].b<<" "<<stu[i].c<<endl;
       }
       cout<<"-----------------------------";
       sort(stu,stu+n,cmp);
       cout<<"Case #"<<count<<":"<<endl;
       for(i=0;i<n;i++)
       {
           cout<<setprecision(4)<<stu[i].name<<" "<<stu[i].sum<<" "
           <<stu[i].a<<" "<<stu[i].b<<" "<<stu[i].c<<endl;
       }

    }


}

9.做题时长

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

分析:由于时间是用分钟来表示,而且根据样例输出来看可以不用时间转换,那么只需要单独处理-1即可

注意!!比赛的排行榜时间越少越好

#include <bits/stdc++.h>

using namespace std;

typedef struct stu
{
    string name;
    int a,b,c;
    int x,y,z;
    int sum,count;
};


bool cmp(const stu &s1,const stu &s2)
{
   return s1.sum<s2.sum;
}


main()
{
    int n;
    cin>>n;
    struct stu stu[n];
    int i;
     for(i=0;i<n;i++)
    {
       stu[i].count=3;

    }
        for(i=0;i<n;i++)
    {
        cin>>stu[i].name>>stu[i].a>>stu[i].b>>stu[i].c;
        if(stu[i].a==-1){stu[i].a++;stu[i].count--;}
        if(stu[i].b==-1) {stu[i].b++;stu[i].count--;}
        if(stu[i].c==-1) {stu[i].c++;stu[i].count--;}
        stu[i].sum=stu[i].a+stu[i].b+stu[i].c;
    }
    for(i=0;i<n;i++)
    {
        cin>>stu[i].x>>stu[i].y>>stu[i].z;
        stu[i].sum+=(stu[i].x+stu[i].y+stu[i].z-3)*20;

    }
    sort(stu,stu+n,cmp);
     for(i=0;i<n;i++)
    {
        cout<<stu[i].name<<" "<<stu[i].count<<" "<<stu[i].sum<<endl;

    }





}

10.坐标按xy排序

现在给定一组二维平面上面的点的坐标,保证它的坐标是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)

分析:分四种排序的可能,按照xy排序即可

#include <bits/stdc++.h>

using namespace std;

typedef struct s
{
    int x,y;
};

bool cmp1(const s &s1,const s &s2)
{
    if(s1.x!=s2.x) return s1.x>s2.x;
    else s1.y>s2.y;
}
bool cmp2(const s &s1,const s &s2)
{
    if(s1.x!=s2.x) return s1.x>s2.x;
    else s1.y<s2.y;
}
bool cmp3(const s &s1,const s &s2)
{
    if(s1.x!=s2.x) return s1.x<s2.x;
    else s1.y<s2.y;
}
bool cmp4(const s &s1,const s &s2)
{
    if(s1.x!=s2.x) return s1.x<s2.x;
    else s1.y>s2.y;
}
main()
{
    int i;
    int a,b,n;
    while(cin>>a>>b>>n)
    {
        struct s s[n];
        for(i=0;i<n;i++)
        {
            cin>>s[i].x>>s[i].y;
        }
        if(a==0&&b==0) sort(s,s+n,cmp1);
        else if(a==0&&b==1) sort(s,s+n,cmp2);
        else if(a==1&&b==0) sort(s,s+n,cmp3);
        else  sort(s,s+n,cmp4);
        for(i=0;i<n;i++)
        {
            cout<<"("<<s[i].x<<","<<s[i].y<<")"<<endl;
        }
    }
}

  • 29
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值