#include <algorithm> #include <ctype.h> #include <cstdio> using namespace std; void read(int &x) { x=0;char ch=getchar(); for(;!isdigit(ch);ch=getchar()); for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; } struct node { int x,y,num; }pos[50005]; bool cmp(node a,node b) { return a.y<b.y; } bool comp(node a,node b) { if(a.x!=b.x) return a.x<b.x; else if(a.x==b.x) return a.y<b.y; } int ans,sum,size,tim,n,tag[50005]; int lowbit(int x) { return x&(-x); } void add(int x,int y) { for(;x<=size;x+=lowbit(x)) tag[x]+=y; } int query(int x) { int ans=0; for(;x;x-=lowbit(x)) ans+=tag[x]; return ans; } int main() { read(n); for(int i=1;i<=n;i++) { read(pos[i].x); read(pos[i].y); } sort(pos+1,pos+1+n,cmp); pos[1].num=++tim; for(int i=2;i<=n;i++) { if(pos[i].y==pos[i-1].y) pos[i].num=tim; else pos[i].num=++tim; } sort(pos+1,pos+1+n,comp); int t=0; ans=0; sum=1; size=tim; add(pos[1].num,1); for(int i=2;i<=n;i++) { ans+=sum-query(pos[i].num); sum++; add(pos[i].num,1); if(pos[i].x==pos[i-1].x&&pos[i].num <pos[i-1].num) t++; } printf("%d",ans-t); return 0; }
基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
二维平面上N个点之间共有C(n,2)条连线。求这C(n,2)条线中斜率小于0的线的数量。
二维平面上的一个点,根据对应的X Y坐标可以表示为(X,Y)。例如:(2,3) (3,4) (1,5) (4,6),其中(1,5)同(2,3)(3,4)的连线斜率 < 0,因此斜率小于0的连线数量为2。
Input
第1行:1个数N,N为点的数量(0 <= N <= 50000) 第2 - N + 1行:N个点的坐标,坐标为整数。(0 <= X[i], Y[i] <= 10^9)
Output
输出斜率小于0的连线的数量。(2,3) (2,4)以及(2,3) (3,3)这2种情况不统计在内。
Input示例
4 2 3 3 4 1 5 4 6
Output示例
2
和求逆序数类似
先排序纵坐标 编号(离散化)
再排序横坐标 用求逆序数方法得出结果
屠龙宝刀点击就送