2017-2018 ACM-ICPC, NEERC, Moscow Subregional Contest F - Fake or Leak? [Gym/101611]

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/z591826160/article/details/84205509

F - Fake or Leak? [Gym/101611]

题面

在这里插入图片描述

思路

算是需要小贪心的模拟题吧
如果输入输出简单一点 可能就是一个铜牌的签到题吧
对于一个不在给定终榜的队伍,如果他能滚榜到给定终榜的第一个人上面,那就让他上去,不然就让他留在原地,这样是最能满足条件的情况了
然后只需要按照情况模拟即可。

(占机子写模拟之前还是要想好怎么写再上 一来写的简洁不容易崩 二来确定好写法别占用太多机时 看到其他博客貌似很少有这个题的代码 就贴上来了 )

题解

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn=30;
int n,k,m;
int frozen=0,fin=1;
struct team{
    string name;
    bool solved[maxn];
    int lastsub[maxn];
    int penalty[maxn];
    int submited[maxn];
    int totsolved,totpenalty,totlast;
    void update(){
        totsolved=totpenalty=totlast=0;
        for(int i=0;i<n;i++){
            if(solved[i]){
                totsolved++;
                totpenalty+=lastsub[i]+20*(submited[i]-1);
                totlast=max(totlast,lastsub[i]);
            }
        }
    }
    bool operator <(const team &b)const{
        if(totsolved!=b.totsolved)
            return totsolved>b.totsolved;
        if(totpenalty!=b.totpenalty)
            return totpenalty<b.totpenalty;
        if(totlast!=b.totlast)
            return totlast<b.totlast;
        return name<b.name;
    }
}Rank[2][2000];
void read(){
    cin>>n>>m>>k;
    for(int i=0;i<m;i++){
        cin>>Rank[frozen][i].name;
        for(int j=0;j<n;j++){
            string op;
            int a,t;
            cin>>op>>a>>t;
            if(op[0]=='+'){
                Rank[frozen][i].solved[j]=true;
                Rank[frozen][i].lastsub[j]=t;
                Rank[frozen][i].submited[j]=a;
            } else if(op[0]=='-'){
                Rank[frozen][i].lastsub[j]=t;
                Rank[frozen][i].submited[j]=a;
            } 
        }
    }
    for(int i=0;i<k;i++){
        cin>>Rank[fin][i].name;
        for(int j=0;j<n;j++){
            string op;
            int a,t;
            cin>>op>>a>>t;
            if(op[0]=='+'){
                Rank[fin][i].solved[j]=true;
                Rank[fin][i].lastsub[j]=t;
                Rank[fin][i].submited[j]=a;
            } else if(op[0]=='-'){
                Rank[fin][i].lastsub[j]=t;
                Rank[fin][i].submited[j]=a;
            } 
        }
    }
}

void canbigger(team &a,const team b){
    team tmp = a;
    for(int i=0;i<n;i++)
        if(!a.solved[i]&&!a.submited[i]){
            a.solved[i]=true;
            a.lastsub[i]=240;
            a.submited[i]=1;
        } else if(!a.solved[i]){
            a.solved[i]=true;
            a.lastsub[i]=240;
            a.submited[i]++;
        }
    a.update();
    if(b.totsolved==n){
        if(a.totpenalty>b.totpenalty){
            a=tmp;
            return ;
        }
        if(a.totpenalty==b.totpenalty)
            if(a.totlast>b.totlast){
                a=tmp;
                return ;
            }
        if(a.totpenalty==b.totpenalty)
            if(a.totlast==b.totlast)
                if(a.name>b.name){
                    a=tmp;
                    return ;
                }
    }
}
void solve(){
    for(int i=0;i<m;i++)Rank[frozen][i].update();
    for(int i=0;i<k;i++)Rank[fin][i].update();
    for(int i=0;i<m;i++){
        bool in=false;
        for(int j=0;j<k;j++)
            if(Rank[frozen][i].name==Rank[fin][j].name)
                in=true;
        if(!in)
            canbigger(Rank[frozen][i],Rank[fin][0]);
    }
}
void merge(){
    for(int i=0;i<m;i++)
        for(int j=0;j<k;j++)
            if(Rank[frozen][i].name==Rank[fin][j].name)
                Rank[frozen][i]=Rank[fin][j];
}
int main(){
    ios::sync_with_stdio(false);
    read();
    solve();
    merge();
    sort(Rank[frozen],Rank[frozen]+m);
    int pos=0;
    /*cout<<"NicoNicoNi"<<endl;
    for(int i=0;i<m;i++){
        cout<<Rank[frozen][i].name<<" "<<Rank[frozen][i].totsolved<<" "<<Rank[frozen][i].totlast<<endl;
    }*/
    for(int i=0;i<m;i++)
        if(Rank[frozen][i].name==Rank[fin][0].name){
            pos=i;
            break;
        }
    bool ans=true;
    if(pos+k-1<m)
        for(int i=pos;i<pos+k;i++)
            if(Rank[frozen][i].name!=Rank[fin][i-pos].name)
                ans=false;
    if(pos+k-1>=m)
        ans=false;
    if(ans)
        cout<<"Leaked"<<endl;
    else 
        cout<<"Fake"<<endl;
}

猜你喜欢

转载自blog.csdn.net/z591826160/article/details/84205509