2015年nefu寒假集訓結構體排序專題解題報告

life4711發表於2015-01-29


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;
}

雖然題目對大家來說並不都是很容易,但相信經過一番冥思苦想後的豁然開朗,是做多少道水題都無法相比的。也祝大家在接下來的訓練中取得好成績!

相關文章