zoukankan      html  css  js  c++  java
  • POJ3067 Japan

    题目大意

    日本岛的东海岸和西海岸分别有N和M个城市,在这些城市中有K条高速公路,每条公路连接着东海岸一个城市和西海岸的一个城市,问总共这些公路有多少交叉点

    题解

    认真观察可以发现,只有这种情况两个线段(规范的)才是有交点的,假设两条的坐标的左右端点分别为(x1,y1)和(x2,y2),只有当x1<x2并且y1>y2或者x1>x2并且y1<y2的时候两个线段才是相交的。这样的话就很好解决这个题目了,我们只需K条高速公路的西海岸城市按编号降序排序,如果编号相同,则让东海岸的城市按编号降序排序(不能升序排序,这样的话在西海岸城市编号相同,东海岸编号不同时的情况下,在计算编号较大者它与其他公路有多少交点的时候会把编号较小的那条公路也计算进去),之后就是用树状数组处理了。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define MAXN 1005
    using namespace std;
    typedef struct
    {
        int x;
        int y;
    }NODE;
    NODE a[MAXN*MAXN];
    int c[MAXN];
    int n,k,m;
    bool cmp(NODE a,NODE b)
    {
        if(a.y==b.y) return  a.x>b.x;
        return a.y>b.y;
    }
    int lowbit(int x)
    {
        return x&-x;
    }
    void add(int x)
    {
        while(x<=MAXN)
        {
            c[x]++;
            x+=lowbit(x);
        }
    }
    int sum(int x)
    {
        long long  ret=0;
        while(x>0)
        {
            ret+=c[x];
            x-=lowbit(x);
        }
        return ret;
    }
    int main(void)
    {
        int i,T,p=0;
        long long ans;
        scanf("%d",&T);
        while(T--)
        {
            printf("Test case %d: ",++p );
            scanf("%d%d%d",&n,&m,&k);
            for(i=1;i<=k;i++)
            scanf("%d%d",&a[i].x,&a[i].y);
            memset(c,0,sizeof(c));
            sort(a+1,a+k+1,cmp);
            ans=0;
            for(i=1;i<=k;i++)
             {
                 ans+=sum(a[i].x-1);
                 add(a[i].x);
             }
             printf("%lld\n",ans);
        }
        return 0;
    }
  • 相关阅读:
    利用web.confing保存数据
    sql2005 未知错误 MS Visual Database Tools
    安装SQL2005时系统配置检查出现“性能监视器计数器要求”
    DNN中的Unit Test
    介绍一个收费的SVN Host
    DNN Navisuite菜单模块原始XML文件的格式
    如何使用C#调用Java
    介绍几个DNN SEO模块,可免费试用的
    帮你找到色彩Photoshop LAB Color
    Google PR 到4了
  • 原文地址:https://www.cnblogs.com/zjbztianya/p/3031642.html
Copyright © 2011-2022 走看看