andre_joy

导航

hdu 1025

地址:http://acm.hdu.edu.cn/showproblem.php?pid=1025

题意:上面n个点,下面n个点,然后在这2n个点之间随意连线,一个点只能被连一次,问最多有多少条线不交叉。

mark:把上面点排序后,那么就转换成最大升序子序列的问题了。可以看看我上一篇博客~poj 3903

代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct
{
    int s,e;
}city;

city c[500010];
int len;
int d[500010];

int cmp(const void *a, const void *b)
{
    return (*(city *)a).s - (*(city *)b).s;
}

int find(int m)
{
    int fr = 0, la = len-1, mid;
    while(fr <= la)
    {
        mid = (fr+la)/2;
        if(d[mid] == m) return 0;
        if(d[mid] > m) la = mid-1;
        else fr = mid+1;
    }
    return fr;
}

int main()
{
    int n,m;
    int i,j;
    j = 1;
    while(~scanf("%d", &n))
    {
        len = 0;
        for(i = 0; i < n; i++)
            scanf("%d %d", &c[i].s, &c[i].e);
           qsort(c, n, sizeof(c[0]), cmp);
        for(i = 0; i < n; i++)
        {
            if(!len) {d[len++] = c[i].e; continue;}
            if(c[i].e < d[0]) {d[0] = c[i].e; continue;}
            if(c[i].e > d[len-1]) {d[len++] = c[i].e; continue;}
            m = find(c[i].e);
            if(m) d[m] = c[i].e;
        }
        printf("Case %d:\nMy king, at most %d road", j++, len);
        if(len-1) putchar('s');
        puts(" can be built.\n");
    }
    return 0;
}

posted on 2012-07-25 15:48  andre_joy  阅读(549)  评论(0编辑  收藏  举报