2012/12/10

SPOJ: Шүүгч бодлогын бодолт

http://www.spoj.com/CSMS/problems/TOP0002/

Бодолтын тайлбар:

Team гэдэг struct үүсгэж байгаа юм.
Symbol - багийн тэмдэг
point - багийн оноо
number - багийн гишүүдийн тоо
sixth - 6 дахь гишүүний байр

str гэдэгт оролтын тэмдэгт мөр орно.
34-р мөрд n ширхэг Team-г санах ойд нөөцөлж авна. calloc функ ашигласан учраас нөөцлөгдсөн санах ойн утга бүгд 0 болно. Тиймээс symbol, point, number, sixth бүгд 0 гэсэн утгатай болох учир утга олгох шаардлагагүй.
35-р мөр дахь давталт тэмдэгт мөрийг эхнээс нь төгсөх хүртэл нэг нэг тэмдэгтээр давтана. Тэгээд үүссэн n ширхэг Team-дээ утгуудаа хадгална. Баг 6 гишүүнтэй бол зургаа дахь гишүүний оноог sixth дээр хадгална.

47-р мөрд багуудаа эрэмбэлж байна. Selection Sort ашигласан болно. Үндсэн гол нөхцөл шалгах үйлдлээ diff_teams (11-р мөр) гэсэн функцээр илэрхийлж байгаа. Хоёр багийн 5-аас олон гишүүнтэй нь бага. Хоёулаа 5, оноо нь тэнцүү бол symbol-ын зөрөөгөөрөө, хоёулаа 6 гишүүнтэй, эхний тавынх нь оноонууд нь тэнцүү бол 6 дахь гишүүний оноогоор, хоёулаа 5-аас бага гишүүдтэй бол онооны зөрүүгээр тооцно.

60-р мөрд эрэмбэлсэн багуудынхаа symbol-г хэвлэнэ.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <stdio.h>
#include <stdlib.h>

typedef struct Team
{
    char symbol;
    int point;
    int number;
    int sixth;
}team_t;
int diff_teams(team_t *team1, team_t *team2)
{
    if(team1->number >= 5 && team2->number < 5)
        return -1;
    else if(team1->number < 5 && team2->number >= 5)
        return 1;
    else if(team1->number == 5 && team2->number == 5 && team1->point == team2->point)
        return team1->symbol - team2->symbol;
    else if(team1->number > 5 && team2->number > 5 && team1->point == team2->point)
        return team1->sixth - team2->sixth;
    else
        return team1->point - team2->point;
}

int main()
{
    char str[51];
    int n;
    int i, j;
    team_t *team;
    team_t *current_team;
    scanf("%d", &n);
    scanf("%s", str);
    team = (team_t*) calloc(n, sizeof(team_t));
    for(i = 0; str[i] != '\0'; i++)
    {
        current_team = team + str[i] - 'A';
        if(current_team->symbol == 0)
            current_team->symbol = str[i];
        current_team->number++;
        if(current_team->number <= 5)
            current_team->point += i + 1;
        else if(current_team->sixth == 0)
            current_team->sixth = i + 1;
    }
  
    for(i = n - 1; i > 0; i--)
    {
        team_t max_team = *team;
        int maxi = 0;
        for(j = 1; j <= i; j++)
            if(diff_teams(&max_team, team + j) < 0)
            {
                max_team = *(team + j);
                maxi = j;
            }
        *(team + maxi) = *(team + i);
        *(team + i) = max_team;
    }
    for(i = 0; i < n; i++)
        if((team + i)->number >= 5)
        printf("%c", (team + i)->symbol);
    return 0;
}

No comments:

Post a Comment