这个题最后没过,全场只过了3个人,然后好多人包括我都是得了90分,我一直不知道问题在哪,哪组数据把我HACK了呢?求大犇指点一下小弟。。。
说一下我的思路,先给输入数据按照时间排个序,然后,根据时间的流逝,维护一个MIN和MAX,分别代表集合S里的最小值,和不在集合里的人的最大值。最大值比较容易维护,直接max就行了,但是最小值,不太好搞,因为初值都是0,为了解决这个问题,我用了一个ticket数组存了一下:S集合内的人得票数是i的人的个数,ticket[0]=K,一开始有K个人得0票,然后每次发生票数变化,就对这个数组进行修改,MIN值一开始是0,当ticket[MIN]=0的时候,MIN就+1。。。。。乱搞一通,一直是WA,90/100
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <bits/stdc++.h>
using namespace std;
int N,K;
struct node{
int t,c;
node(){}
node(int T,int C){
t=T;
c=C;
}
friend bool operator<(const node&a,const node&b){
return a.t<b.t;
}
};
node A[320000];
bool S[320000];//第i个人是否在集合内
int num[320000];//第i个人得了x票
int ticket[320000];//集合内的人得票数是i的人数
int main(){
cin>>N>>K;
for(int i=0;i<N;i++){
scanf("%d%d",&A[i].t,&A[i].c);
}
memset(S,0,sizeof(S));
memset(num,0,sizeof(num));
memset(ticket,0,sizeof(ticket));
for(int i=0;i<K;i++){
int a;
scanf("%d",&a);
S[a]=1;
}
sort(A,A+N);
ticket[0]=K;
int MIN=0;
int MAX=0;
int lastT=0;
int nextT=0;
int ans=0;
int i=0;
while(i<N){
while(i<N&&A[i].t==A[nextT].t){
if(S[A[i].c]){
num[A[i].c]++;
ticket[num[A[i].c]-1]--;
ticket[num[A[i].c]]++;
if(ticket[num[A[i].c]-1]==0&&num[A[i].c]-1==MIN){
MIN=num[A[i].c];
}
}
else{
num[A[i].c]++;
MAX=max(MAX,num[A[i].c]);
}
i++;
}
ans+=A[nextT].t-A[lastT].t;
if(MIN>MAX){
lastT=nextT;
nextT=i;
}
else{
lastT=i;
nextT=i;
}
}
cout<<ans<<endl;
return 0;
}
//
// _oo0oo_
// o8888888o
// 88" . "88
// (| -_- |)
// 0\ = /0
// ___/`---'\___
// .' \\| |// '.
// / \\||| : |||// \
// / _||||| -:- |||||- \
// | | \\\ - /// | |
// | \_| ''\---/'' |_/ |
// \ .-\__ '-' ___/-. /
// ___'. .' /--.--\ `. .'___
// ."" '< `.___\_<|>_/___.' >' "".
// | | : `- \`.;`\ _ /`;.`/ - ` : | |
// \ \ `_. \_ __\ /__ _/ .-` / /
// =====`-.____`.___ \_____/___.-`___.-'=====
// `=---='
//
//
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 佛祖保佑 永无BUG
//
//
//