POJ 1030--Rating

博客介绍了POJ 1030问题的解决思路,涉及多个队伍在两场比赛中的排名比较。通过计算两场比赛的胜差来决定最终排名,对于只参加一场的队伍,需对比已知排名的队伍。文章提供了排序算法的思路和代码实现,重点在于链表的使用和复杂情况的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意

题目大意是讲有若干个队伍参加两场比赛,其中一些队伍只参加了其中一场,每个队伍均有一个单独的ID(1-100).

比较出所有队伍最终排名.

example:

Contest1Contest2
placeidplaceid
1913
27,1,425
5531,10
615,856
831,1869
1017719
84,20
1021

排名要求:

  • 如果 A 队在两场比赛中均胜过其他一些队伍,那么这个 A 队的最终排名一定比这些队伍排名高.
  • 如果 A 队在第一场比赛表现胜过 B 队,在第二场不如 B 队,那么他们最终的排名根据两队在两场比赛中的排名差来判断.比如在比赛1中,1队的排名为2,5队的排名为5,胜差为3;在比赛2里,1队的排名为3,5队的排名为2,胜差为-1,总胜差为2.因此,最终排名1队高于5队.如果总胜差为0,那么他们最终的排名也相同,比如5队和9队.
  • 如果 A 队参加了两场比赛,B 队伍只参加了比赛1,并且在比赛1中A 队和 B 队的排名相同,同时在这个排名的位置没有其他参加了两场比赛并且最终排名和 A 队不相同的队伍,那么他们的最终排名也相同.比如10队与1队的最终排名相同,另外虽然7队的排名和1队、4队相同,但是因为1、4队最终排名不相同,所以7队的最终排名无法确定.在比赛2中,6队虽然排名在5队和9队的中间,但是因为5队和9队的最终排名相同,所以6队的排名也不能确定.
  • 对于只参加了一场比赛的队伍,则比较他们在比赛中与最终排名已经确定的队伍表现.比如3队.排名末尾的队伍,最终排名也为末尾,比如17和21队.

results:

final placeboth contestsone contest only
1
2110
35,9
419
5420
68,15
718,31
817,21

分析

很明显,首先应该计算参加过两场比赛的队伍的最终排名,然后参加过一场比赛的队伍去比较排名已经确定的队伍,确定他们的最终排名.
为了方便排序,用了链表,先构建参加了两场比赛队伍的排名,然后遍历剩余队伍.只要不考虑掉情况,问题不大.

代码如下:
Memory: 816K Time: 79MS Length: 249LINES

#include <iostream>
#include <map>
#include <set>
#include <sstream>
#include <vector>
using namespace std;

const int max_num = 100;
typedef set<int> set_int;
typedef map<float, set_int> mp_f_si;
struct node_t {
    float rate;
    set_int ids;
    node_t* next;
    node_t() {rate = 0.0; next = NULL;}
};
struct info_t {
    int id;
    bool flag;
    info_t(int x, bool y) {id = x; flag = y;}
    info_t() {id = 0; flag = false;}
};
struct rate_info_t {
    int rate;
    vector<info_t*> vinfo;
    rate_info_t* next;
    rate_info_t() {rate = 0; next = NULL;}
};
struct rate_t {
    info_t* p_info;
    int rate;
    rate_t() {p_info = NULL; rate = 0;}
};
rate_t rate[2][max_num + 1];

void destroy(rate_info_t* p)
{
    while (p) {
        rate_info_t* tp = p;
        p = p->next;
        for (vector<info_t*>::iterator it = tp->vinfo.begin(); it != tp->vinfo.begin(); ++it) {
            delete *it;
        }
        delete tp;
        tp = NULL;
    }
}

int get_rate(node_t* head, int id)
{
    int rate = 1;
    for (int rate = 1; head; ++rate, head = head->next) {
        if (head->ids.count(id)) {
            return rate;
        }
    }
    return -1;
}

bool check(vector<info_t*>& vec, node_t* head, int id) {
    if (vec.size() < 3) {
        return true;
    } else {
        int rate = 0;
        for (vector<info_t*>::iterator it = vec.begin(); it != vec.end(); ++it) {
            if ((*it)->flag && (*it)->id != id) {
                if (rate == 0) {
                    rate = get_rate(head, (*it)->id);
                } else if (rate != get_rate(head, (*it)->id)) {
                    return false;
                }
            }
        }
    }
    return true;
}

bool check2(set_int& si, int id) {
    for (set_int::iterator it = si.begin(); it != si.end(); ++it) {
        if ((rate[0][*it].rate != 0 && rate[0][*it].rate != rate[0][id].rate) &&
            (rate[1][*it].rate != 0 && rate[1][*it].rate != rate[1][id].rate)) {
            return false;
        }
    }
    return true;
}

