题目来源: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的更多相关文章

  1. Codefroces 750C:New Year and Rating(思维)

    http://codeforces.com/contest/750/problem/C 题意:有n场比赛,每场比赛有一个c,代表比赛结束后分数的增长情况,有一个d,代表这场比赛在div1或者div2打 ...

  2. AngularJs的UI组件ui-Bootstrap分享(十二)——Rating

    Rating是一个用于打分或排名的控件.看一个最简单的例子: <!DOCTYPE html> <html ng-app="ui.bootstrap.demo" x ...

  3. 从Elo Rating System谈到层次分析法

    1. Elo Rating System Elo Rating System对于很多人来说比较陌生,根据wikipedia上的解释:Elo评分系统是一种用于计算对抗比赛(例如象棋对弈)中对手双方技能水 ...

  4. HDU 4870 Rating(概率、期望、推公式) && ZOJ 3415 Zhou Yu

    其实zoj 3415不是应该叫Yu Zhou吗...碰到ZOJ 3415之后用了第二个参考网址的方法去求通项,然后这次碰到4870不会搞.参考了chanme的,然后重新把周瑜跟排名都反复推导(不是推倒 ...

  5. Elo rating system 模拟

    package org.cc.foo_008; import java.util.ArrayList; import java.util.List; import java.util.Random; ...

  6. HDU4870 Rating(概率)

    第一场多校,感觉自己都跳去看坑自己的题目里去了,很多自己可能会比较擅长一点的题目没看,然后写一下其中一道概率题的题解吧,感觉和自己前几天做的概率dp的思路是一样的.下面先来看题意:一个人有两个TC的账 ...

  7. HDU 4870 Rating 概率DP

    Rating Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Statu ...

  8. hdu 4870 Rating

    题目链接:hdu 4870 这题应该算是概率 dp 吧,刚开始看了好几个博客都一头雾水,总有些细节理不清楚,后来看了 hdu 4870 Rating (概率dp) 这篇博客终于有如醍醐灌顶,就好像是第 ...

  9. HDU 4870 Rating(高斯消元 )

    HDU 4870   Rating 这是前几天多校的题目,高了好久突然听旁边的大神推出来说是可以用高斯消元,一直喊着赶快敲模板,对于从来没有接触过高斯消元的我来说根本就是一头雾水,无赖之下这几天做DP ...

随机推荐

  1. windows下面的python的MySQLdb环境安装

    什么是MySQLdb? MySQLdb 是用于Python链接Mysql数据库的接口,它实现了 Python 数据库 API 规范 V2.0,基于 MySQL C API 上建立的. 如何安装MySQ ...

  2. CMake简易入门

    使用CMake编译 CMake工具用于生成Makefile文件.用户通过编写CMakeLists.txt文件,描述构建过程(编译.连接.测试.打包),之后通过解析该文件,生成目标平台的Makefile ...

  3. Agc017_E Jigsaw

    传送门 题目大意 有$n$块拼图,每一块都由左中右三个部分组成,每块拼图中间部分是高为$H$的长方形,对于第$i$块品推左侧是高为$A_i$距离底部为$C_i$的长方体,右侧是高位$B_i$距底部为$ ...

  4. C++中getline的用法

    在看紫皮书的时候看到getline,然后查了查具体用法,记录下来. #include"iostream" #include"string" using name ...

  5. oracle 12c 列式存储 ( In Memory 理论)

    随着Oracle 12c推出了in memory组件,使得Oracle数据库具有了双模式数据存放方式,从而能够实现对混合类型应用的支持:传统的以行形式保存的数据满足OLTP应用:列形式保存的数据满足以 ...

  6. debian上安装codeblocks

    1.查看linux的版本uname -a 2.在官网上下载稳定版的codeblocks(www.codeblocks.org) 3.解压codeblocks后,进入到文件夹中用root身份执行dpkg ...

  7. ZAB与Paxos算法的联系与区别

    ZAB协议并不是Paxos算法的一个典型实现,在讲解ZAB和Paxos之间的区别之前,我们首先来看下两者的联系. 两者都存在一个类似于Leader进程的角色,由其负责协调多个Follow进程的运行. ...

  8. 51单片机的TXD、 RXD 既接了 232 又接了 485芯片 ,会导致通信失败!

    51单片机的TXD. RXD 既接了 232 又接了 485 ,会导致通信失败! 下面是绘制电路板用的部分电路图: 通信现象: 1.我使用了USB-232的下载模块,把它接到P4上,发现单片机只能发送 ...

  9. Selenium VS Webdriver

    Selenium 是 ThroughtWorks 一个强大的基于浏览器的开源自动化测试工具,它通常用来编写 Web 应用的自动化测试.随着 Selenium 团队发布 Selenium 2(又名 We ...

  10. 写一个c程序辨别系统是16位or32位

    方法: 32位处理器就是一次只能处理32位,也就是4个字节的数据,虚拟地址空间的最大大小是4G,而64位处理一次就能处理64位,即8个字节的数据,最大虚拟地址空间的最大大小是16T.最明显的是指针大小 ...