POJ1030 Rating
题目来源:http://poj.org/problem?id=1030
题目大意:有100支队伍(编号1->100),有两场比赛。以下表的形式列出了两场比赛的名次。(有的队伍没有参赛或只参加了一场比赛。)

要求两场比赛的总排名。计算规则是:
1.如果某队两场都比另一队排名靠前(或一场赢一场平),则总排名靠前。
2.如果两队在两场比赛中各赢一场,则他们的排名取决于他们在两场比赛中的排名差。如上面的例子中1队在比赛1中赢了5队,名次差为3,在比赛2中输给5对,名次差为1,所以1队应排在5队前面。如果两个名次差相等,则两队的总排名相等。两队两场比赛都平局时总排名也相等。
3.对于只参加了一次比赛的队伍,他们的最终排名不一定能够确定。他们能否进入最终名单由下面的规则决定:
A) 如果存在某支队伍参加了两场比赛,与该队伍平局,那么这个队伍的排名与这支参加两场的排名一致。如果有多支这样的队伍,他们的排名应该完全相同,否则所有的队伍排名都不能决定。
B) 如果能为只参加了一场比赛c的一支队伍A找到一个位置,使得这个位置之前的队伍在c中都赢了A,该位置之后的队伍在c中都输给A,则可以把A插入到该位置,如果有多个队伍可以插到该位置,按他们在各自比赛中获得的名次决定先后顺序或并列。

