2015年nefu寒假集训结构体排序专题解题报告


A

排序字符串,利用课件里讲到的sort用法,直接递增排序,然后倒序输出就可以了。

标程如下:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
char a[100005];
int main()
{
    //freopen("data.in","r",stdin);
    //freopen("data.out","w",stdout);
    while(~scanf("%s",a))
    {
        int n=strlen(a);
        sort(a,a+n);
        for(int i=n-1;i>=0;i--)
            printf("%c",a[i]);
        printf("\n");
    }
    return 0;
}


B

这道题有点难度,不知道大家会做成什么样。对于排序的cmp函数我们这样定义:

先是数量优先,然后考虑时间:

在排序的时候要注意,队伍若没有ac这一道题目,那么他提交无论多少次都是不计入罚时的,至于处理大家好好看看标程,我写的还算是比较有脉络的,挺好理解。

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
struct note
{
    int num,x,y,z;
    char s[24];
    int ti;
} a[100005];
bool cmp(note a,note b)
{
    if(a.num!=b.num)
        return a.num>b.num;
    return a.ti<b.ti;
}
int n;
int main()
{
   // freopen("data.in","r",stdin);
  //  freopen("data.out","w",stdout);
    while(~scanf("%d",&n))
    {
        for(int i=0; i<n; i++)
        {
            scanf("%s%d%d%d",a[i].s,&a[i].x,&a[i].y,&a[i].z);
            a[i].num=0;
        }
        for(int i=0; i<n; i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            if(a[i].x!=-1)
            {
                a[i].x+=(x-1)*20;
                a[i].num++;
            }
            else
                a[i].x=0;
            if(a[i].y!=-1)
            {
                a[i].y+=(y-1)*20;
                a[i].num++;
            }
            else
                a[i].y=0;
            if(a[i].z!=-1)
            {
                a[i].z+=(z-1)*20;
                a[i].num++;
            }
            else
                a[i].z=0;
            a[i].ti=a[i].x+a[i].y+a[i].z;
        }
        sort(a,a+n,cmp);
        for(int i=0; i<n; i++)
        {
            printf("%s %d %d\n",a[i].s,a[i].num,a[i].ti);
        }
    }
    return 0;
}


C

这道题没什么难的,不过我任性了一把,给大家挖了个坑,如果不仔细读题很容易上当,题目去掉的是最高分和次低分。看清这一点然后排个序,求下平均数就轻松AC了。

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
int n;
double a[100005];
int main()
{

     //freopen("data.in","r",stdin);
     //freopen("data.out","w",stdout);
    while(~scanf("%d",&n))
    {
        double sum=0.0;
        for(int i=0;i<n;i++)
        {
            scanf("%lf",&a[i]);
            sum+=a[i];
        }
        sort(a,a+n);
        sum=sum-(a[n-1]+a[1]);
        printf("%.4lf\n",sum/(n-2));
    }
    return 0;
}


D

这道题是第二道题的简单版,不过我也给大家留陷阱了,不细心又会WA几次的,题目描述的比例顺序为b a c,而输入顺序是a b c,不知道大家能不能一下子就注意到。看清题后,我们利用sort就可以排一下了,我是这样写的cmp函数:

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;

struct note
{
    char s[25];
    double sum,x,y,z;
}a[100005];
bool cmp(note a,note b)
{
    if(a.sum!=b.sum)
       return a.sum>b.sum;
    if(a.x!=b.x)
        return a.x>b.x;
    if(a.y!=b.y)
        return a.y>b.y;
    return a.z>b.z;
}
int T,n;
double aa,b,c;

int main()
{
    int tt=0;
   // freopen("data.in","r",stdin);
  //  freopen("data.out","w",stdout);
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%lf%lf%lf",&n,&aa,&b,&c);
        aa/=100.0;
        b/=100.0;
        c/=100.0;
        for(int i=0;i<n;i++)
        {
            scanf("%s%lf%lf%lf",a[i].s,&a[i].x,&a[i].y,&a[i].z);
            a[i].x=a[i].x*b;
            a[i].y=a[i].y*aa;
            a[i].z=a[i].z*c;
            a[i].sum=a[i].x+a[i].y+a[i].z;
        }
        sort(a,a+n,cmp);
        printf("Case #%d:\n",++tt);
        for(int i=0;i<n;i++)
        {
            printf("%s %.4lf %.4lf %.4lf %.4lf\n",a[i].s,a[i].sum,a[i].x,a[i].y,a[i].z);
        }
    }
    return 0;
}


E

这是本次比赛中最难的一个题,难点在于把给定的字符串转化成一系列数字,但是问题在于,转化成的数字已经暴了longlong我们只有用字符串来表示数,这道题其实是对利用sort对字符串排序的考查。如果你比赛中没做出来,希望你能好好看看标程,把他弄懂,我的做法是把字符串放在结构体中,再进行结构体排序。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

struct node
{
    char s[110];
}nt[1010];

bool cmp(node a,node b)
{
    int alen=strlen(a.s),blen=strlen(b.s);
    if(alen<blen)
    {
        return true;
    }
    else if(alen>blen)
    {
        return false;
    }
    else
    {
        if(strcmp(a.s,b.s)<0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}
int main()
{
    //freopen("g:\\data.in", "r", stdin);
    //freopen("g:\\data.out", "w", stdout);
    char s[1010],st[110];
    memset(st,0,sizeof(st));
    while(scanf("%s",s)!=EOF)
    {
        int len=strlen(s);
        int k=0,tlen=0;
        for(int i=0;i<=len;i++)
        if(i==len||s[i]=='5')
        {
            if(tlen==0) continue;
            int d=0;
            for(d=0;d<tlen-1;d++)
            if(st[d]!='0')
            {
                break;
            }
            strcpy(nt[k++].s,st+d);
            memset(st,0,sizeof(st));
            tlen=0;
        }
        else
        {
            st[tlen++]=s[i];
        }
        sort(nt,nt+k,cmp);
        printf("%s",nt[0].s);
        for(int i=1;i<k;i++)
        {
            printf(" %s",nt[i].s);
        }
        puts("");
    }
    return 0;
}

虽然题目对大家来说并不都是很容易,但相信经过一番冥思苦想后的豁然开朗,是做多少道水题都无法相比的。也祝大家在接下来的训练中取得好成绩!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值