team2012-F3-sol-0022

从 Trac 迁移的文章

这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。

原文章内容如下:

{{{
题意:一个小组有n支队伍,两两之间进行一场球赛,现在知道每场的结果和排名规则,求最后的排名
规则英文写的好坑啊。。到最后才发现题意理解错了-_-##
规则按优先顺序:
s) 首先按照分数排序,每场赢者得3分,平则各一分
a) 按照平分的队伍集合中两两之间的比赛获得的分数排序
b) 按这个集合中比赛获得的净胜球的累积排序。。不是最大一场净胜球。。-_-###
c) 按这个集合中比赛的进球数排序
d) 对于tie的情况反复应用abc直到没作用
e) 按总净胜球的累积排序。。不是最大一场净胜球。。-_-###
f) 按总进球数排序
g) 按一个ranklist排序
解法:递归排序即可。。
}}}
{{{
#include <iostream>
#include <map>
#include <cstring>
#include <algorithm>
#include <sstream>
using namespace std;

const int MAXN = 505;
map<string, int> num;
bool vis[MAXN][MAXN];
string s1, s2, s3;
int n, m, score[MAXN], diff[MAXN][MAXN], goal[MAXN][MAXN], rank[MAXN];
int lst[MAXN], pts[MAXN][MAXN], e_diff[MAXN], e_goal[MAXN], e_pts[MAXN];
int t_goal[MAXN], t_diff[MAXN], tot;
string name[MAXN];

int get_n(string& s)
{
    if(num[s] == 0)
    {
        num[s] = ++tot;
        name[tot] = s;
    }
    return num[s];
}

void init()
{
    int a = get_n(s1),
        b = get_n(s3),
        ga, gb;
    for(int i=0;i<s2.size();i++)
        if(s2[i] == ':')
            s2[i] = ' ';
    istringstream in(s2);
    in>>ga>>gb;

    if(ga > gb)
    {
        pts[a][b] = 3;
        pts[b][a] = 0;
    }
    if(gb > ga)
    {
        pts[b][a] = 3;
        pts[a][b] = 0;
    }
    if(ga == gb)
        pts[a][b] = pts[b][a] = 1;

    score[a] += pts[a][b];
    score[b] += pts[b][a];
    goal[a][b] = ga;
    goal[b][a] = gb;
    diff[a][b] = ga-gb;
    diff[b][a] = gb-ga;
    t_goal[a] += ga;
    t_goal[b] += gb;
    t_diff[a] += diff[a][b];
    t_diff[b] += diff[b][a];
}

bool abc(int a, int b)
{
    if(e_pts[a] != e_pts[b])    return e_pts[a] > e_pts[b];
    if(e_diff[a] != e_diff[b])   return e_diff[a] > e_diff[b];
    return e_goal[a] > e_goal[b];
}

bool efg(int a, int b)
{
    if(t_diff[a] != t_diff[b])   return t_diff[a] > t_diff[b];
    if(t_goal[a] != t_goal[b])   return t_goal[a] > t_goal[b];
    return rank[a] > rank[b];
}

bool sco(int a, int b)
{
    return score[a] > score[b];
}

void gao(int l, int r)
{
    if(vis[l][r])
    {
        sort(lst+l, lst+r+1, efg);
        return;
    }
    vis[l][r] = 1;
    for(int i=l;i<=r;i++)
    {
        int a = lst[i];
        e_pts[a] = e_diff[a] = e_goal[a] = 0;
    }
    for(int i=l;i<=r;i++)
        for(int j=l;j<=r;j++)
        {
            int a = lst[i], b = lst[j];
            if(a != b)
            {
                e_pts[a] += pts[a][b];
                e_diff[a] += diff[a][b];
                e_goal[a] += goal[a][b];
            }
        }
    sort(lst+l, lst+r+1, abc);
    while(l < r)
    {
        int p = l;
        while(p+1<=r && abc(lst[l], lst[p+1])==0)   p++;
        if(p > l)   gao(l, p);
        l = p+1;
    }
}

int main()
{
    int cs = 0;
    while(cin>>n)
    {
        if(cs++)    cout<<endl;
        num.clear();
        tot = 0;
        memset(score, 0, sizeof(score));
        memset(t_goal, 0, sizeof(t_goal));
        memset(t_diff, 0, sizeof(t_diff));

        for(int i=1;i<=n*(n-1)/2;i++)
        {
            cin>>s1>>s2>>s3;
            init();
        }
        cin>>m;
        for(int i=1;i<=m;i++)
        {
            cin>>s1;
            rank[num[s1]] = m-i+1;
        }

        for(int i=1;i<=n;i++)   lst[i] = i;
        sort(lst+1, lst+n+1, sco);
        memset(vis, 0, sizeof(vis));
        int l = 1;
        while(l < n)
        {
            int p = l;
            while(p+1<=n && sco(lst[l], lst[p+1])==0)   p++;
            if(p > l)   gao(l, p);
            l = p+1;
        }

        for(int i=1;i<=n;i++)
            cout<<name[lst[i]]<<endl;
    }
    return 0;
}
}}}
题意:一个小组有n支队伍,两两之间进行一场球赛,现在知道每场的结果和排名规则,求最后的排名
规则英文写的好坑啊。。到最后才发现题意理解错了-_-##
规则按优先顺序:
s) 首先按照分数排序,每场赢者得3分,平则各一分
a) 按照平分的队伍集合中两两之间的比赛获得的分数排序
b) 按这个集合中比赛获得的净胜球的累积排序。。不是最大一场净胜球。。-_-###
c) 按这个集合中比赛的进球数排序
d) 对于tie的情况反复应用abc直到没作用
e) 按总净胜球的累积排序。。不是最大一场净胜球。。-_-###
f) 按总进球数排序
g) 按一个ranklist排序
解法:递归排序即可。。
#include <iostream>
#include <map>
#include <cstring>
#include <algorithm>
#include <sstream>
using namespace std;
const int MAXN = 505;
map<string, int> num;
bool vis[MAXN][MAXN];
string s1, s2, s3;
int n, m, score[MAXN], diff[MAXN][MAXN], goal[MAXN][MAXN], rank[MAXN];
int lst[MAXN], pts[MAXN][MAXN], e_diff[MAXN], e_goal[MAXN], e_pts[MAXN];
int t_goal[MAXN], t_diff[MAXN], tot;
string name[MAXN];
int get_n(string& s)
{
    if(num[s] == 0)
    {
        num[s] = ++tot;
        name[tot] = s;
    }
    return num[s];
}
void init()
{
    int a = get_n(s1),
        b = get_n(s3),
        ga, gb;
    for(int i=0;i<s2.size();i++)
        if(s2[i] == ':')
            s2[i] = ' ';
    istringstream in(s2);
    in>>ga>>gb;
    if(ga > gb)
    {
        pts[a][b] = 3;
        pts[b][a] = 0;
    }
    if(gb > ga)
    {
        pts[b][a] = 3;
        pts[a][b] = 0;
    }
    if(ga == gb)
        pts[a][b] = pts[b][a] = 1;
    score[a] += pts[a][b];
    score[b] += pts[b][a];
    goal[a][b] = ga;
    goal[b][a] = gb;
    diff[a][b] = ga-gb;
    diff[b][a] = gb-ga;
    t_goal[a] += ga;
    t_goal[b] += gb;
    t_diff[a] += diff[a][b];
    t_diff[b] += diff[b][a];
}
bool abc(int a, int b)
{
    if(e_pts[a] != e_pts[b])    return e_pts[a] > e_pts[b];
    if(e_diff[a] != e_diff[b])   return e_diff[a] > e_diff[b];
    return e_goal[a] > e_goal[b];
}
bool efg(int a, int b)
{
    if(t_diff[a] != t_diff[b])   return t_diff[a] > t_diff[b];
    if(t_goal[a] != t_goal[b])   return t_goal[a] > t_goal[b];
    return rank[a] > rank[b];
}
bool sco(int a, int b)
{
    return score[a] > score[b];
}
void gao(int l, int r)
{
    if(vis[l][r])
    {
        sort(lst+l, lst+r+1, efg);
        return;
    }
    vis[l][r] = 1;
    for(int i=l;i<=r;i++)
    {
        int a = lst[i];
        e_pts[a] = e_diff[a] = e_goal[a] = 0;
    }
    for(int i=l;i<=r;i++)
        for(int j=l;j<=r;j++)
        {
            int a = lst[i], b = lst[j];
            if(a != b)
            {
                e_pts[a] += pts[a][b];
                e_diff[a] += diff[a][b];
                e_goal[a] += goal[a][b];
            }
        }
    sort(lst+l, lst+r+1, abc);
    while(l < r)
    {
        int p = l;
        while(p+1<=r && abc(lst[l], lst[p+1])==0)   p++;
        if(p > l)   gao(l, p);
        l = p+1;
    }
}
int main()
{
    int cs = 0;
    while(cin>>n)
    {
        if(cs++)    cout<<endl;
        num.clear();
        tot = 0;
        memset(score, 0, sizeof(score));
        memset(t_goal, 0, sizeof(t_goal));
        memset(t_diff, 0, sizeof(t_diff));
        for(int i=1;i<=n*(n-1)/2;i++)
        {
            cin>>s1>>s2>>s3;
            init();
        }
        cin>>m;
        for(int i=1;i<=m;i++)
        {
            cin>>s1;
            rank[num[s1]] = m-i+1;
        }
        for(int i=1;i<=n;i++)   lst[i] = i;
        sort(lst+1, lst+n+1, sco);
        memset(vis, 0, sizeof(vis));
        int l = 1;
        while(l < n)
        {
            int p = l;
            while(p+1<=n && sco(lst[l], lst[p+1])==0)   p++;
            if(p > l)   gao(l, p);
            l = p+1;
        }
        for(int i=1;i<=n;i++)
            cout<<name[lst[i]]<<endl;
    }
    return 0;
}