team2012-E1-mysol-0022

从 Trac 迁移的文章

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

原文章内容如下:

{{{
/* 解题报告 //

给出足球比赛的规则,某些队伍之间两两的比分,以及一个联赛积分榜
使用题目给出的这些信息,计算出这些队伍的最终排名

没啥好说的,理解了规则就行,顺便可以练练 STL
挺不错的一道题,主要考察基本功,这种风格的题最喜欢了

// By 猛犸也钻地 @ 2012.07.26 */
}}}

{{{
#include <cstdio>
#include <vector>
#include <string>
#include <map>
#include <cstring>
#include <algorithm>
using namespace std;

map<string,int> idx;
map<int,string> rev;

typedef pair<string,int> PSI;

int getidx(const char* s){
    map<string,int>::iterator u=idx.find(s);
    if(u==idx.end()) u=idx.insert(PSI(s,idx.size())).first;
    return u->second;
}

int n,m,a[500][500],all;
int pt[500],df[500],in[500],rk[500],at[500];
vector<int> ans;

bool cmp(int x, int y){
    if(pt[x]!=pt[y]) return pt[x]>pt[y];
    if(df[x]!=df[y]) return df[x]>df[y];
    if(in[x]!=in[y]) return in[x]>in[y];
    return all && rk[x]<rk[y];
}

void gao(vector<int> u){
    int n=u.size();
    for(int i=0;i<n;i++) pt[u[i]]=df[u[i]]=in[u[i]]=0;
    for(int i=0;i<n;i++) for(int j=0;j<i;j++){
        int x=u[i],y=u[j];
        int cx=a[x][y];
        int cy=a[y][x];
        df[x]+=cx-cy;
        df[y]+=cy-cx;
        in[x]+=cx;
        in[y]+=cy;
        if(cx>cy) pt[x]+=3;
        if(cx<cy) pt[y]+=3;
        if(cx==cy) pt[x]++,pt[y]++;
    }
    sort(u.begin(),u.end(),cmp);
    if(!cmp(u[0],u[n-1]) && !cmp(u[n-1],u[0])){
        all=1; sort(u.begin(),u.end(),cmp); all=0;
        ans.insert(ans.end(),u.begin(),u.end());
    }else{
        vector<int> o;
        for(int i=0;i<n;i++){
            o.push_back(u[i]);
            if(i==n-1 || cmp(u[i],u[i+1])) gao(o),o.clear();
        }
    }
}

int main(){
    int cs=0,n,m;
    while(scanf("%d",&n)==1){
        ans.clear();
        idx.clear();
        rev.clear();
        memset(pt,0,sizeof(pt));
        memset(df,0,sizeof(df));
        memset(in,0,sizeof(in));
        for(int i=0;i<n;i++) for(int j=0;j<i;j++){
            int cx,cy,x,y;
            char sx[50],sy[50];
            scanf("%s%d:%d%s",sx,&cx,&cy,sy);
            x=getidx(sx);
            y=getidx(sy);
            df[x]+=cx-cy;
            df[y]+=cy-cx;
            in[x]+=a[x][y]=cx;
            in[y]+=a[y][x]=cy;
            if(cx>cy) pt[x]+=3;
            if(cx<cy) pt[y]+=3;
            if(cx==cy) pt[x]++,pt[y]++;
        }
        for(map<string,int>::iterator u=idx.begin();u!=idx.end();++u)
            rev[u->second]=u->first;
        scanf("%d",&m);
        for(int i=0;i<m;i++){
            char s[100];
            scanf("%s",s);
            map<string,int>::iterator u=idx.find(s);
            if(u!=idx.end()) rk[u->second]=i;
        }
        for(int i=0;i<n;i++) at[i]=i;
        all=1; sort(at,at+n,cmp); all=0;
        for(int i=0;i<n;i++) rk[at[i]]=i;
        vector<int> o;
        for(int i=0;i<n;i++){
            o.push_back(at[i]);
            if(i==n-1 || pt[at[i]]>pt[at[i+1]]) gao(o),o.clear();
        }
        if(cs++) puts("");
        for(int i=0;i<n;i++) printf("%s\n",rev[ans[i]].c_str());
    }
}
}}}
/* 解题报告 //
给出足球比赛的规则,某些队伍之间两两的比分,以及一个联赛积分榜
使用题目给出的这些信息,计算出这些队伍的最终排名
没啥好说的,理解了规则就行,顺便可以练练 STL
挺不错的一道题,主要考察基本功,这种风格的题最喜欢了
// By 猛犸也钻地 @ 2012.07.26 */
#include <cstdio>
#include <vector>
#include <string>
#include <map>
#include <cstring>
#include <algorithm>
using namespace std;
map<string,int> idx;
map<int,string> rev;
typedef pair<string,int> PSI;
int getidx(const char* s){
    map<string,int>::iterator u=idx.find(s);
    if(u==idx.end()) u=idx.insert(PSI(s,idx.size())).first;
    return u->second;
}
int n,m,a[500][500],all;
int pt[500],df[500],in[500],rk[500],at[500];
vector<int> ans;
bool cmp(int x, int y){
    if(pt[x]!=pt[y]) return pt[x]>pt[y];
    if(df[x]!=df[y]) return df[x]>df[y];
    if(in[x]!=in[y]) return in[x]>in[y];
    return all && rk[x]<rk[y];
}
void gao(vector<int> u){
    int n=u.size();
    for(int i=0;i<n;i++) pt[u[i]]=df[u[i]]=in[u[i]]=0;
    for(int i=0;i<n;i++) for(int j=0;j<i;j++){
        int x=u[i],y=u[j];
        int cx=a[x][y];
        int cy=a[y][x];
        df[x]+=cx-cy;
        df[y]+=cy-cx;
        in[x]+=cx;
        in[y]+=cy;
        if(cx>cy) pt[x]+=3;
        if(cx<cy) pt[y]+=3;
        if(cx==cy) pt[x]++,pt[y]++;
    }
    sort(u.begin(),u.end(),cmp);
    if(!cmp(u[0],u[n-1]) && !cmp(u[n-1],u[0])){
        all=1; sort(u.begin(),u.end(),cmp); all=0;
        ans.insert(ans.end(),u.begin(),u.end());
    }else{
        vector<int> o;
        for(int i=0;i<n;i++){
            o.push_back(u[i]);
            if(i==n-1 || cmp(u[i],u[i+1])) gao(o),o.clear();
        }
    }
}
int main(){
    int cs=0,n,m;
    while(scanf("%d",&n)==1){
        ans.clear();
        idx.clear();
        rev.clear();
        memset(pt,0,sizeof(pt));
        memset(df,0,sizeof(df));
        memset(in,0,sizeof(in));
        for(int i=0;i<n;i++) for(int j=0;j<i;j++){
            int cx,cy,x,y;
            char sx[50],sy[50];
            scanf("%s%d:%d%s",sx,&cx,&cy,sy);
            x=getidx(sx);
            y=getidx(sy);
            df[x]+=cx-cy;
            df[y]+=cy-cx;
            in[x]+=a[x][y]=cx;
            in[y]+=a[y][x]=cy;
            if(cx>cy) pt[x]+=3;
            if(cx<cy) pt[y]+=3;
            if(cx==cy) pt[x]++,pt[y]++;
        }
        for(map<string,int>::iterator u=idx.begin();u!=idx.end();++u)
            rev[u->second]=u->first;
        scanf("%d",&m);
        for(int i=0;i<m;i++){
            char s[100];
            scanf("%s",s);
            map<string,int>::iterator u=idx.find(s);
            if(u!=idx.end()) rk[u->second]=i;
        }
        for(int i=0;i<n;i++) at[i]=i;
        all=1; sort(at,at+n,cmp); all=0;
        for(int i=0;i<n;i++) rk[at[i]]=i;
        vector<int> o;
        for(int i=0;i<n;i++){
            o.push_back(at[i]);
            if(i==n-1 || pt[at[i]]>pt[at[i+1]]) gao(o),o.clear();
        }
        if(cs++) puts("");
        for(int i=0;i<n;i++) printf("%s\n",rev[ans[i]].c_str());
    }
}