1. 程式人生 > >2017-2018 ACM-ICPC, NEERC, Moscow Subregional Contest F - Fake or Leak? [Gym/101611]

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

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; }