Codeforces Round #558 (Div. 2)-Cat Party (Hard Edition)-(前缀和 + 模拟)

http://codeforces.com/problemset/problem/1163/B2

题意:有n天,每天有一个颜色,截取前x天,随便抽掉一天,使剩下的各个颜色出现的次数相等。

解题,也可以解决B1:

有三种情况:

1.一种颜色出项一次,其他相等,抽掉出现1次颜色的那一天,例如13天分别是

6 222 333 444 555

2.只有两种颜色次数,次数相差1,并且最大出现次数的颜色只有1次,例如13天分别是

777 333 222 8888

3.所有颜色都只出现过1次,例如

1 2 3 4 5 6 7 8 9 

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<string>
#include<vector>
#include<iostream>
#include<map>
#include<cstring>
#include<set>
#include<queue>
#define inf 0x3f3f3f3f
#define ll long long
using namespace std;

int a[200086];///每一天的颜色
int color[200086];///下标颜色出现的次数
int n;


int main()///cf558div2B
{
    while(scanf("%d",&n)!=EOF)
    {
        memset(a,0,sizeof(a));
        memset(color,0,sizeof(color));
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        int sum=0;/// 一共出现几种颜色
        int maxx=-1,ans=0;///最大次数 答案
        int one=0; ///特判颜色次数为1的颜色数量
        set<int>se;///判断当前颜色是否出现过
        map<int,int>mp;///快速找到最大次数的颜色数
        for(int i=1;i<=n;i++)
        {
            if( !se.count(a[i]) )
            {
                sum++;
                se.insert(a[i]);
            }
            color[ a[i] ]++;
            mp[ color[ a[i] ] ]++;///每一次都累加,最后只需要用到maxx和maxx-1

            if( color[ a[i] ]==1 )
                one++;
            else if( color[ a[i] ]==2 )///颜色出现的次数超过1自然会先变成2,并且回不来了
                one--;

            if( color[ a[i] ] > maxx )
                maxx=color[  a[i] ];

            if( mp[maxx]==1 && mp[maxx-1]==sum )
                ans=i;
            if( mp[maxx]==sum-1 && one==1 )
                ans=i;
            if(maxx==1 && mp[maxx]==sum)
                ans=i;
        }
        printf("%d
",ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/shoulinniao/p/10860898.html