【2019华东交通校赛:H】谁在说谎(思维)

链接:https://ac.nowcoder.com/acm/contest/1168/H

题目:


题目描述

邓志聪是一位非常聪明的小伙子,这次他在某个学校当班主任,他班上有n个学生,然而有些学生非常的讨厌邓志聪。一次考试结束后,邓志聪想知道这些学生的考试情况,于是一个一个叫这些学生叫去办公室问他们,但是有些学生并没有讲真话,第i个学生说:“有ai个人分数比我高,bi个人分数比我低。”邓志聪想知道最少有几个学生没有说真话,你能帮助他吗?(可能有相同的分数)

输入描述:

第一行一个整数n,接下来每行两个整数,第i+1行两个整数代表ai,bi。(1<=n<=100000,0<=ai,bi<=n)

输出描述:

一个整数,表示最少有几个人在说谎。

输入

3
1 1
2 2
0 2

输出

1

解题思路:


题目要求最少的说谎人数,反向即求最多有多少人没有说谎。

对于第i个学生,由可以确定一个区间(),该区间内的所有学生排名相同,且共有个人。对于一个区间,出现的次数可能大于次,这说有一定有人说谎了,所以最终可以确定一个三元组,,

方法1:

对这些三元组按照R从小到大排序,对于拍完序的第i个元组,在之间二分找到一个最大的j,使得,不断更新答案

方法2:

统计元组中的R对应的所有L,1~n遍历R,枚举R对应的所有L,更新答案

基本思路:确定同排名的人所在的所有区间,寻找一个区间集合满足上一个区间的R<下一个区间的L(目的是得到一个连续的排名),确定区间集合中的最大人数。

ac代码:


方法1:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
struct node{
    int l, r, v;
    friend bool operator < (node a, node b)
    {
        return a.r == b.r ? a.l < b.l : a.r < b.r;
    }
}c[maxn];
int n, a, b, L, R;
int f[maxn], p[maxn];
map<pair<int, int>, int> m;
int main() {
    //freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);
    scanf("%d", &n);
    int num = 1;
    for(int i = 1; i <= n; i++)
    {
        scanf("%d %d", &a, &b);
        L = a+1, R = n-b;
        if(L<=R)
        {
            if(m[make_pair(L, R)] == 0)
            {
                c[num].l = L;
                c[num++].r = R;
                m[make_pair(L, R)] = 1;//相同的区间只在c中存储一次
            }
            else m[make_pair(L, R)]++;//统计区间出现的次数
        }
    }
    num--;
    sort(c+1,c+1+num);
    for(int i = 1; i <= num; i++)
    {
        c[i].v = min(m[make_pair(c[i].l,c[i].r)], c[i].r-c[i].l+1);
        p[i] = c[i].r;
    }
    for(int i = 1; i <= num; i++)
    {
        int last = lower_bound(p+1, p+1+num, c[i].l)-p-1;//最后一个小于c[i].l的下标
        //printf("last%d\n", last);
        f[i] = max(f[i-1], f[last]+c[i].v);
    }
    printf("%d\n", n-f[num]);
    return 0;
}

方法2:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
struct node{
    int l, r;
}c[maxn];
vector<int> p[maxn];//p[i]中存储(L,R)中R=i的所有L值
int n, a, b, L, R;
int f[maxn];
map<pair<int, int>, int> m;
int main()
{
    //freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
    {
        scanf("%d %d", &a, &b);
        L = a+1, R = n-b;
        if(L<=R)
        {
            m[make_pair(L, R)]++;//统计区间出现的次数
            if(m[make_pair(L,R)] == 1)p[R].push_back(L);
        }
    }
    for(int i = 1; i <= n; i++)
    {
        f[i] = f[i-1];
        for(int j = 0; j < p[i].size(); j++)
        {
            int cnt = min(i-p[i][j]+1, m[make_pair(p[i][j], i)]);//(L,R)区间出现的次数
            f[i] = max(f[i], f[p[i][j]-1]+cnt);
        }
    }
    printf("%d\n", n-f[n]);
    return 0;
}

 

全部评论

相关推荐

10-15 09:13
已编辑
天津大学 soc前端设计
点赞 评论 收藏
分享
评论
点赞
收藏
分享
正在热议
# 25届秋招总结 #
440428次浏览 4493人参与
# 春招别灰心,我们一人来一句鼓励 #
41455次浏览 524人参与
# 北方华创开奖 #
107285次浏览 599人参与
# 地方国企笔面经互助 #
7922次浏览 18人参与
# 虾皮求职进展汇总 #
114057次浏览 883人参与
# 实习,投递多份简历没人回复怎么办 #
2453918次浏览 34847人参与
# 阿里云管培生offer #
119761次浏览 2219人参与
# 实习必须要去大厂吗? #
55665次浏览 960人参与
# 同bg的你秋招战况如何? #
75478次浏览 551人参与
# 提前批简历挂麻了怎么办 #
149813次浏览 1977人参与
# 投递实习岗位前的准备 #
1195668次浏览 18546人参与
# 你投递的公司有几家约面了? #
33170次浏览 188人参与
# 双非本科求职如何逆袭 #
661868次浏览 7394人参与
# 机械人春招想让哪家公司来捞你? #
157600次浏览 2267人参与
# 如果公司给你放一天假,你会怎么度过? #
4723次浏览 54人参与
# 如果你有一天可以担任公司的CEO,你会做哪三件事? #
11332次浏览 270人参与
# 发工资后,你做的第一件事是什么 #
12405次浏览 61人参与
# 工作中,努力重要还是选择重要? #
35599次浏览 384人参与
# 参加完秋招的机械人,还参加春招吗? #
20087次浏览 240人参与
# 实习想申请秋招offer,能不能argue薪资 #
39225次浏览 314人参与
# 我的上岸简历长这样 #
451915次浏览 8088人参与
# 非技术岗是怎么找实习的 #
155837次浏览 2120人参与
牛客网
牛客企业服务