题解

5 条题解

  • 3
    @ 2015-02-17 16:21:21

    先去zhong(第四声)点,【=_=】

    然后取一个不在任意两点所成直线上的点,
    关于这个点为圆心的单位圆作一个配极变换,
    原图的点变为两两不平行的直线,划分线变为一个点,

    那么对于新图,容易知道,
    一个闭区域对应一个无序划分,
    两个由两条相同直线夹出来的开区域对应同一个无序划分,
    于是ans/2=闭区域数+开区域数/2-1,

    注意到开区域数=2n,
    闭区域数+开区域数=1+n+直线交点数(这里k线共点按k-1个交点计),
    整理得ans/2=直线交点数,
    而新图中的交点在原图中表现为一条经过某些点的直线,
    新图中的k线共点则表现为原图中的k点共线,
    所以ans/2=原图中不同的直线条数(这里k点共线按k-1条直线计),

    到这里……实际上就是@EZ_lzh所说的……

  • 1
    @ 2015-02-17 11:48:22

    解题报告

    统计【连接两点的线段】上没有【第三个点】的线段数,将此数乘2输出即可。

  • 0
    @ 2018-05-03 16:21:51
    #include <iostream>
    #include <bits/stdc++.h>
    #define  ll long long
    using namespace std;
    struct Point
    {
        ll x,y;
        Point(){}
        Point (ll _x,ll _y): x(_x),y(_y){}
    
        ll operator^ (const Point &r)
        {
            return x * r.y - r.x * y;
        }
    
        Point operator- (const Point &r)
        {
            ll _x = x - r.x;
            ll _y = y - r.y;
            return Point(_x,_y);
        }
    }p[3005];
    
    
    bool judge1(Point a,Point b,Point c)
    {
        if  ( ( ( b - a ) ^ ( c - b )) == 0) return true;
        else  return false;
    }
    bool judge2(Point s,Point t,Point r)
    {
        int lx = min(s.x,t.x);
        int rx = max(s.x,t.x);
        int ly = min(s.y,t.y);
        int ry = max(s.y,t.y);
    
        if ( r.x >= lx && r.x <= rx && r.y >=ly && r.y <= ry) return true;
        else return  false;
    }
    int n,tn;
    int tx,ty;
    map<pair<int,int>,int> docsb;
    int main() {
    
        scanf("%d",&tn);
        n=0;
        for (int i = 1; i <= tn ; i++)
        {
            scanf("%d%d",&tx,&ty);
            if (docsb[make_pair(tx,ty)] == 0)
            {
                docsb[make_pair(tx,ty)] = 1;
                p[++n].x = tx;
                p[n].y = ty;
            }
        }
    
        ll ans = 0;
        for (int i = 1 ; i <= n ; i++)
            for (int j = i + 1 ; j  <= n ; j ++)
            {
                bool f = true;
                for (int k = 1 ; k <= n ; k ++)
                {
                    if  ( k == i || k == j ) continue;
                    //cout << i << " " << j << " " <<k <<" " << judge1(p[i],p[j],p[k]) <<" " << judge2(p[i],p[j],p[k]) <<endl;
                    if ( judge1(p[i],p[j],p[k]) && judge2(p[i],p[j],p[k])) f = false;
                }
    
                if (f) ans++;
            }
    
        printf("%lld\n",ans*2);
        return 0;
    }
    
  • 0
    @ 2016-03-23 07:44:27

    QWQ#include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<set>
    using namespace std;
    typedef long long ll;
    struct point
    {
    ll x,y;
    void input()
    {
    ll _x,_y;
    scanf("%I64d%I64d",&_x,&_y);
    x=_x; y=_y;
    }
    bool operator == (const point &p) const
    {
    return x==p.x && y==p.y;
    }
    bool operator < (const point &p) const
    {
    return x==p.x ? y<p.y : x<p.x;
    }
    }a[305];
    struct line
    {
    ll a,b,c;//ax+by+c=0
    bool operator < (const line &l) const
    {
    if(a==l.a)
    {
    if(b==l.b)return c<l.c;
    else return b<l.b;
    }
    else return a<l.a;
    }
    };
    ll gcd(ll x,ll y)
    {
    return y==0 ? x : gcd(y,x%y);
    }
    bool online(point p,line l)
    {
    return l.a*p.x+l.b*p.y+l.c==0;
    }
    line makeline(point p,point q)
    {
    line t;
    t.a=p.y-q.y;
    t.b=q.x-p.x;
    t.c=-t.a*p.x-t.b*p.y;
    if(t.a==0)//by+c=0
    {
    if(t.c==0)t.b=1;
    else
    {
    ll g=gcd(t.b,t.c);
    t.b/=g;
    t.c/=g;
    if(t.b<0)
    {
    t.b=-t.b;
    t.c=-t.c;
    }
    }
    }
    else if(t.b==0)//ax+c=0
    {
    if(t.c==0)t.a=1;
    else
    {
    ll g=gcd(t.a,t.c);
    t.a/=g;
    t.c/=g;
    if(t.a<0)
    {
    t.a=-t.a;
    t.c=-t.c;
    }
    }
    }
    else if(t.c==0)//ax+by=0
    {
    ll g=gcd(t.a,t.b);
    t.a/=g;
    t.b/=g;
    if(t.a<0)
    {
    t.a=-t.a;
    t.b=-t.b;
    }
    }
    else
    {
    ll g=gcd(gcd(t.a,t.b),t.c);
    t.a/=g;
    t.b/=g;
    t.c/=g;
    if(t.a<0)
    {
    t.a=-t.a;
    t.b=-t.b;
    t.c=-t.c;
    }
    }
    return t;
    }
    vector<point>b;
    set<point>q;
    set<line>s;
    int main()
    {
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
    a[i].input();
    if(!q.count(a[i]))q.insert(a[i]);
    }
    set<point>::iterator itr;
    int cnt=q.size();
    for(itr=q.begin();itr!=q.end();itr++)
    b.push_back(*itr);
    q.clear();
    ll ans=0;
    for(int i=0;i<cnt;i++)
    {
    for(int j=i+1;j<cnt;j++)
    {
    line l=makeline(b[i],b[j]);
    if(!s.count(l))
    {
    s.insert(l);
    ll res=0;
    for(int k=0;k<cnt;k++)
    if(online(b[k],l))res++;
    ans+=res-1;
    }
    }
    }
    printf("%I64d",ans*2);
    return 0;
    }

  • 0
    @ 2015-02-13 21:49:55

    1234

  • 1

信息

ID
1920
难度
7
分类
组合数学 | 容斥原理 点击显示
标签
(无)
递交数
166
已通过
31
通过率
19%
被复制
1
上传者