2017-2018 ACM-ICPC, NEERC, Moscow Subregional Contest F
阿新 • • 發佈:2018-12-22
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;
}