Project Eular 630

大概这一题题意:

给你n=2500个点,生成方式给你了

设Ln表示这n个点两两连出来的直线(去重后,例如(1 1) (2 2) (3 3)只有一条直线)

问这些直线之间两两一共有多少个交点

(两条线交在一起算2次,因为A交B一次,B交A一次)

三条线交在一个点算6次,因为AB,AC,BA,BC,CA,CB)

做法:

我们只要考虑平行的,没有交,不平行的都有交,这样就把复杂度弄到n^2级别了

用分数类统计以后直接计算即可

代码(分数类板子比较重要...):

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<time.h>
#include<math.h>
#include<memory>
#include<vector>
#include<bitset>
#include<fstream>
#include<stdio.h>
#include<utility>
#include<sstream>
#include<string.h>
#include<iostream>
#include<stdlib.h>
#include<algorithm>
using namespace std;
int new_s()
{
    static int s=290797;
    s=(long long)s*s%50515093;
    return s;
}
struct point
{
    int x;
    int y;
    void get()
    {
        x=new_s()%2000-1000;
        y=new_s()%2000-1000;
    }
};
int get_sgn(int x)
{
    if (x==0) return 0;
    if (x>0) return 1;
    return -1;
}
struct fenshu
{
    int fenzi;
    int fenmu;
    int sgn() const
    {
        return get_sgn(fenzi)*get_sgn(fenmu);
    }
    fenshu (int x=0,int y=1)
    {
        fenzi=x;
        fenmu=y;
    }
    friend fenshu operator / (const fenshu &a,const fenshu &b)
    {
        return fenshu(a.fenzi*b.fenmu,b.fenzi*a.fenmu);
    }
    friend fenshu operator * (int k,const fenshu &b)
    {
        return fenshu(k*b.fenzi,b.fenmu);
    }
    friend fenshu operator * (const fenshu &b,int k)
    {
        return fenshu(k*b.fenzi,b.fenmu);
    }
    friend fenshu operator - (int y,const fenshu &a)
    {
        return fenshu(y*a.fenmu-a.fenzi,a.fenmu);
    }
    friend bool operator == (const fenshu &a,const fenshu &b)
    {
        if ((a.fenmu==0)^(b.fenmu==0)) return false;
        return (long long)a.fenzi*b.fenmu==(long long)a.fenmu*b.fenzi;
    }
    friend bool operator < (fenshu a,fenshu b)
    {
        if (a.fenmu==0) return false;
        if (b.fenmu==0) return true;
        int k1=a.sgn();
        int k2=b.sgn();
        if (k1!=k2)
        {
            return k1<k2;
        }
        if (a.fenzi<0) a.fenzi=-a.fenzi;
        if (a.fenmu<0) a.fenmu=-a.fenmu;
        if (b.fenzi<0) b.fenzi=-b.fenzi;
        if (b.fenmu<0) b.fenmu=-b.fenmu;
        if (k1==-1)
        {
            return (long long)a.fenzi*b.fenmu>(long long)a.fenmu*b.fenzi;
        }
        else
        {
            return (long long)a.fenzi*b.fenmu<(long long)a.fenmu*b.fenzi;
        }
    }
};
point a[2505];
//#define fenshu long double
struct line
{
    fenshu k;
    fenshu b;
    line ()
    {
    }
    line (point a,point bb)
    {
        #ifdef fenshu
        k=(double)(a.y-bb.y)/(a.x-bb.x);
        #else
        k=fenshu(a.y-bb.y,a.x-bb.x);
        #endif
        if (a.x==bb.x)
        {
            #ifdef fenshu
            k=1e300;
            b=a.x;
            #else
            k=fenshu(1,0);
            b=fenshu(a.x,1);
            #endif
        }
        else
        {
            b=a.y-k*a.x;
        }
    }
    friend bool operator < (const line &a,const line &b)
    {
        if ((a.k<b.k)||(b.k<a.k)) return a.k<b.k;
        return a.b<b.b;
    }
    friend bool operator == (const line &a,const line &b)
    {
        return (a.k==b.k)&&(a.b==b.b);
    }
};
line b[50000005];
int main()
{
    freopen("output.txt","w",stdout);
    int n=2500;
    int i;
    for (i=0;i<n;i++)
    {
        a[i].get();
    }
    int cnt=0;
    int j;
    for (i=0;i<n;i++)
    {
        for (j=i+1;j<n;j++)
        {
            if ((a[i].x==a[j].x)&&(a[i].y==a[j].y)) continue;
            b[cnt++]=line(a[i],a[j]);
        }
    }
    sort(b,b+cnt);
    cnt=unique(b,b+cnt)-b;
    cout<<cnt<<endl;
    long long ans=0;
    ans=(long long)cnt*(cnt-1);
    int now=1;
    for (i=1;i<cnt;i++)
    {
        //printf("%.12lf
",b[i].k);
        if (b[i].k==b[i-1].k)
        {
            now++;
        }
        else
        {
            //if (now>1) printf("%d
",now);
            ans-=(long long)now*(now-1);
            now=1;
        }
    }
    ans-=(long long)now*(now-1);
    cout<<ans<<endl;
    return 0;
}

  

原文地址:https://www.cnblogs.com/absi2011/p/9256604.html