对于上面图片所示的例子,分析过程如下:
Team 3 will occupy the first place in the overall list (rule B).
The positions of teams 6 and 7 cannot be determined.
Team 10 will share the overall rating with team 1 (rule A).
Team 20 will share the overall rating with team 4 (rule A).
Team 19 will occupy the position between teams 9, 5 and team 4 (rule B).
Teams 8, 15, 17, 18, 21, and 31 will finish the overall list (rule B). But the first of them will be teams 15 and 8 (that took 6th place) followed by teams 31 and 18 (that took 8th place) and teams 17 and 21 (that took 10th place).
程序的目标是由两场比赛的排名求总排名。
输入:两场比赛中表格中team's id部分。
输出:同样形式的总排名。
Sample Input
6
9
7 1 4
5
15 8
31 18
17 8
3
5
1 10
6
9
19
4 20
21
Sample Output
3
1 10
5 9
19
4 20
8 15
18 31
17 21
我的程序写得比较复杂了,按照每条规则为每个队伍找排名。一个处理是在计算时把排名设定为浮点数而不是整数,这样在进行插入的时候不会需要移动很多队伍的名次,最要最后整理的时候映射为整数即可。
//////////////////////////////////////////////////////////////////////////
// POJ1030 Rating
// Memory: 320K Time: 94MS
// Language: C++ Result: Accepted
////////////////////////////////////////////////////////////////////////// #include <iostream>
#include <stdio.h>
#include <map>
#include <list> using namespace std; int cnt[];
int rank1[];
int rank2[];
float rank[];
float buff[];
bool tag[];
map<int, list<int>> record1;
map<int, list<int>> record2;
int k1, k2; struct Rate {
float rank;
list<int> teams;
Rate * next;
};
Rate * head = NULL; float compRank(Rate * a, Rate * b) {
return a->rank - b->rank;
}
bool cmp(const void * a, const void * b) {
return *(int *)a > *(int *)b ? true : false;
}
void exchangeRank(Rate *a, Rate * b) {
float rank = a->rank;
list<int> teams = a->teams;
a->rank = b->rank;
a->teams = b->teams;
b->rank = rank;
b->teams = teams;
}
void sortRank() {
if (head == NULL || head->next == NULL) {
return;
}
Rate * key = head->next;
Rate * p = head;
while (key != NULL) {
while (p != key) {
if (compRank(p, key) > ) {
exchangeRank(p, key);
}
p = p->next;
}
p = head;
key = key->next;
}
}
void readData() {
char buf[];
int teamId;
int teamCnt;
char * pCur;
int rankSum = ;
int rankCur = ; gets(buf);
sscanf(buf, "%d", &k1);
for (int i = ; i < k1; ++i) {
gets(buf);
rankCur = rankSum + ;
pCur = strtok(buf, " ");
list<int> ts;
while (pCur) {
++rankSum;
teamId = atoi(pCur);
++cnt[teamId];
rank1[teamId] = rankCur;
ts.push_back(teamId);
pCur = strtok(NULL, " ");
}
record1[rankCur] = ts;
}
getchar();
gets(buf);
sscanf(buf, "%d", &k2);
rankSum = rankCur = ;
for (int i = ; i < k2; ++i) {
gets(buf);
rankCur = rankSum + ;
pCur = strtok(buf, " ");
list<int> ts;
while (pCur) {
++rankSum;
teamId = atoi(pCur);
++cnt[teamId];
rank2[teamId] = rankCur;
ts.push_back(teamId);
pCur = strtok(NULL, " ");
}
record2[rankCur] = ts;
}
} void cc2() {
for (int i = ; i <= ; ++i) {
if (cnt[i] == ) {
rank[i] = rank1[i] + rank2[i];
}
}
for (int i = ; i <= ; ++i) {
Rate * rate = new Rate;
rate->rank = i;
for (int j = ; j <= ; ++j) {
if (rank[j] == i) {
rate->teams.push_back(j);
}
}
if (!rate->teams.empty()) {
rate->next = head;
head = rate;
}
}
} void cc1() {
for (int i = ; i <= ; ++i) {
if (cnt[i] != ) {
continue;
}
int r;
int p;
if (rank1[i] != ) {
r = rank1[i];
p = ;
} else {
r = rank2[i];
p = ;
}
int count = ;
list<int> temp;
if (p == ) {
temp = record1[r];
} else {
temp = record2[r];
}
list<int> eq;
for (list<int>::iterator it = temp.begin(); it != temp.end(); ++it) {
if (cnt[*it] == ) {
eq.push_back(*it);
}
}
if (!eq.empty()) {
int rc = rank[eq.front()];
bool flag = true;
for (list<int>::iterator it = eq.begin(); it != eq.end(); ++it) {
if (rank[*it] != rc) {
rank[i] = ;
flag = false;
break;
}
}
if (flag == true) {
for (Rate * p = head; p != NULL; p = p->next) {
if (p->rank == rc) {
p->teams.push_back(i);
break;
}
}
}
} else {
tag[i] = true;
}
}
for (int i = ; i <= ; ++i) {
if (tag[i] != true) {
continue;
}
int p;
int r;
if (rank1[i] != ) {
r = rank1[i];
p = ;
} else {
r = rank2[i];
p = ;
}
int * temp = (p == ) ? rank1 : rank2;
int prior = -;
int next = ;
for (int j = ; j <= ; ++j) {
if (temp[j] != && temp[j] < r && rank[j] != ) {
if (rank[j] > prior) {
prior = rank[j];
}
}
if (temp[j] != && temp[j] > r && rank[j] != ) {
if (rank[j] < next) {
next = rank[j];
}
} }
if (next > prior) {
buff[i] = (next + prior) / 2.0;
}
}
} void insertcc1() {
for (int i = ; i <= ; ++i) {
if (buff[i] == ) {
continue;
}
float fr = buff[i];
Rate * p = head;
Rate * rate = new Rate;
rate->rank = fr;
rate->teams.push_back(i);
if (head == NULL || fr < head->rank) {
rate->next = head;
head = rate;
continue;
} else if (fr == head->rank) {
int t1 = rank1[i] > ? rank1[i] :rank2[i];
int t2 = rank1[head->teams.front()] > ?rank1[head->teams.front()] : rank2[head->teams.front()];
if (t1 == t2) {
head->teams.push_back(i);
continue;
} else if (t1 < t2) {
rate->next = head;
head = rate;
continue;
}
}
Rate * q = p->next;
bool f = false;
while(q != NULL) {
if (fr < q->rank) {
rate->next = q;
p->next = rate;
f = true;
break;
} else if (fr == q->rank) {
int t1 = rank1[i] > ? rank1[i] :rank2[i];
int t2 = rank1[q->teams.front()] > ?rank1[q->teams.front()] : rank2[q->teams.front()];
if (t1 == t2) {
q->teams.push_back(i);
} else if (t1 < t2) {
rate->next = q;
p->next = rate;
} else {
if (q->next == NULL) {
rate->next = q->next;
q->next = rate;
} else{
int t3 = rank1[q->next->teams.front()] > ? rank1[q->next->teams.front()] : rank2[q->next->teams.front()];
if (t3 > t1) {
rate->next = q->next;
q->next = rate;
} else {
p = p->next;
q = q->next;
continue;
}
}
}
f = true;
break;
}
p = p->next;
q = q->next;
}
if (f == true) {
continue;
}
rate->next = NULL;
p->next = rate;
}
}
void output() {
for (Rate * p = head; p != NULL; p = p->next) {
p->teams.sort();
for (list<int>::iterator it = p->teams.begin(); it != p->teams.end(); ++it) {
if (*it != p->teams.back()) {
cout << *it << " ";
} else {
cout << *it;
if (p->next != NULL) {
cout << endl;
}
}
}
}
}
int main () {
readData();
cc2();
sortRank();
cc1();
insertcc1();
output();
system("pause");
return ;
}
必须承认代码写得很拙劣,不过思路还是能看得比较清晰吧。
POJ1030 Rating的更多相关文章
- Codefroces 750C:New Year and Rating(思维)
http://codeforces.com/contest/750/problem/C 题意:有n场比赛,每场比赛有一个c,代表比赛结束后分数的增长情况,有一个d,代表这场比赛在div1或者div2打 ...
- AngularJs的UI组件ui-Bootstrap分享(十二)——Rating
Rating是一个用于打分或排名的控件.看一个最简单的例子: <!DOCTYPE html> <html ng-app="ui.bootstrap.demo" x ...
- 从Elo Rating System谈到层次分析法
1. Elo Rating System Elo Rating System对于很多人来说比较陌生,根据wikipedia上的解释:Elo评分系统是一种用于计算对抗比赛(例如象棋对弈)中对手双方技能水 ...
- HDU 4870 Rating(概率、期望、推公式) && ZOJ 3415 Zhou Yu
其实zoj 3415不是应该叫Yu Zhou吗...碰到ZOJ 3415之后用了第二个参考网址的方法去求通项,然后这次碰到4870不会搞.参考了chanme的,然后重新把周瑜跟排名都反复推导(不是推倒 ...
- Elo rating system 模拟
package org.cc.foo_008; import java.util.ArrayList; import java.util.List; import java.util.Random; ...
- HDU4870 Rating(概率)
第一场多校,感觉自己都跳去看坑自己的题目里去了,很多自己可能会比较擅长一点的题目没看,然后写一下其中一道概率题的题解吧,感觉和自己前几天做的概率dp的思路是一样的.下面先来看题意:一个人有两个TC的账 ...
- HDU 4870 Rating 概率DP
Rating Time Limit:5000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Statu ...
- hdu 4870 Rating
题目链接:hdu 4870 这题应该算是概率 dp 吧,刚开始看了好几个博客都一头雾水,总有些细节理不清楚,后来看了 hdu 4870 Rating (概率dp) 这篇博客终于有如醍醐灌顶,就好像是第 ...
- HDU 4870 Rating(高斯消元 )
HDU 4870 Rating 这是前几天多校的题目,高了好久突然听旁边的大神推出来说是可以用高斯消元,一直喊着赶快敲模板,对于从来没有接触过高斯消元的我来说根本就是一头雾水,无赖之下这几天做DP ...
随机推荐
- HDU4699:Editor
浅谈栈:https://www.cnblogs.com/AKMer/p/10278222.html 题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=46 ...
- 洛谷【P1080】国王游戏
我对贪心的理解:https://www.cnblogs.com/AKMer/p/9776293.html 题目传送门:https://www.luogu.org/problemnew/show/P10 ...
- bzoj 1070 修车 —— 费用流
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1070 需要考虑前面修的车对后面等待的车造成的时间增加: 其实可以从每个人修车的顺序考虑,如果 ...
- HDOJ2553(2N皇后问题)
N皇后问题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- Python:更改字典的key
思路:先删除原键值对,保存值,然后以新键插入字典 格式:dict[newkey] = dict.pop(key) d = {'a':1, 'aa':11} d['b'] = d.pop('a') d[ ...
- ss1
首先,对系统来一次升级,以解决一些莫名其妙的依赖问题. sudo yum update 然后安装Python-pip. sudo yum -y install python-pip 注意,通过yum包 ...
- electron将网站打包成桌面应用
需求同 NW.js将网站打包成桌面应用 1. 从github上克隆electron示例项目 git clone https://github.com/electron/electron-quick-s ...
- Mysql ExcuteNonQuery
ExecuteNonQuery()方法主要用户更新数据,通常它使用Update,Insert,Delete语句来操作数据库,其方法返回值意义:对于 Update,Insert,Delete 语句 执 ...
- This account is currently not available
今天在linux下切换用户发现提示This account is currently not available,说是无效用户了后来网上查了一下发现是用户的shell禁止登录了,解决方法只要开启she ...
- MinimumTours TopCoder - 7620
Problem Statement Little Bonnie has taken a vacation to Ha Long Bay. There are a few thousand s ...