SUST ACM Summer Training(1)

SUST ACM Summer Training(1)_第1张图片
Cover

SUST ACM Summer Training(陕西科技大学 暑期ACM训练)

10道结构体和排序类型问题

题解

HDU 1029 Ignatius and the Princess IV

题目描述

求给出测试序列中,出现次数至少为(n+1)/2的数字

思路

把序列排序一遍出现次数为(n+1)/2次的数字必定在数据列的中间

#include
#include
#include
#define Len 1000100
using namespace std;
int n,a[Len];
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        memset(a,0,sizeof(a));
        for(int i = 0; i < n; i++)
            scanf("%d",&a[i]);
        sort(a,a+n);
        printf("%d\n",a[(n+1)/2]);
    }
    return 0;
}

HDU 1040 As Easy As A+B

题目描述

给出测试序列,按升序输出序列

思路

直接sort()即可

#include
#include
using namespace std;
int t,n,a[1010];
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i = 0; i < n; i++)
            scanf("%d",&a[i]);
        sort(a,a+n);
        printf("%d",a[0]);
        for(int i = 1; i < n ; i++)
            printf(" %d",a[i]);
        printf("\n");
    }
    return 0;
}

HDU 1106 排序

题目描述

给出一个数字字符串,以5为分割,把每个数排序后输出,注意00表示0,01表示1

思路

为了避免00这种情况,从后往前判断,遇到5跳过否则依次转换成整形数存进数组,最后排序输出。

#include
#include
#include
#include
using namespace std;
char s[1010];
int l,x,i,j,a[1010];
int main()
{
    while(scanf("%s",s)!=EOF)
    {
        memset(a,0,sizeof(a));
        l = strlen(s);
        x = 0;
        for(i = l-1, j = 0; i >= 0; i--)
        {
            if(s[i] == '5')
                continue;
            else
            {
                while(s[i] != '5')
                {
                    if(i == -1)
                        break;
                    a[j] += pow(10,x++) * (s[i--] - '0');
                }
                j++;
                x = 0;
            }
        }
        sort(a,a+j);
        printf("%d",a[0]);
        for(i = 1; i < j; i++)
            printf(" %d",a[i]);
        printf("\n");
    }
    return 0;
}

HDU 1209 Clock

题目描述

给出5个时刻,让你计算每个时刻的时针与分针的夹角,然后按夹角从小到大排序,如果角度相同,则按时间先后顺序排序,最后输出中间的时刻

思路

简单的换算题,时针每小时转30°,每分钟转0.5°,分针每分钟转6°,所以可以推导出换算公式。最后两个针的角度相减算出绝对值角度,如果大于180°的话,再用360°减去。

#include
#include
#include
using namespace std;
struct tt
{
    double angle;
    int h;
    int m;
}t[6];
int T,n;
bool cmp(tt x,tt y)
{
    if(x.angle == y.angle)
        return x.h < y.h;
    return x.angle < y.angle;
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        for(int i = 0; i < 5; i++)
        {
            scanf("%d:%d",&t[i].h,&t[i].m);
            t[i].angle = (t[i].h > 12) ? abs( (t[i].h - 12) * 30 + 0.5 * t[i].m - t[i].m * 6) : abs( t[i].h * 30 + 0.5 * t[i].m - t[i].m * 6);
            t[i].angle = (t[i].angle > 180) ? 360 - t[i].angle : t[i].angle;
        }
        sort(t,t+5,cmp);
        printf("%02d:%02d\n",t[2].h,t[2].m);
    }
    return 0;
}

HDU 1236 排名

题目描述

先给出每道题的总分,依次给出每个学生的学号、通过的题目数量、每道题的得分。
让你根据成绩进行排序,如果成绩一样,则按照学号进行排序

思路

结构体保存学生的信息,然后排序,特别注意一点就是学号要按照字典序排序

