2020CCPC秦皇岛 Exam Results(尺取)

7-5 Exam Results

Professor Alex is preparing an exam for his students now.

There will be n students participating in this exam. If student i has a good mindset, he/she will perform well and get a​i​​ points. Otherwise, he/she will get b​i​​ points. So it is impossible to predict the exam results. Assume the highest score of these students is x points. The students with a score of no less than x⋅p% will pass the exam.
Alex needs to know what is the maximum number of students who can pass the exam in all situations. Can you answer his question?

Input

The first line of the input gives the number of test cases, T (1≤T≤5×10​3​​). T test cases follow.
For each test case, the first line contains two integers n (1≤n≤2×10​5​​) and p (1≤p≤100), where n is the number of students and p% is the ratio.

Each of the following n lines contains two integers a​i​​,b​i​​ (1≤b​i​​≤a​i​​≤10​9​​), representing the scores of student i.
The sum of n in all test cases doesn’t exceed 5×10​5​​.

Output

For each test case, output one line containing “Case #x: y”, where x is the test case number (starting from 1), and y is the maximum number of students.

Sample Input

2
2 50
2 1
5 1
5 60
8 5
9 3
14 2
10 8
7 6

Sample Output

Case #1: 2
Case #2: 4

题意
给出你 n n n个学生,每个学生有两个成绩,可以从这两个成绩中选出来一个,让你求及格的人有几个? 及格的条件是:去这n个学生的最高分乘以%p这就是及格线。小于这个分就不及格。

思路:
我们可以从题意中发现如果我们降低最高分及格线与会降低,同样我们提升最高分及格线也要提升,所以我们要解决的难点就在这里。首先我们看,条件就是一定会拉出来 n n n个学生这个是一定的,然后就是选成绩最大的那个,我们可以先给这 2 ∗ n 2*n 2n个成绩整体排序,这样我们就很容易的找出最大了,然后在想如何知道这个学生选那个分或者是这个学生是否参与选分,那么我们就需要标记,用 v i s vis vis数组标记当前这个点是否全部pop掉。
尺取:因为我们一边在进元素,进的是最大的那个,一边再出元素出的是不及格的(以为最大分在提高,及格分也就提高了)这就是典型的尺取。
具体看下代码吧。
这个题莫名的卡了下long long也不知道为啥。

代码

#include <stack>
#include <map>
#include <queue>
#include <string>
#include<iostream>
#include<stdio.h>
#include<string.h>
#include <algorithm>
#include <math.h>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
typedef pair<ll, ll> pii;
#define mem(a,x) memset(a,x,sizeof(a))
#define debug(x) cout << #x << ": " << x << endl;
#define rep(i,n) for(int i=0;i<(n);++i)
#define repi(i,a,b) for(int i=int(a);i<=(b);++i)
#define repr(i,b,a) for(int i=int(b);i>=(a);--i)
const int maxn = 5e5 + 10;
#define inf 0x3f3f3f3f
#define sf scanf
#define pf printf
const int mod = 1e9 + 7;
struct node
{
    ll val,id;
} q[maxn];
bool cmp(node a,node b)
{
    return a.val<b.val;
}
ll vis[maxn];
ll n,p,cnt;
int main()
{
    ll t,T=0;
    cin>>t;
    while(t--)
    {
        cnt=0;
        scanf("%lld%lld",&n,&p);
        for(int i=1; i<=n; i++)
        {
            ll a,b;
            scanf("%lld%lld",&a,&b);
            q[++cnt].val= a;///为下面离散化标记
            q[cnt].id=i;
            q[++cnt].val= b;///为下面离散化标记
            q[cnt].id=i;
            vis[i]=0;
        }
        sort(q+1,q+1+cnt,cmp);///排序,按成绩大小排序
        ll top=1,res=0;///top表示第一个及格元素的下标 res表示最高分的下表
        ll now=0;///当下表示及格的人数
        while(now!=n)///先预处理一下,找到第一个满足 包含n个学生的下标
        {
            res++;
            if(vis[q[res].id]==0)///没出现过 人数+1
            {
                now++;
            }
            vis[q[res].id]++;///标记当前学生出现几次
        }
        now--;///以为下面要 res++ 所以先把这个pop掉
        ll ans=0;
        vis[q[res].id]--;
        res--;
        while(res<cnt)
        {
            res++;///后移一位
            if(vis[q[res].id]==0)///没在及格标记 几个人数++
                now++;
            vis[q[res].id]++;
            while(q[top].val*100<q[res].val*p)/// 及格分提高原及格的不及格了
            {
                if(vis[q[top].id]==1)///原就这一个分 就把这个人从及格表中pop掉
                {
                    now--;
                }
                vis[q[top].id]--;
                top++;///及格下标后移
            }
            ans=max(now,ans);///找到最大的
        }
        printf("Case #%lld: %lld\n",++T,ans);
    }

    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值