D - 斜率小於0的連線數量 51Nod - 1107

題目:

二維平面上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 <= Xii, Yii <= 10^9)
Output
輸出斜率小於0的連線的數量。(2,3) (2,4)以及(2,3) (3,3)這2種情況不統計在內。

Sample Input
4
2 3
3 4
1 5
4 6

Sample Output
2

思路:

求斜率小於0的連線也就是求一個點右下方有多少個點,同時題目說了不考慮斜率爲0和斜率不存在的情況.首先點的座標很大所以先要離散化先將點按照y軸排序然後對他們進行編號,然後再按照x軸排一次序就可以了

然後就是根據求逆序數的方法,每插一個數進入數組就查詢一次前面x座標比他大的有多少
注意要將斜率爲0的記錄一下,最後答案要減去這種情況

代碼:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000000;
const int maxn = 123467;
int T,n,q;
int c[maxn];
struct Node
{
    int x,y,id;
}node[maxn];

bool cmpy(Node a,Node b)
{
    if(a.y!=b.y)
        return a.y<b.y;
    else
        return a.x<b.x;
}

bool cmpx(Node a,Node b)
{
    if(a.x!=a.y)
        return a.x<b.x;
    else if(a.x==a.y)
        return a.y<b.y;
}

int lowbit(int x)
{
    return x&(-x);
}

int query_sum(int x)
{
    int sum=0;
    while(x>0)
    {
        sum+=c[x];
        x-=lowbit(x);
    }
    return sum;
}

void update(int x, int v)
{
    while(x<=n)
    {
        c[x]+=v;
        x+=lowbit(x);
    }
}

int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        int tot=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&node[i].x,&node[i].y);
        }
        sort(node+1,node+n+1,cmpy);
        node[1].id=++tot;
        for(int i=2;i<=n;i++)
        {
            if(node[i].y==node[i-1].y)
                node[i].id=tot;
            else
                node[i].id=++tot;
        }
        sort(node+1,node+n+1,cmpx);
        int k=0;
        int ans=0;
        update(node[1].id,1);
        for(int i=2;i<=n;i++)
        {
            ans+=(query_sum(n)-query_sum(node[i].id));
            update(node[i].id,1);
            if(node[i].x==node[i-1].x&&node[i].id<node[i-1].id)//斜率爲0的情況
                k++;
        }
        printf("%d\n",ans-k);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章