ZOJ 3129 Japan

题意叫你求交叉点的个数,转换一下思维,把第一个数看作是i,和它相连接的第二个数看作是ai,当i < j 且 ai > aj时这时才有交叉点,

这样就转换为求逆序对的个数;首先,把他x从小到大排序,x相同的按y从大到小排序,排完序后,在使用合并排序,计算逆序对的个数。

#include<math.h>
#include<stdio.h>
#include<limits.h>
#define MAX 1000005
 
int L[MAX/2],R[MAX/2];
long long sum;

typedef struct NODE{
    int e;
    int w;    
}node;
node A[MAX];

void MERGE(int p,int q,int r)
{
    int n1,n2,i,j,k;
    n1=q-p+1;
    n2=r-q;
    for(i=0;i<n1;i++)    L[i]=A[p+i].w;   // 左部分
    L[n1]=INT_MAX;
    for(j=0;j<n2;j++)    R[j]=A[q+1+j].w;     // 右部分
    R[n2]=INT_MAX;
    i=0; j=0;
    for(k=p;k<=r;k++){                   // 归并,递增序列
        if(L[i]<=R[j]) {
            A[k].w=L[i];
            i++;               
        }
        else{
            sum+=(long long)(n1-i);
            A[k].w=R[j];
            j++;     
        }
    }     
}

void MergeSort(int p,int r)
{
    int q;
    if(p<r){
        q=(p+r)/2;
        MergeSort(p,q);
        MergeSort(q+1,r);
        MERGE(p,q,r);        
    }     
}

int cmp(const void *a,const void *b )
{
    if(((node *)a)->e>((node *)b)->e) return 1;
    else if((((node *)a)->e==((node *)b)->e) && (((node *)a)->w>((node *)b)->w))
        return 1;
    return -1;
}
int main()
{
    int i,k,j,m,n,t;
    scanf("%d",&t);
    for(j=1;j<=t;j++){
        sum=0;
        scanf("%d%d%d",&n,&m,&k);
        for(i=0;i<k;i++)
            scanf("%d%d",&A[i].e,&A[i].w);
        qsort(A,k,sizeof(node),cmp);
        MergeSort(0,k-1);        
        printf("Test case %d: %lld\n",j,sum);    
    }
    system("pause");
    return 0;    
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值