题目分析
$50pts:$
瞎搞就行
$80pts$
大家看到这道题,肯定第一想法是直接暴力去模拟,就是左边一个右边一个然后算到只剩两个,自以为这个复杂度是线性的,然后就会拿到 $80$ 分的好成绩,因为你每模拟一个数,到了下一个数,这个数还要再被模拟一次,这样复杂度就会退化到平方级这样的话 $10^5$ 的数据就妥妥的超时了
$100pts$
正解就是在 $80$ 分的代码上进行优化,如果我们每次按照,这个数拥有的个数去模拟的话,就可以把模拟次数控制在线性,但是这样的话,一边模拟一边计算胜利者很麻烦,所以我们到最后进行一下特判首先,如果
$n\leq2$,因为之前的循环过后还是 Mirko
先手,所以 Mirko
直接输掉了;如果 $n=3$,那么有三种情况:
- 最矮小麦的根数等于最高小麦的根数,
Mirko
是先手,所以Mirko
获胜; - 最矮小麦的根数大于最高小麦的根数,
Slavko
会先取完,所以Slavko
获胜 - 最矮小麦的根数小于最高小麦的根数,与第二种情况相反,
Slavko
会输掉。
std
#include<bits/stdc++.h>
#define int long long
const int N=100005;
using namespace std;
int n,m;
int a[N],cnt[N];//a是记录小麦高度的种类,cnt是记录每种高度的小麦根数
signed main(){
cin>>m;
for(int i=1;i<=m;i++){
int num;
cin>>num;
if(!cnt[num]) a[++n]=num;//防止a中出现重复
cnt[num]++;
}
sort(a+1,a+1+n);//对所有的高度要先进行排序,保证其单调性
int l=1,r=n;
while(n>3){/*小于等于3的时候就可以退出进行特判*/
if(cnt[a[l]]>cnt[a[r]]){
cnt[a[l]]-=cnt[a[r]];//多的要减去少的,少的不变,因为下面还要用到
cnt[a[l+1]]+=cnt[a[r]];
cnt[a[r-1]]+=cnt[a[r]];
r--,n--;
}
else if(cnt[a[l]]<cnt[a[r]]){
cnt[a[r]]-=cnt[a[l]];
cnt[a[l+1]]+=cnt[a[l]];
cnt[a[r-1]]+=cnt[a[l]];
l++,n--;
}
else{
cnt[a[l+1]]+=cnt[a[l]];
cnt[a[r-1]]+=cnt[a[r]];
l++,r--;
n-=2;
}
}
if(n<=2) cout<<"Slavko"<<endl<<a[l]<<" "<<a[r];
else{
if(cnt[a[l]]>cnt[a[r]]) cout<<"Slavko"<<endl<<a[l]<<" "<<a[l+1];
else cout<<"Mirko"<<endl<<a[r-1]<<" "<<a[r];
}//按照题目给出的三种情况进行分类讨论
return 0;
}