题目
题解思路
我们可以将所有人的5个等级的分数弄在一起从小到大排序,因为A等是有限的,在同分数的时候我们贪心的将A等往后面放。
例子
当尺取缺一个人的时候这个人的B类分和A类相同但是区间已经用了K个a了,
此时用B来才能取出正解。
我们的代码只在开头删除cnta,所以我们必须要让结尾最优。
尺取的时候 我们维护取到的区间满足有N个人的分数。并且必须选择A的人小于等于K个,此时就可以更新答案。
当加入一个分数的时候
将这个分数的人有多少个分数在集合++
这个分数的人没加过 cntstu++
这个分数为A类时
这个人的A在集合中的数目++
并且只有一个分数在集合中必须选择它
cnta++
当首指针往前取分数的时候
将这个分数的人有多少个分数在集合–
当这个人减到0的时候 cntstu–
当这个人减到1并且 这个人的A在集合中的数目为1时
即剩下了一个A类的分数
必须选择 cnta++
当这个被减去的分数为A类并且区间中没这个人的分数了。
cnta–
调了很久的bug
思路还是好理解的。
AC代码
#include <bits/stdc++.h>
//#include <unordered_map>
//priority_queue
#define PII pair<int,int>
#define ll long long
using namespace std ;
const int INF = 0x3f3f3f3f ;
const int N = 100010 ;
int cnt = 1 ;
struct node
{
int x , val , p ;
}a[5*N] ;
int mp[N] ;
int mpa[N] ;
bool cmp (node A , node B )
{
if ( A.val == B.val )
return A.x < B.x ;
return A.val < B.val ;
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int k , n ;
cin >> n >> k ;
for (int i = 1 ; i <= n ; i++ )
{
int t1 , t2 , t3 , t4 , t5 ;
cin >> t1 >> t2 >> t3 >> t4 >> t5 ;
a[cnt] = {1,t1,i};
cnt++;
a[cnt] = {0,t2,i};
cnt++;
a[cnt] = {0,t3,i};
cnt++;
a[cnt] = {0,t4,i};
cnt++;
a[cnt] = {0,t5,i};
cnt++;
}
//unordered_map <int , int > mp ;
//unordered_map <int , int > mpa ;
int cntstu = 0 ;
int cnta = 0 ;
int ans = INF ;
int sp = 1 ;
cnt--;
sort(a+1,a+1+cnt,cmp) ;
/*for (int i = 1 ; i <= cnt ; i++ )
cout << i << " " ;
cout << "\n" ;
for (int i = 1 ; i <= cnt ; i++ )
cout << a[i].x << " " ;
cout << "\n" ;
for (int i = 1 ; i <= cnt ; i++ )
cout << a[i].val << " " ;
cout << "\n" ;
for (int i = 1 ; i <= cnt ; i++ )
cout << a[i].p << " " ;
cout << "\n" ;*/
mp[a[1].p]++;
cntstu++;
for (int i = 1 ; i <= cnt ; i++ )
{
for (; sp <= cnt ; sp++ )
{
if (cntstu == n && cnta <= k )
{
ans = min(a[sp].val - a[i].val , ans ) ;
break ;
}
mp[a[sp+1].p]++;
if (mp[a[sp+1].p] == 1 )
{
//cout << cntstu << " " << a[sp+1].p << " " << mp[1] << " " << mp[2] << " " << mp[3] << "\n" ;
cntstu++;
}
if (a[sp+1].x == 1 )
{
mpa[a[sp+1].p]++;
if (mp[a[sp+1].p] == 1 )
{
//cout << sp+1 << " a++\n";
cnta++;
}
}
}
//cout << i << " stu:" << cntstu << " a:" << cnta << " sp:"<< sp << "\n" ;
mp[a[i].p]--;
if (mp[a[i].p] == 0 )
cntstu--;
if (mp[a[i].p] == 1 && mpa[a[i].p] == 1 )
{
cnta++;
}
if (a[i].x == 1 && mp[a[i].p] == 0 )
cnta--;
//cout << i << " stu:" << cntstu << " a:" << cnta << " sp:"<< sp << "\n" ;
}
cout << ans << "\n" ;
return 0 ;
}