Triangles
1010: Triangles
Time Limit: 2 Sec Memory Limit: 128 MBSubmit: 18 Solved: 8
Description
You are given a figure consisting of n 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 n and m. (n ≤ 200, m ≤ 20000)
Each of the following n lines contains two real numbers xi and yi indicating the coordinates of the i-th point. (−100000 < xi, yi < 100000)
Each of the following m lines contains four real numbers xi, yi, xj, yj . It means (xi,yi) and (xj,yj) are connected by a segment. We guarantee that these points are part of the given n points.
Output
For each test case, print a single line contains the total number of triangles in the given figure.
Sample Input
Sample Output
#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:暑假训练第二场