Triangles

1010: Triangles

Time Limit: 2 Sec   Memory Limit: 128 MB
Submit: 18   Solved: 8

Description

You are given a figure consisting of points in a 2D-plane and m segments connecting some of them. We guarantee that any two segments don’t share points except their ends and there’s no more than one segment between the same pair of points. Please count the total number of triangles in the given figure. 

 

Input

There’re multiple test cases. In each case:
The first line contains two positive integers 
and m. (≤ 200, ≤ 20000)

Each of the following lines contains two real numbers xand yindicating the coordinates of the i-th point. (100000 < xi, y100000)

Each of the following m lines contains four real numbers xiyixjy. It means (xi,yi) and (xj,yj) are connected by a segment. We guarantee that these points are part of the given points. 

 

Output

For each test case, print a single line contains the total number of triangles in the given figure. 

 

Sample Input

4 5
0 0
1 1
2 0
1 0
0 0 1 1
1 1 2 0
2 0 1 0
1 0 0 0
1 1 1 0

Sample Output

3

思路:题意是给你n个点,在这n个点里有m条连线,求这些线段最后组成多少个三角形。题目想好怎么做就不难了,大致就是先找出:三点在一条线上,但是只有两条连线,你必须找出这样的例子,并且把第三条线段加上,然后就是遍历所有的点,三点之间有连线且不共线,则组成三角形。
代码:
#include<iostream>
#include<stdio.h>
#include<cmath>
#include<map>
#include<cstring>
using namespace std;
const unsigned int MAX=200;
#define ERR 0.000001
struct Point
{
    double x,y;
}point[MAX+10];
int edge[MAX+10][MAX+10];
map <double,int> mymap;
bool in_line(Point a1,Point a2,Point a3)//判断是否共线
{
     if(fabs((a2.x-a1.x)*(a3.y-a2.y)-(a2.y-a1.y)*(a3.x-a2.x))<=ERR)
        return true;
     return false;
}
int main()
{
    //freopen("Triangles.in","r",stdin);
    int m,n,i,j,k,ans;
    int u,v;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        mymap.clear();
        memset(edge,0,sizeof(edge));
        ans=0;
        for(i=0;i<n;i++)
        {
            scanf("%lf%lf",&point[i].x,&point[i].y);
            mymap[point[i].x*20000+point[i].y]=i;
        }
        for(i=0;i<m;i++)
        {
            double p1,q1,p2,q2;
            scanf("%lf%lf%lf%lf",&p1,&q1,&p2,&q2);
            u=mymap[p1*20000+q1];
            v=mymap[p2*20000+q2];
            //printf("u==%d  v==%d\n",u,v);
            edge[u][v]=edge[v][u]=1;//点与线之间联系起来
        }
        /*for(i=0;i<n;i++)
        {
            for(j=i+1;j<n;j++)
            {
                printf("edge[%d][%d]=%d  ",i,j,edge[i][j]);
            }
            printf("\n");
        }*/
        for(i=0;i<n;i++)
            for(j=0;j<n;j++)
                for(k=0;k<n;k++)
                    if(i!=j&&j!=k&&i!=k&&edge[j][i]&&edge[i][k]&&!edge[j][k]&&in_line(point[i],point[j],point[k]))
                        edge[j][k]=edge[k][j]=1;//三个点中,有两条连线,并且三点共线,加一条连线
        /*for(i=0;i<n;i++)//这种方法貌似可以,并且复杂度较低,但就是通不过,不知为啥
            for(j=i+1;j<n;j++)
                for(k=j+1;k<n;k++)
                {
                    //printf("point[%d] x=%lf  y=%lf   ",i,point[i].x,point[i].y);
                    //printf("point[%d] x=%lf  y=%lf   ",j,point[j].x,point[j].y);
                    //printf("point[%d] x=%lf  y=%lf   \n",k,point[k].x,point[k].y);
                    if(in_line(point[i],point[j],point[k]))
                    {
                        if((edge[i][j]&&(edge[j][k]||edge[i][k]))||(edge[j][k]&&edge[i][k]))
                            edge[i][j]=edge[i][k]=edge[j][k]=edge[j][i]=edge[k][i]=edge[k][j]=1;
                    }
                }*/
        for(i=0;i<n;i++)//扫描所有点,三点两两之间有连线,且不共线,则组成三角形
            for(j=i+1;j<n;j++)
                for(k=j+1;k<n;k++)
                {
                    if(edge[i][j]&&edge[i][k]&&edge[j][k]&&!in_line(point[i],point[j],point[k]))
                        ans++;
                }
        printf("%d\n",ans);
    }
    return 0;
}

FROM:暑假训练第二场

 

posted @ 2013-07-11 18:36  爱生活,爱编程  阅读(272)  评论(0编辑  收藏  举报