题意: n支铅笔,每只笔有一个颜色值, 无限个盒子, 如果一个盒子里面放笔的话, 就至少需要k支笔装在一起,并且一个盒子里面的笔的颜色值只差 不能大于 d。如果满足条件就输出YES,不满足就输出NO
题解:
对于这一条直线来说, B,C的长度为K+1, && val[C] - vla[A+1] <= d 如果我们说点C能够和前面的成员塞到一个盒子里面能成功的话, 那么[A,B]之间至少有一个点在前面处理过程中是可以分配的,设这个点为D, 那么[0,D], [D+1,C]都是合法的了。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); 4 #define LL long long 5 #define ULL unsigned LL 6 #define fi first 7 #define se second 8 #define pb push_back 9 #define lson l,m,rt<<1 10 #define rson m+1,r,rt<<1|1 11 #define max3(a,b,c) max(a,max(b,c)) 12 #define min3(a,b,c) min(a,min(b,c)) 13 typedef pair<int,int> pll; 14 const int INF = 0x3f3f3f3f; 15 const LL mod = 1e9+7; 16 const int N = 5e5+100; 17 int a[N]; 18 int vis[N]; 19 int main(){ 20 ///Fopen; 21 int n, k, d; 22 scanf("%d%d%d", &n, &k, &d); 23 for(int i = 1; i <= n; i++) scanf("%d", &a[i]); 24 sort(a+1, a+1+n); 25 vis[0] = 1; 26 int pre = 0, last = 0; 27 int cnt = 1; 28 for(int i = k; i <= n; i++){ 29 while(pre <= last && a[i] - a[pre+1] > d){ 30 if(vis[pre]) cnt--; 31 pre++; 32 } 33 if(cnt > 0) vis[i] = 1; 34 last++; 35 if(vis[last]) cnt++; 36 } 37 if(vis[n]) printf("YES\n"); 38 else printf("NO\n"); 39 return 0; 40 }