bool insert(node_t* head, rate_t* rate, int id)
{
    int max_rate = 0, min_rate = 0;
    node_t* pre;
    for (pre = head; pre && pre->next; pre = pre->next) {
        node_t* node = pre;
        for (set_int::iterator it = node->ids.begin(); it != node->ids.end(); ++it) {
            if (rate[*it].rate != 0 && rate[*it].rate > max_rate) {
                max_rate = rate[*it].rate;
            }
        }
        node = pre->next;
        min_rate = max_num + 1;
        while (node) {
            for (set_int::iterator it = node->ids.begin(); it != node->ids.end(); ++it) {
                if (rate[*it].rate != 0 && rate[*it].rate < min_rate) {
                    min_rate = rate[*it].rate;
                }
            }
            node = node->next;
        }
        if (min_rate == max_num + 1) {
            min_rate = pre->next->rate;
        }
        if (rate[id].rate > max_rate && rate[id].rate < min_rate) {
            break;
        }
    }
    if (rate[id].rate > max_rate) {
        if (pre && rate[id].rate == pre->rate && check2(pre->ids, id)) {
            pre->ids.insert(id);
        } else if (pre->next && rate[id].rate == pre->next->rate && check2(pre->next->ids, id)) {
            pre->next->ids.insert(id);
        } else {
            node_t* nxt = pre->next;
            pre->next = new node_t;
            pre->next->ids.insert(id);
            pre->next->rate = rate[id].rate;
            pre->next->next = nxt;
        }
        return true;
    }
    return false;
}

int main()
{
    rate_info_t rinfo[2];
    rate_info_t* rinfo_rear[2];
    rinfo_rear[0] = &rinfo[0];
    rinfo_rear[1] = &rinfo[1];

    int cnt[2] = { 0 };
    int lines;
    int id;
    int tmprate;
    for (int ct_idx = 0; ct_idx < 2; ++ct_idx) {
        cin >> lines;
        string buff;
        getline(cin, buff);
        tmprate = 1;
        for (int i = 0; i < lines; ++i) {
            getline(cin, buff);
            istringstream istr(buff);
            rinfo_rear[ct_idx]->next = new rate_info_t;
            rinfo_rear[ct_idx] = rinfo_rear[ct_idx]->next;
            rinfo_rear[ct_idx]->rate = tmprate;
            int rate_cnt = 0;
            while (istr >> id) {
                ++rate_cnt;
                ++cnt[ct_idx];
                rate[ct_idx][id].rate = tmprate;
                rate[ct_idx][id].p_info = new info_t(id, false);
                rinfo_rear[ct_idx]->vinfo.push_back(rate[ct_idx][id].p_info);
            }
            tmprate += rate_cnt;
        }
    }
    rinfo_rear[0] = rinfo[0].next;
    rinfo_rear[1] = rinfo[1].next;
    mp_f_si map_result;
    for (int i = 1; i < max_num + 1; ++i) {
        if (rate[0][i].rate != 0 && rate[1][i].rate != 0) {
            rate[0][i].p_info->flag = rate[1][i].p_info->flag = true;
            map_result[(rate[0][i].rate + rate[1][i].rate) / 2.0].insert(i);
        }
    }
    node_t final_result;
    node_t* rear = &final_result;
    for (mp_f_si::iterator it = map_result.begin(); it != map_result.end(); ++it) {
        rear->next = new node_t;
        rear = rear->next;
        rear->ids.insert(it->second.begin(), it->second.end());
        rear->rate = it->first;
    }
    node_t* head = final_result.next;
    for (int ct_idx = 0; ct_idx < 2; ++ct_idx) {
        for (rate_info_t* ri_rear = rinfo[ct_idx].next; ri_rear; ri_rear = ri_rear->next) {
            for (vector<info_t*>::iterator it = ri_rear->vinfo.begin(); it != ri_rear->vinfo.end(); ++it) {
                if (!(*it)->flag && check(ri_rear->vinfo, head, (*it)->id)) {
                    if (!head) {
                        node_t* p = new node_t;
                        p->rate = rate[ct_idx][(*it)->id].rate;
                        p->ids.insert((*it)->id);
                        p->next = head;
                        head = rear = p;
                    } else {
                        bool key = false;
                        for (vector<info_t*>::iterator it2 = ri_rear->vinfo.begin(); it2 != ri_rear->vinfo.end(); ++it2) {
                            if ((*it2)->id != (*it)->id && (*it2)->flag) {
                                for (node_t* p = head; p; p = p->next) {
                                    if (p->ids.count((*it2)->id)) {
                                        p->ids.insert((*it)->id);
                                        break;
                                    }
                                }
                                (*it)->flag = true;
                                key = true;
                                break;
                            }
                        }
                        if (!key && rate[ct_idx][(*it)->id].rate == 1) {
                           if (head->rate == 1) {
                                head->ids.insert((*it)->id);
                            } else {
                                node_t* p = new node_t;
                                p->rate = 1;
                                p->ids.insert((*it)->id);
                                p->next = head;
                                head = p;
                            }
                            key = true;
                            (*it)->flag = true;
                        }
                        if (!key && insert(head, rate[ct_idx], (*it)->id)) {
                            (*it)->flag = true;
                        }
                    }
                    if (rear->next) {
                        rear = rear->next;
                    }
                }
            }
        }
    }
    for (node_t* node = head; node;) {
        for (set_int::iterator it = node->ids.begin(); it != node->ids.end();) {
            cout << *it;
            if ((++it) == node->ids.end()) {
                cout << endl;
            } else {
                cout << " ";
            }
        }
        node_t* p = node;
        node = node->next;
        delete p;
    }
    destroy(rinfo[0].next);
    destroy(rinfo[1].next);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值