• HUD-5124-lines


    题目链接

    http://acm.hdu.edu.cn/showproblem.php?pid=5124

    这题题目做的好悲催,比赛时题目意思不理解,也没有深究了,赛后又看了很久没有看懂,问了很多才搞懂,我有一种想哭的冲动,我一直把

    这题[x,y]这个线段看成了一个坐标,我想哭了,由于x,y坐标带来的惯性,,本来题目告诉你了【x,y】这条线段,

    这是一个区间,是数轴,是一维坐标,而一直把它看做一个二维坐标,悲剧了。

    官方解析

    1002 lines
    我们可以将一条线段[xi,yi]分为两个端点xi(yi)+1,在xi时该点会新加入一条线段,同样的,在(yi)+1时该点会减少一条线段,
    因此对于2n个端点进行排序,令xi为价值1,yi为价值-1,问题转化成了最大区间和,因为1一定在-1之前,因此问题变成最大前缀和,
    我们寻找最大值就是答案,另外的,这题可以用离散化后线段树来做。复杂度为排序的复杂度即nlgn,另外如果用第一种做法数组应
    是2n,而不是n,由于各种非确定性因素我在小数据就已经设了n=10W的点。



    代码

    #include<stdio.h>
    #include<algorithm>
    using namespace std;

    pair<int,int> a[200010];//相当于结构体作用。

    int main(void)
    {
    int t,n,ans,k,i;
    scanf("%d",&t);
    while(t--)
    {
    scanf("%d",&n);
    n=n*2;
    for(i=0;i<n;i++)
    {
    scanf("%d",&a[i].first);
    a[i].second=1;
    scanf("%d",&a[++i].first);
    a[i].first++;
    a[i].second=-1;
    }
    sort(a,a+n);
    ans=0; k=0;
    for(i=0;i<n;i++)
    {
    k=k+a[i].second;
    ans=max(ans,k);
    }
    printf("%d ",ans);
    }
    return 0;
    }

    
    

    离散化,首先把所有的坐标映射到x轴上,然后将坐标压缩。怎么压缩呢?

    可以用一个v数组,直接存贮位置就可以了,那么这样就完成了坐标的压缩。

    #include <iostream>
    #include <algorithm>
    #include <stdio.h>
    #include <map>
    #include <vector>

    using namespace std;

    #define MAXN 200005

    typedef pair<int,int> PII;

    int x[MAXN];
    PII p[MAXN];
    int v[MAXN];

    int main()
    {
    int t;
    scanf("%d",&t);
    while(t--)
    {
    int n;
    scanf("%d",&n);
    int cnt = 0;
    for(int i = 0; i<n; i++)
    {
    scanf("%d %d",&p[i].first,&p[i].second);
    x[cnt++] = p[i].first;
    x[cnt++] = p[i].second;
    }
    sort(x,x+cnt);
    printf("%d ",cnt);
    printf("%d ",x);
    cnt = unique(x,x+cnt)-x;
    printf("%d ",cnt);
    for(int i = 0; i<cnt; i++)
    {
    v[i] = 0;
    }
    int sum = 0;
    for(int i = 0; i<n; i++)
    {
    int l = lower_bound(x,x+cnt,p[i].first)-x;
    int r = lower_bound(x,x+cnt,p[i].second)-x;
    v[l]++;
    v[r+1]--;
    }
    int s = 0;
    int mx = 0;
    for(int i = 0; i<cnt; i++)
    {
    s+=v[i];
    mx = max(mx,s);
    }
    printf("%d ",mx);
    }
    return 0;
    }

    当然不一定非得把坐标映射到x轴上,vector <pair<int,int> > v; v[i].first 用来把坐标排序,起到了映射的作用。然后数组的下标就起到了压缩的作用。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>

    using namespace std;

    vector <pair<int,int> > v;

    int main ()
    {
    int T;
    cin >> T;
    while (T--)
    {
    v.clear();
    int N;
    scanf("%d",&N);
    for (int i = 0; i < N; i++)
    {
    int x;
    scanf("%d",&x);
    v.push_back(make_pair(x,1));
    scanf("%d",&x);
    v.push_back(make_pair(x + 1,-1));
    }
    sort(v.begin(), v.end());
    int ans = 0;
    int maxn = 0;
    for (int i = 0; i < v.size(); i++)
    {
    ans += v[i].second;
    maxn = max(maxn,ans);
    }
    cout << maxn << endl;
    }
    }



  • 相关阅读:
    svn使用教程
    软件工程课程设计分组与选题名单
    解决自己的提问
    <构建之法>第十三章到十七章有感以及这个项目读后感
    <构建之法>第十一章、十二章有感
    关于C语言打印string类字符串的问题
    单链表
    8、判断三角形ABC中是否有点D
    7、完整版的strcpy函数
    6、旋转数组的最小数字
  • 原文地址:https://www.cnblogs.com/liudehao/p/4133838.html
Copyright © 2020-2023  润新知