内卷 题解(尺取)
作者:互联网
题目链接
题目思路
本赛的时候没看这个题目,其实思路挺简单
但是实现有很多小细节
用尺取法,保证那个区间type==n且typema<=k即可
代码
#include<bits/stdc++.h>
#define fi first
#define se second
#define debug cout<<"I AM HERE"<<endl;
using namespace std;
typedef long long ll;
const int maxn=1e5+5,inf=0x3f3f3f3f,mod=1e9+7;
const int eps=1e-6;
int n,m,k,ans=inf;
int a[maxn][6];
int vis[maxn][6];
struct node{
int w,x,y;
}nd[maxn*5];
bool cmp(node a,node b){
if(a.w!=b.w){
return a.w<b.w;
}else{ //保证a等级和其他等级相同时让a等级在后面
return a.y>b.y;
}
}
signed main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
for(int j=1;j<=5;j++){
scanf("%d",&a[i][j]);
nd[++m]={a[i][j],i,j};
}
}
sort(nd+1,nd+1+m,cmp);
int type=0,typema=0;
// type 代表有多少个种类
// typema代表这个区间有多少个只存在a等级的种类
for(int l=1,r=0;l<=m;l++){
if(l!=1){
vis[nd[l-1].x][nd[l-1].y]=0;
if(nd[l-1].y==1){
// 当其中一个人的最大分数都没有了那么肯定凑不齐n个人了
typema--;
break;
}
int cnt=0;
for(int i=1;i<=5;i++){
cnt+=vis[nd[l-1].x][i];
}
if(cnt==0){
type--;
}else if(cnt==1&&vis[nd[l-1].x][1]){
//如果只存在一个值,且是最大值那么typema++
typema++;
}
}
while(r<=m&&type<n&&typema<=k){
int cnt=0;
r++;
vis[nd[r].x][nd[r].y]=1;
for(int j=1;j<=5;j++){
cnt+=vis[nd[r].x][j];
}
if(cnt==1){
type++;
if(nd[r].y==1){
typema++;
}
}
}
if(typema<=k&&type==n){
ans=min(ans,nd[r].w-nd[l].w);
}
}
printf("%d\n",ans);
return 0;
}
标签:题目,int,题解,d%,尺取,思路,define 来源: https://www.cnblogs.com/hunxuewangzi/p/14380884.html