题意
题目大意是讲有若干个队伍参加两场比赛,其中一些队伍只参加了其中一场,每个队伍均有一个单独的ID(1-100).
比较出所有队伍最终排名.
example:
Contest1 | Contest2 | ||
---|---|---|---|
place | id | place | id |
1 | 9 | 1 | 3 |
2 | 7,1,4 | 2 | 5 |
5 | 5 | 3 | 1,10 |
6 | 15,8 | 5 | 6 |
8 | 31,18 | 6 | 9 |
10 | 17 | 7 | 19 |
8 | 4,20 | ||
10 | 21 |
排名要求:
- 如果 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 place | both contests | one contest only |
---|---|---|
1 | ||
2 | 1 | 10 |
3 | 5,9 | |
4 | 19 | |
5 | 4 | 20 |
6 | 8,15 | |
7 | 18,31 | |
8 | 17,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;
}