这个时间段分配的数据结构问题,怎么利用C编程语言的方式解答?采用C语言

Problem Description
Barry Bennett, the coach of the Bings football team, wants to arrange his team for an important match against the Bangs. He decides on the formation he wants to play, for example 4-4-2, meaning that there will be four defenders, four midfielders, and two strikers (and of course, one goalkeeper). Your task is to determine the players who will play. For each available player, we know his role (e.g. midfielder). For each role, the players are selected in ascending order of their numbers. When the players are selected, you must determine the captain too, who is the player with the longest record in the team play. In case two players have the same record, the one with bigger number is chosen. Note that the captain is chosen among the players that are selected in the arrange.

Input
The input consists of multiple test cases. The first 22 lines of each test case contain the data for the 22 available players in this format:

number name role year1–year'1 year2–year'2 ...

number is the player number (unique positive integer less than 100). name is a string of at most 20 letters. role is a single character among G, D, M, S, for goalkeeper, defender, midfielder, and striker respectively. Each yeari –year'i pair (yeari ≤ year'i) shows the player has been a member of the team between the specified years (inclusive). The years are in four-digit format. There is at least one and at most 20 such pairs, and the same year is not repeated more than once in the list. There is a 23rd line describing the desired formation, like 4-4-2 in that format. Note that there are only three numbers in the formation (so, 4-3-2-1 is not valid), none of them is zero, and their sum is always 10. The input is terminated by a line containing a single 0.

Output
For each test case, output a list of 11 players chosen in the arrange. Each line must contain the player number, his name and his role, separated by single blank characters. The players must be sorted according to their role, in the order of goalkeeper, defenders, midfielders, and strikers. The players with the same role are sorted according to ascending order of their numbers. There is an exception that the captain always comes as the first player in the entire list. If it is not possible to arrange the team conforming to the desired formation, write a single line containing IMPOSSIBLE TO ARRANGE in the output. There should be a blank line after the output for each test case.

Sample Input
9 PlayerA M 2000-2001 2003-2006
2 PlayerB M 2004-2006
10 PlayerC D 2001-2005
1 PlayerD D 2000-2001 2002-2004
11 PlayerE S 2003-2006
8 PlayerF M 2005-2006
22 PlayerG S 2005-2006
25 PlayerH G 2000-2001 2002-2003 2005-2006
6 PlayerI D 2003-2006
26 PlayerJ D 2003-2004 2000-2001
18 PlayerK M 2003-2004
19 PlayerL M 2000-2001 2003-2006
7 PlayerM S 2003-2006 1999-2001
21 PlayerN S 2003-2006
13 PlayerO S 2005-2006
15 PlayerP G 2001-2006
14 PlayerQ D 2003-2004
5 PlayerR S 2000-2005
20 PlayerS G 2000-2002 2003-2003
12 PlayerT M 2004-2005
3 PlayerU D 2000-2005
4 PlayerV M 2001-2004
4-4-2
0

Sample Output
7 PlayerM S
15 PlayerP G
1 PlayerD D
3 PlayerU D
6 PlayerI D
10 PlayerC D
2 PlayerB M
4 PlayerV M
8 PlayerF M
9 PlayerA M
5 PlayerR S

1个回答

图片说明

今天抽空写完了剩下的代码,细节可能不会面面俱到,但基本功能是实现了的。
若有遗漏请自行修改了。有不懂就回帖问。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>

struct Player {//球员结构
    int number; //玩家编号
    char name[20];  //名字
    char type;  //类型 G、D、M、S 分别对应守门员,后卫,中场和前锋
    char years[20][10]; //年份 这里用一个二维数组 最多20行,每行录入一条信息。
};

