题目来源: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. Agc011_F Train Service Planning

    先放题面,再放LHX巨佬题解 接着就是%%%.$orz.Oro.Or2.Otz.OTL.sto.rzo.Jto$.On_.○| ̄|_啊 模拟赛里直接把这道题刚掉了 一题升天·爆踩全场 这题思维跨越度已 ...

  2. ACM学习历程—HDU 3915 Game(Nim博弈 && xor高斯消元)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3915 题目大意是给了n个堆,然后去掉一些堆,使得先手变成必败局势. 首先这是个Nim博弈,必败局势是所 ...

  3. Ubuntu 14.04开发环境

    安装ssh服务:sudo apt-get install openssh-server 安装vim:sudo apt-get install vim-gtk 安装gparted:sudo apt-ge ...

  4. css 更换浏览器 默认图标

    cursor:url("./images/test.cur"),auto; 只在chrome测试过...

  5. 【转】Pro Android学习笔记(十三):用户界面和控制(1):UI开发

    目录(?)[-] UI开发 方式一通过XML文件 方式二通过代码 方式三XML代码 UI开发 先理清一些UI概念: view.widget.control:这三个名词其实没有什么区别,都是一个UI元素 ...

  6. mariadb复制

    实验环境:CentOS7 #安装mariadb-server #主数据库: [root@~ localhost]#vim /etc/my.cnf.d/server.cnf [mysqld] skip_ ...

  7. sql 查看表结构

    sqlserver 查看表结构 exec sp_help @TableName --得到表信息.字段,索引.constraint. exec sp_pkeys @TableName --得到主键. e ...

  8. K-NN回归算法

    from sklearn.datasets import load_iris import numpy as np import matplotlib.pyplot as plt iris = loa ...

  9. linux日常管理-rsync常用选项详解

    -av 同步目录 写法 123/   /tmp/333/ 意思是把123下的文件同步到/tmp/333/下  结尾不加/ 只同步目录 两个目录一样的. //////////////////////// ...

  10. strust2.2.3版本启动报错struts-plugin.xml:8:162

    我用的是struts-2.2.3,开始把全部的jar包都放进去了,可是一直报 信息: Parsing configuration file [struts-plugin.xml] 2011-6-11 ...