Codeforces Round #544 (Div. 3) C. Balanced Team [暴力剪枝]

You are a coach at your local university. There are
n
n
students under your supervision, the programming skill of the
i
i
-th student is
a
i
ai
.
You have to create a team for a new programming competition. As you know, the more students some team has the more probable its victory is! So you have to create a team with the maximum number of students. But you also know that a team should be balanced. It means that the programming skill of each pair of students in a created team should differ by no more than
5
5
.
Your task is to report the maximum possible number of students in a balanced team.
Input
The first line of the input contains one integer
n
n
(
1≤n≤2?
10
5
1≤n≤2?105
) — the number of students.
The second line of the input contains
n
n
integers
a
1
,
a
2
,…,
a
n
a1,a2,…,an
(
1≤
a
i

10
9
1≤ai≤109
), where
a
i
ai
is a programming skill of the
i
i
-th student.
Output
Print one integer — the maximum possible number of students in a balanced team.
Examples
Input
Copy
6
1 10 17 12 15 2
Output
Copy
3
Input
Copy
10
1337 1337 1337 1337 1337 1337 1337 1337 1337 1337
Output
Copy
10
Input
Copy
6
1 1000 10000 10 100 1000000000
Output
Copy
1

题解:题意给n个数,求子集的最小值和最大值之差不超过5,求最大的子集的元素数.
我的思路:先对数组排序,这里如果直接暴力的话,O(n^2)的复杂度,肯定会tle,
优化一下,因为是排过序的,所以子集的左端和右端都是极值,如果右值与左值之差大于5,左值的位置右移,

再次优化,如果前一值与后一值之差大于5,I 移动的后一值的位置.

#include <bits/stdc++.h>
const int N=2e5+5;
using namespace std;
int a[N],b[N];
int ans=0,cnt=0,flag=0,maxn=0;
void check(int m){
    if(m>maxn) maxn=m;
}
int cal(int i,int j){
    return a[j]-a[i];
}
int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    sort(a+1,a+1+n);
    int i=1,j=i+1;
    while(i<=n-1&&j<=n){
        if(cal(j-1,j)>5){
            check(j-1-i);
            i=j;
            j++;
        }
        else if(cal(i,j)>5){
            check(j-1-i);
            i++;
            if(i==j) j++;
            //cout<<"jjg"<<endl;
        }
        else{
            j++;
            //cout<<"jj"<<endl;
        }
        //if(!flag) break;
    }
    check(j-1-i);
    printf("%d\n",maxn+1);
    return 0;
}

原文地址:https://www.cnblogs.com/-yjun/p/10503477.html

时间: 2024-10-28 15:07:16

Codeforces Round #544 (Div. 3) C. Balanced Team [暴力剪枝]的相关文章

Codeforces Round #486 (Div. 3) A. Diverse Team

Codeforces Round #486 (Div. 3) A. Diverse Team 题目连接: http://codeforces.com/contest/988/problem/A Description There are n students in a school class, the rating of the i-th student on Codehorses is ai. You have to form a team consisting of k students

Codeforces Round #516 (Div. 2, by Moscow Team Olympiad)

Codeforces Round #516 (Div. 2, by Moscow Team Olympiad) https://codeforces.com/contest/1064 A 1 #include<bits/stdc++.h> 2 #define pb push_back 3 using namespace std; 4 5 bool Check(int a,int b,int c){ 6 if(a+b>c&&b+c>a&&a+c>

Codeforces Round #359 (Div. 2) C. Robbers&#39; watch (暴力DFS)

题目链接:http://codeforces.com/problemset/problem/686/C 给你n和m,问你有多少对(a, b) 满足0<=a <n 且 0 <=b < m 且a的7进制和n-1的7进制位数相同 且b的7进制和m-1的7进制位数相同,还有a和b的7进制上的每位上的数各不相同. 看懂题目,就很简单了,先判断a和b的7进制位数是否超过7,不超过的话就dfs暴力枚举计算就可以了. 1 //#pragma comment(linker, "/STACK

CodeForces Round #544 Div.3

A. Middle of the Contest 代码: #include <bits/stdc++.h> using namespace std; int h1, m1, h2, m2; int tim1 = 0, tim2 = 0; int main() { scanf("%d:%d", &h1, &m1); scanf("%d:%d", &h2, &m2); tim1 = h1 * 60 + m1; tim2 = h

Codeforces Round #379 (Div. 2) Analyses By Team:Red &amp; Black

A.Anton and Danik Problems: 给你长度为N的,只含'A','D'的序列,统计并输出何者出现的较多,相同为"Friendship" Analysis: lucky_ji: 水题,模拟统计A和D的数目比较大小输出结果即可 Tags: Implementation B.Anton and Digits Problems: 给定k2个2,k3个3,k5个5及k6个6,可以组成若干个32或256,求所有方案中Sigma的最大值 Analysis: lucky_ji: 同

Codeforces Round #516 (Div. 2, by Moscow Team Olympiad) D. Labyrinth

http://codeforces.com/contest/1064/problem/D 向上/向下加0,向左/右加1, step = 0,1,-- 求的是最少的步数,所以使用bfs. step=k -> step=k+1 1.step=k 使用一次左/右 到达 step=k+1 2.step=k+1 无限使用上下,得到所有 step=k+1 的状态 用dijkstra+堆优化 / spfa 超时. 1 #include <bits/stdc++.h> 2 using namespace

Codeforces Round #544 (Div. 3) dp + 双指针

https://codeforces.com/contest/1133/problem/E 题意 给你n个数(n<=5000),你需要对其挑选并进行分组,总组数不能超过k(k<=5000),每组数字差距不超过5,问最多能挑出多少数字 题解 先排序,在进行dp,定义dp[i][j]为前i个数分成j组的最大值 两个转移方向 不选 dp[i-1][j] -> dp[i][j] 和前面的分组 dp[lt[i]-1][j-1] -> dp[i][j] 怎么确定i前面的哪个点是最大的? 选择能

Codeforces Round #516 (Div. 1, by Moscow Team Olympiad) B

题链 Description 给一张方格图,对于上下移动无限制,左右移动数分别不能超过L,R,求能到多少点. Sol 发现 新的y坐标=老坐标-左移操作数+右移操作数 所以我们只需最小化左移操作数即可,最短路. Code #include<bits/stdc++.h> #define N 2007 #define pii pair<int,int> #define fi first #define se second using namespace std; char p[N][N

Codeforces Round #516 (Div. 1, by Moscow Team Olympiad) C

题链 Description 和交互库交互,你给出n个点,交互库指定颜色,求一条直线分割颜色. Sol 分别在x轴,y轴上二分即可. Code #include<bits/stdc++.h> #define Mid (l+r>>1) using namespace std; int n,l,r; char p1[102],p2[102],p3[102]; void work(int x,int pos,int g) { l=500000000; r=1000000000; for