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\n",ans); } return 0; }