Codeforces Round #424 E. Cards Sorting

题目大意:给你一堆n张牌(数字可以相同),你只能从上面取牌,如果是当前牌堆里面最小的值则拿走,

否则放到底部,问你一共要操作多少次。

 

思路:讲不清楚,具体看代码。。

#include<bits/stdc++.h>
#define pb push_back
#define ll long long
using namespace std;
const int N=1e5+5;
ll n,mxi[N],a[N];//a[i]保存原始数据,mxi[i]保存大小为i的牌最下面一张的编号
vector<ll> p[N];//p[i] 保存值为i的所有牌的编号,从小到大。
ll solve()
{
    sort(a+1,a+n+1);//先从小到大排序
    ll now_n=n;//now_n表示到目前为止还剩多少张牌
    ll ans=now_n;//第一次操作取全部牌,扔掉大小为a[1]的。
    now_n-=p[a[1]].size();
    p[a[1]].clear();
    for(int i=2;i<=n;i++)//从a[2]开始
    {
        if(p[a[i]].empty()) continue;//如果这个大小的都取完了跳过。
        if(p[a[i]].back()>mxi[a[i-1]])//如果当前a[i]的最底下一个的编号大于
        {                             //a[i-1]最底下的编号,则在mxi[a[i-1]]下面的编号
                                       //在上一次取a[i-1]的时候就取掉了。
            vector<ll> ::iterator it;
            it=lower_bound(p[a[i]].begin(),p[a[i]].end(),mxi[a[i-1]]);
            ll num=p[a[i]].end()-it;
            p[a[i]].erase(it,p[a[i]].end());
            if(!p[a[i]].empty()) mxi[a[i]]=p[a[i]].back();
            now_n-=num;//减掉num为当前的牌数。
        }
        else//取出全部牌将a[i]大小的牌扔掉。
        {
            ans+=now_n;
            now_n-=p[a[i]].size();
            p[a[i]].clear();
        }
    }
    return ans;
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        scanf("%I64d",&a[i]);
        p[a[i]].pb(i);
        mxi[a[i]]=i;
    }
    ll ans=solve();
    cout<<ans<<endl;
    return 0;
}
View Code

 

posted @ 2017-07-31 16:21  NotNight  阅读(179)  评论(0编辑  收藏  举报