int main() {
    struct Player team[22], *captain = NULL;    //定义22个球员和指向队长的指针
    int nowCaptainYears = 0;    //记录当前队长的年份,用于确定谁是队长

    int i = 0, j = 0, k = 0;
    char t = 0;

    for (; i < 22; ++i) {//初始化数据
        team[i].number = -1;
        strcpy(team[i].name, "");
        team[i].type = '\0';
        for (j = 0; j < 20; ++j) {
            strcpy(team[i].years[j], "");
        }
    }

    printf("请输入球员数据:\n");

    i = 0;
    do {
        int Years = 0;
        j = 0;
        scanf("%d %s %c",&team[i].number,team[i].name,&team[i].type);   //先输入编号、姓名、类型

        while (t = getchar()) {
            if (t == 10 || t == '\n')   //当遇到回车或者是换行符即切换下一个球员输入
                break;  //当前球员录入完毕则退出循环
            int start = 0, end = 0;
            scanf("%s", team[i].years[j]);  //输入年份
            sscanf(team[i].years[j], "%d-%d", &start, &end);
            Years += (end - start);
            ++j;
        }

        if (Years == nowCaptainYears) { //相同年份的情况下,选择参与次数多的(如果我没理解错的话),要是是选择number大小就更简单了,一个if完事
            int old = 0; int now = 0;
            int n = 0;
            while (strcmp(captain->years[n], "")) {
                ++n;
                ++old;
            }

            n = 0;
            while (strcmp(team[i].years[n], "")) {
                ++n;
                ++now;
            }

            if (old < now) {
                captain = &team[i];
            }
        }

        if (Years > nowCaptainYears) {
            captain = &team[i];
            nowCaptainYears = Years;
        }

        ++i;

    } while (i<22);

    i = j = k = 0;

    scanf("%d-%d-%d", &i, &j, &k);  //阵营安排
    getchar();  //取出回车或者换行符

    struct Player *G = NULL, **D = NULL, **M = NULL, **S = NULL;    //做表外排序用的指针,守门员只用选一个,其他选相应个数

    if (captain->type == 'D')
        i--;
    if (captain->type == 'M')
        j--;
    if (captain->type == 'S')
        k--;

    if (i != 0 && j != 0 && k != 0) {
        D = (struct Player**)malloc(sizeof(struct Player*)*i);
        M = (struct Player**)malloc(sizeof(struct Player*)*j);
        S = (struct Player**)malloc(sizeof(struct Player*)*k);
    }

    if (getchar() == '0') {
        int n = 0, m = 0, key = 0;
        for (n = 0; n < 22; ++n) {  //赋初值
            if (team[n].type == 'D') {
                D[0] = &team[n];
                break;
            }
        }
        for (n = 0; n < 22; ++n) {
            if (team[n].type == 'M') {
                M[0] = &team[n];
                break;
            }
        }
        for (n = 0; n < 22; ++n) {
            if (team[n].type == 'S') {
                S[0] = &team[n];
                break;
            }
        }

        for (n = 0; n < i; ++n) {
            for (m = 0;m<22;++m) {
                //排除队长与其他类型之外,选出对应数目的合适的队员
                if (team[m].type == 'D' && &team[m] != captain && key < team[m].number && team[m].number < D[n]->number) {
                    D[n] = &team[m];
                }
            }
            key = D[n]->number; //设置一个key值,记录上一次选出的球员编号,防止重复。
            if (n == i - 1) {
                break;  //选完了就退出
            }
            for (m = 0; m < 22; ++m) {
                if (team[m].type == 'D' && &team[m] != captain && team[m].number > key) {
                    D[n + 1] = &team[m];
                    break;
                }
            }
            if (D[n + 1] == NULL) { //找不到合适的队员输出错误信息,其他2个循环同理
                printf("没有足够的队员!\n");
                exit(-1);
            }
        }

        key = 0;
        for (n = 0; n < j; ++n) {
            for (m = 0; m < 22; ++m) {
                //排除队长与其他类型之外,选出对应数目的合适的队员
                if (team[m].type == 'M' && &team[m] != captain && key < team[m].number && team[m].number < M[n]->number) {
                    M[n] = &team[m];
                }
            }
            key = M[n]->number;
            if (n == j - 1) {
                break;
            }
            for (m = 0; m < 22; ++m) {
                if (team[m].type == 'M' && &team[m] != captain && team[m].number > key) {
                    M[n + 1] = &team[m];
                    break;
                }
            }
            if (M[n + 1] == NULL) {
                printf("没有足够的队员!\n");
                exit(-1);
            }
        }

        key = 0;
        for (n = 0; n < k; ++n) {
            for (m = 0; m < 22; ++m) {
                //排除队长与其他类型之外,选出对应数目的合适的队员
                if (team[m].type == 'S' && &team[m] != captain && key < team[m].number && team[m].number < S[n]->number) {
                    S[n] = &team[m];
                    key = S[n]->number;
                }
            }
            key = M[n]->number;
            if (n == k - 1) {
                break;
            }
            for (m = 0; m < 22; ++m) {
                if (team[m].type == 'S' && &team[m] != captain && team[m].number > key) {
                    S[n + 1] = &team[m];
                    break;
                }
            }
            if (S[n + 1] == NULL) {
                printf("没有足够的队员!\n");
                exit(-1);
            }
        }

        if (captain->type != 'G') { //队长不为守门员的情况,选出守门员
            for (n = 0; n < 22; ++n) {
                if (team[n].type == 'G') {
                    G = &team[n];
                    break;
                }
            }
            if (G == NULL) {
                printf("没有足够的队员!\n");
                exit(-1);
            }
            for (n = 0; n < 22; ++n) {
                if (team[n].type == 'G' && team[n].number < G->number) {
                    G = &team[n];
                }
            }
        }
        else G == NULL;

        if (captain->type != 'G') {
            printf("%d %s %c\n",captain->number,captain->name,captain->type);
            printf("%d %s %c\n",G->number,G->name,G->type);
        }
        else printf("%d %s %c\n", G->number, G->name, G->type);
        for (n = 0; n < i; ++n) //输出D类型
            printf("%d %s %c\n", D[n]->number, D[n]->name, D[n]->type);
        for (n = 0; n < j; ++n) //输出M类型
            printf("%d %s %c\n", M[n]->number, M[n]->name, M[n]->type);
        for (n = 0; n < k; ++n) //输出S类型
            printf("%d %s %c\n", S[n]->number, S[n]->name, S[n]->type);

    }

    free(D);
    free(M);
    free(S);
    return 0;
}
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问