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

我的程序写得比较复杂了,按照每条规则为每个队伍找排名。一个处理是在计算时把排名设定为浮点数而不是整数,这样在进行插入的时候不会需要移动很多队伍的名次,最要最后整理的时候映射为整数即可。

  1 //////////////////////////////////////////////////////////////////////////
  2 //        POJ1030 Rating
  3 //        Memory: 320K        Time: 94MS
  4 //        Language: C++        Result: Accepted
  5 //////////////////////////////////////////////////////////////////////////
  6 
  7 #include <iostream>
  8 #include <stdio.h>
  9 #include <map>
 10 #include <list>
 11 
 12 using namespace std;
 13 
 14 int cnt[101];
 15 int rank1[101];
 16 int rank2[101];
 17 float rank[101];
 18 float buff[101];
 19 bool tag[101];
 20 map<int, list<int>> record1;
 21 map<int, list<int>> record2;
 22 int k1, k2;
 23 
 24 struct Rate {
 25     float rank;
 26     list<int> teams;
 27     Rate * next;
 28 };
 29 Rate * head = NULL;
 30 
 31 float compRank(Rate * a, Rate * b) {
 32     return a->rank - b->rank;
 33 }
 34 bool cmp(const void * a, const void * b) {
 35     return *(int *)a > *(int *)b ? true : false; 
 36 }
 37 void exchangeRank(Rate *a, Rate * b) {
 38     float rank = a->rank;
 39     list<int> teams = a->teams;
 40     a->rank = b->rank;
 41     a->teams = b->teams;
 42     b->rank = rank;
 43     b->teams = teams;
 44 }
 45 void sortRank() {
 46     if (head == NULL || head->next == NULL) {
 47         return;
 48     }
 49     Rate * key = head->next;
 50     Rate * p = head;
 51     while (key != NULL) {
 52         while (p != key) {
 53             if (compRank(p, key) > 0) {
 54                 exchangeRank(p, key);
 55             }
 56             p = p->next;
 57         }
 58         p = head;
 59         key = key->next;
 60     }
 61 }
 62 void readData() {
 63     char buf[10000];
 64     int teamId;
 65     int teamCnt;
 66     char * pCur;
 67     int rankSum = 0;
 68     int rankCur = 0;
 69 
 70     gets(buf);
 71     sscanf(buf, "%d", &k1);
 72     for (int i = 0; i < k1; ++i) {
 73         gets(buf);
 74         rankCur = rankSum + 1;
 75         pCur = strtok(buf, " ");
 76         list<int> ts;
 77         while (pCur) {
 78             ++rankSum;
 79             teamId = atoi(pCur);
 80             ++cnt[teamId];
 81             rank1[teamId] = rankCur;
 82             ts.push_back(teamId);
 83             pCur = strtok(NULL, " ");
 84         }
 85         record1[rankCur] = ts;
 86     }
 87     getchar();
 88     gets(buf);
 89     sscanf(buf, "%d", &k2);
 90     rankSum = rankCur = 0;
 91     for (int i = 0; i < k2; ++i) {
 92         gets(buf);
 93         rankCur = rankSum + 1;
 94         pCur = strtok(buf, " ");
 95         list<int> ts;
 96         while (pCur) {
 97             ++rankSum;
 98             teamId = atoi(pCur);
 99             ++cnt[teamId];
100             rank2[teamId] = rankCur;
101             ts.push_back(teamId);
102             pCur = strtok(NULL, " ");
103         }
104         record2[rankCur] = ts;
105     }
106 }
107 
108 void cc2() {
109     for (int i = 1; i <= 100; ++i) {
110         if (cnt[i] == 2) {
111             rank[i] = rank1[i] + rank2[i];
112         }
113     }
114     for (int i = 1; i <= 200; ++i) {
115         Rate * rate = new Rate;
116         rate->rank = i;
117         for (int j = 1; j <= 100; ++j) {
118             if (rank[j] == i) {
119                 rate->teams.push_back(j);
120             }
121         }
122         if (!rate->teams.empty()) {
123             rate->next = head;
124             head = rate;
125         }
126     }
127 }
128 
129 void cc1() {
130     for (int i = 1; i <= 100; ++i) {
131         if (cnt[i] != 1) {
132             continue;
133         }
134         int r;
135         int p;
136         if (rank1[i] != 0) {
137             r = rank1[i];
138             p = 1;
139         } else {
140             r = rank2[i];
141             p = 2;
142         }
143         int count = 0;
144         list<int> temp;
145         if (p == 1) {
146             temp = record1[r];
147         } else {
148             temp = record2[r];
149         }
150         list<int> eq;
151         for (list<int>::iterator it = temp.begin(); it != temp.end(); ++it) {
152             if (cnt[*it] == 2) {
153                 eq.push_back(*it);
154             }    
155         }
156         if (!eq.empty()) {
157             int rc = rank[eq.front()];
158             bool flag = true;
159             for (list<int>::iterator it = eq.begin(); it != eq.end(); ++it) {
160                 if (rank[*it] != rc) {
161                     rank[i] = 0;
162                     flag = false;
163                     break;
164                 }
165             }
166             if (flag == true) {
167                 for (Rate * p = head; p != NULL; p = p->next) {
168                     if (p->rank == rc) {
169                         p->teams.push_back(i);
170                         break;
171                     }
172                 }
173             }
174         } else {
175             tag[i] = true;
176         }
177     }
178     for (int i = 1; i <= 100; ++i) {
179         if (tag[i] != true) {
180             continue;
181         }
182         int p; 
183         int r;
184         if (rank1[i] != 0) {
185             r = rank1[i];
186             p = 1;
187         } else {
188             r = rank2[i];
189             p = 2;
190         }
191         int * temp = (p == 1) ? rank1 : rank2;
192         int prior = -1;
193         int next = 101;
194         for (int j = 1; j <= 100; ++j) {
195             if (temp[j] != 0 && temp[j] < r && rank[j] != 0) {
196                 if (rank[j] > prior) {
197                     prior = rank[j];
198                 }
199             }
200             if (temp[j] != 0 && temp[j] > r && rank[j] != 0) {
201                 if (rank[j] < next) {
202                     next = rank[j];
203                 }
204             }
205 
206         }
207         if (next > prior) {
208             buff[i] = (next + prior) / 2.0;
209         }
210     }
211 }
212 
213 void insertcc1() {
214     for (int i = 1; i <= 100; ++i) {
215         if (buff[i] == 0) {
216             continue;
217         }
218         float fr = buff[i];
219         Rate * p = head;
220         Rate * rate = new Rate;
221         rate->rank = fr;
222         rate->teams.push_back(i);
223         if (head == NULL || fr < head->rank) {
224             rate->next = head;
225             head = rate;
226             continue;
227         } else if (fr == head->rank) {
228             int t1 = rank1[i] > 0 ? rank1[i] :rank2[i];
229             int t2 = rank1[head->teams.front()] > 0 ?rank1[head->teams.front()] : rank2[head->teams.front()]; 
230             if (t1 == t2) {
231                 head->teams.push_back(i);
232                 continue;
233             } else if (t1 < t2) {
234                 rate->next = head;
235                 head = rate;
236                 continue;
237             }
238         }
239         Rate * q = p->next;
240         bool f = false;
241         while(q != NULL) {
242             if (fr < q->rank) {
243                 rate->next = q;
244                 p->next = rate;
245                 f = true;
246                 break;
247             } else if (fr == q->rank) {
248                 int t1 = rank1[i] > 0 ? rank1[i] :rank2[i];
249                 int t2 = rank1[q->teams.front()] > 0 ?rank1[q->teams.front()] : rank2[q->teams.front()]; 
250                 if (t1 == t2) {
251                     q->teams.push_back(i);
252                 } else if (t1 < t2) {
253                     rate->next = q;
254                     p->next = rate;
255                 } else {
256                     if (q->next == NULL) {
257                         rate->next = q->next;
258                         q->next = rate;
259                     } else{
260                         int t3 = rank1[q->next->teams.front()] > 0 ? rank1[q->next->teams.front()] : rank2[q->next->teams.front()];
261                         if (t3 > t1) {
262                             rate->next = q->next;
263                             q->next = rate;
264                         } else {
265                             p = p->next;
266                             q = q->next;
267                             continue;
268                         }
269                     }
270                 }
271                 f = true;
272                 break;
273             }
274             p = p->next;
275             q = q->next;
276         }
277         if (f == true) {
278             continue;
279         }
280         rate->next = NULL;
281         p->next = rate;
282     }
283 }
284 void output() {
285     for (Rate * p = head; p != NULL; p = p->next) {
286         p->teams.sort();
287         for (list<int>::iterator it = p->teams.begin(); it != p->teams.end(); ++it) {
288             if (*it != p->teams.back()) {
289                 cout << *it << " ";
290             } else {
291                 cout << *it;
292                 if (p->next != NULL) {
293                     cout << endl;
294                 }
295             }
296         }
297     }
298 }
299 int main () {
300     readData();
301     cc2();
302     sortRank();
303     cc1();
304     insertcc1();
305     output();
306     system("pause");
307     return 0;
308 }
View Code

必须承认代码写得很拙劣,不过思路还是能看得比较清晰吧。

 

 

 

posted @ 2013-08-01 00:08  小菜刷题史  阅读(406)  评论(0编辑  收藏  举报