ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

UVA-1609 不公平竞赛 题解答案代码 算法竞赛入门经典第二版

UVA-1609 不公平竞赛 题解答案代码 算法竞赛入门经典第二版 GitHub - jzplp/aoapc-UVA-Answer: 算法竞赛入门经典 例题和习题答案 刘汝佳 第二版题目实际上就是这个队伍能打过超过一半的队伍且没有绝对的胜者。要求找一个合适的安排使这个队伍可以最终获胜。方法采用算法竞赛入门经典书中的方法如果让我自己想可能比较困难或者想不出来。设1号队伍可以打败的队伍为白色队伍不可以直接打败的为黑色队伍。方法分为四步1. 消灭可以直接消灭的黑色队伍进行比赛。2. 对1号队伍选一个可以肯定打败的队伍进行比赛。3. 所有剩下的黑色队伍互相比赛。4. 所有剩下的其余队伍互相比赛。注意步骤3中可能剩下一个黑色队伍没有参加过此时要加进这里来比赛。每轮比赛时取出一般的队伍这样O(logn)的轮次就能找到第一名。但有了方法还是超时。一开始我完全使用数组实现使用两个标记数组表示剩下的队伍与本轮未参加过还剩下的队伍。每次遍历整个队伍来查找。这样一个轮次需要n^2整个需要O(n^2logn) 超时。我发现遍历本轮次剩下的队伍时没有使用随机存取而是仅使用顺序查找。这样把本轮没有参加过的队伍用一个链表表示由于每轮这个链表长度都减小一半因此花费时间依次为n^2 (n/2)^2 (n/4)^2 ... n^2 n^2/4 n^2/16 ... O(n^2)虽然时间减少了很多但还是超时。然后我发现黑色队伍和白色队伍在方法中一般都是分开统计的因此分为两个链表单独计算。这样就没有遍历整个长度的机会。因此花费时间依次为(n/2)^2 (n/4)^2 ... n^2/4 n^2/16 ... O(n^2)虽然还是O(n^2)但实际上去掉了最前面的运算且最终只需要第一步是n^2的计算量。时间消耗明显减少。最终两个链表的方法AC了。AC代码#include stdio.h #include string.h #include list #define MAXN 1030 using namespace std; int group[MAXN][MAXN]; int used[MAXN]; int n; listint lsb, lsw; int history[MAXN * MAXN][2]; int hisn; bool judge() { int i; for (i 2; i n; i) if (!used[i]) return false; return true; } void beat(listint l1, listint::iterator it, listint l2, listint::iterator it2) { if (group[*it][*it2]) used[*it2] 1; else used[*it] 1; history[hisn][0] *it; history[hisn][1] *it2; hisn; it l1.erase(it); // 避免删除it2后it也不存在了 if (l1 l2 it it2) { it2 l2.erase(it2); it it2; } else { it2 l2.erase(it2); } } void computed() { listint::iterator it3; bool flag; // 第一步消灭所有直接消灭的黑色 for (auto it lsb.begin(); it ! lsb.end();) { flag false; for (auto it2 lsw.begin(); it2 ! lsw.end();) { if (group[*it][*it2]) { it2; continue; } beat(lsb, it, lsw, it2); flag true; break; } if (!flag) it; } // 第二步 1和另一个 if (lsw.size() 0) { auto it lsw.begin(); used[*it] 1; history[hisn][0] 1; history[hisn][1] *it; hisn; it lsw.erase(it); } // 第三步 黑黑对决 for (auto it lsb.begin(); it ! lsb.end();) { it3 it; if (it ! lsb.end()) beat(lsb, it3, lsb, it); } // 第四步 剩下混战 for (auto it lsw.begin(); it ! lsw.end();) { it3 it; if (it ! lsw.end()) beat(lsw, it3, lsw, it); } if (lsw.size() 0 lsb.size() 0) { auto it lsb.begin(), it2 lsw.begin(); beat(lsw, it, lsb, it2); } } int main() { int i, j; char c; while (scanf(%d, n) 0) { for (i 1; i n; i) { getchar(); for (j 1; j n; j) { scanf(%c, c); group[i][j] c - 0; } } memset(used, 0, sizeof(used)); memset(history, 0, sizeof(history)); hisn 0; while (1) { lsb.clear(); lsw.clear(); for (i 2; i n; i) { if (used[i]) continue; if (group[1][i]) lsw.push_back(i); else lsb.push_back(i); } computed(); if (judge()) break; } for (i 0; i hisn; i) { printf(%d %d\n, history[i][0], history[i][1]); } // putchar(\n); } return 0; }
返回列表