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;
    }
  • 相关阅读:
    编程思想-模块化-模块化程序设计:模块化程序设计
    编程思想-模块化-产品模块化设计:产品模块化设计
    编程思想-模块化-模块化设计:模块化设计
    编程思想-模块化:目录
    编程思想-模块化:模块化
    Java学习笔记----main
    jdbc连接hive0.14
    黑马day18 鼠标事件&amp;图片变大
    HLJU 1046: 钓鱼(数据增强版) (贪心+优化)
    怎样打包下载源码
  • 原文地址:https://www.cnblogs.com/zjbztianya/p/3031642.html
Copyright © 2011-2022 走看看