Poj 3067 Japan

题目链接:http://poj.org/problem?id=3067

题目大意:输入K组数据,每组包含两个整数,分别代表东西海岸的城市的编号,表示连接对应编号的城市形成的路线,输出这K条路线的交点数,每个交点只由2条路线交叉而成;


思路:将线路数据存入结构体数组line中,将其按x升序排列,若x相同,则按y升序;利用sum函数统计当前线路左边(左边指排序后小于当前元素的一方)y值小于它的元素个数,并在计数器ans中累加,注意ans需使用__int64,然后更新line的值;


代码实现:

#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
int c[1111];
struct Node
{
    int x,y;
}line[1111111];
int N, M, K;
bool cmp(Node a, Node b)//按x升序,若x相同,按y升序 
{
    if(a.x == b.x)
	    return a.y < b.y;
    return a.x < b.x;   
}
int lowbit(int x)
{
    return x & (-x);
}
void update(int i)
{
    while(i <= M)
    {
        c[i] ++;
        i += lowbit(i);
    }
}
int sum(int i)//统计当前元素左边y值小于它的元素个数 
{
    int s = 0;
    while(i > 0)
    {
        s += c[i];
        i -= lowbit(i);
    }
    return s;
}
int main()
{
    int i, j; 
    int T;
    scanf("%d", &T);
    for(i = 1; i <= T; i++)
    {
        scanf("%d %d %d", &N, &M, &K);
        for(j = 1; j <= K; j++)
        {
            scanf("%d %d", &line[j].x, &line[j].y);
        }
        sort(line+1, line+1+K, cmp);
        memset(c, 0, sizeof(c));
        __int64 ans = 0; //数值太大 
        for(j = 1; j <= K; j++)
        {
            ans += sum(M) - sum(line[j].y);
            update(line[j].y);
        }
        printf("Test case %d: %I64d\n", i, ans);
    }
    return 0;
}


你可能感兴趣的:(Poj 3067 Japan)