#include
#include
#include
using namespace std;
struct stu
{
    char name[22];
    int num;
    int score;
}s[1100];
int n,m,g,x,c,score[11];
bool cmp(stu x,stu y)
{
    if(x.score == y.score)
        return strcmp(x.name,y.name) > 0 ? 0 : 1;
    return x.score > y.score;
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        if(n == 0)
            break;
        scanf("%d%d",&m,&g);
        c = 0;
        memset(s,0,sizeof(s));
        for(int i = 1; i <= m; i++)
            scanf("%d",&score[i]);
        for(int i  = 1; i <= n; i++)
        {
            scanf("%s %d",s[i].name,&s[i].num);
            for(int j = 1; j <= s[i].num; j++)
            {
                scanf("%d",&x);
                s[i].score += score[x];
            }
            if(s[i].score >= g)
                c++;
        }
        sort(s+1,s+n+1,cmp);
        printf("%d\n",c);
        for(int i = 1; i <= n; i++)
            if(s[i].score >= g)
                printf("%s %d\n",s[i].name,s[i].score);
            else
                break;
    }
    return 0;
}

HDU 1280 前m大的数

题目描述

给出序列,把它们两两相加到前N*(N-1)/2,然后降序输出前N项

思路

暴力求解,用新数组保存两两相加的值,然后降序排序,遍历输出前N项

#include
#include
using namespace std;
int n,m,i,j,k,a[3010],b[5000100];
bool cmp(int x,int y)
{
    return x > y;
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i = 0; i < n; i++)
            scanf("%d",&a[i]);
        for(i = 0,k = 0; i < n; i++)
        {
            for(j = i + 1; j < n; j++)
                b[k++] = a[i] + a[j];
                      
        }
        sort(b,b+k,cmp);
        printf("%d",b[0]);
        for(int i = 1; i < m; i++)
            printf(" %d",b[i]);
        printf("\n");
    }
    return 0;
}

HDU 1379 DNA Sorting

题目描述

给出字符串,按照逆字典序算出每个字符的逆字典序的个数的和,然后按照每个序列逆字典序个数总和进行排序输出

思路

用结构体保存字符串和逆字典序个数和,最后排序输出

#include
#include
#include
using namespace std;
struct DNA
{
    char s[55];
    int num;
}str[110];
int T,l,n;
bool cmp(DNA x,DNA y)
{
    return x.num < y.num;
}
int main()
{
    scanf("%d",&T);
    getchar();
    while(T--)
    {
        scanf("%d%d",&l,&n);
        getchar();
        for(int i = 0; i < n; i++)
        {
            scanf("%s",str[i].s);
            str[i].num = 0;
            for(int j = 0; j < l; j++)
                for(int k = j + 1; k < l; k++)
                    if(str[i].s[j] > str[i].s[k])
                        str[i].num++;
        }
        sort(str,str+n,cmp);
        for(int i = 0; i < n; i++)
            printf("%s\n",str[i].s);
        if(T)
            printf("\n");
    }
    return 0;
}

HDU 1391 Number Steps

SUST ACM Summer Training(1)_第2张图片
pic

题目描述

让你根据图的规律计算给出的坐标是否存在

思路

找规律,打表保存每一个存在的点,根据输入直接输出结果

#include
#include
using namespace std;
int t,x,y,map[5010][5010]={0};
int main()
{
    for(int i = 0; i <= 5000; i++)
        if(i % 2 == 0)
            map[i][i] = i + i;
        else
            map[i][i] = i + i - 1;
    for(int i = 2, j = 0; i <= 5000; i++)
    {
        if(i % 2 == 0)
            map[i][j] = i + j;
        else
            map[i][j] = i + j - 1;
        j++;
    }
        
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d %d",&x,&y);
        if(map[x][y])
            printf("%d\n",map[x][y]);
        else
            printf("No Number\n");
    }
    return 0;
}

HDU 2673 shǎ崽 OrOrOrOrz

题目描述

给出序列,按照最大最小第二大,第二小的顺序把序列输出

思路

排序,逆序输出时候按照下标变化输出相应结果

#include
#include
using namespace std;
int n,a[10010];
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        for(int i = 0; i < n; i++)
            scanf("%d",&a[i]);
        sort(a,a+n);
        //printf("%d",a[n-1]);
        for(int i = n - 1; i >= n/2; i--)
        {
            if(i == n - 1)
                printf("%d",a[i]);
            else
                printf(" %d",a[i]);
            if(i == n/2 && n%2)
                break;
            printf(" %d",a[n - i - 1]);
        }
        printf("\n");
    }
    return 0;
}

HDU 5884 Sort

Attempted

题解后面补上

你可能感兴趣的:(SUST ACM Summer Training(1))