【LightOJ】1058 - Parallelogram Counting(暴力计数)
2016-08-15 10:10
633 查看
点击打开题目
1058 - Parallelogram Counting
There are n distinct points in the plane, given by their integer coordinates. Find the number of parallelograms whose vertices lie on these points. In other words, find the number of 4-element subsets of these points that can be written
as {A, B, C, D} such that AB || CD, and BC || AD. No four points are in a straight line.
The first line of each test case contains an integer n (1 ≤ n ≤ 1000). Each of the next n lines, contains 2 space-separated integers x and y (the coordinates of a point)
with magnitude (absolute value) of no more than 1000000000.
差点wa到放弃比赛的题。刚开始思路是先选出所有平行的线,然后去掉三点共线的,然后除以2就得到结果,但是还是TLE了。
后来把线的向量全部放到一四象限(这一点出了小问题,查了俩小时),然后再计数的时候同时判断三点共线,这样就省时间了,最后终于查出来了。
代码如下:
#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;
#define CLR(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define LL long long
struct node
{
int x,y;
}dot[1011];
struct node2
{
int a,b;
int x,y;
}edge[500500];
bool check(node2 a,node2 b)
{
if (a.a == b.a || a.a == b.b || a.b == b.a || a.b == b.b)
return false; //三点共线
if ((dot[b.b].x - dot[a.a].x) * a.y == (dot[b.b].y - dot[a.a].y) * a.x)
return false;
return true;
}
bool cmp(node2 a,node2 b)
{
if (a.x == b.x)
return a.y < b.y;
return a.x < b.x;
}
int main()
{
int u;
int n;
int Case = 1;
scanf ("%d",&u);
while (u--)
{
scanf ("%d",&n);
for (int i = 0 ; i < n ; i++)
scanf ("%d %d",&dot[i].x,&dot[i].y);
int ans = 0;
int ant = 0;
for (int i = 0 ; i < n ; i++)
{
for (int j = i + 1 ; j < n ; j++)
{
edge[ant].x = dot[i].x - dot[j].x;
edge[ant].y = dot[i].y - dot[j].y;
edge[ant].a = i;
edge[ant].b = j;
if (edge[ant].x <= 0 && edge[ant].y <= 0)
{
edge[ant].x = -edge[ant].x;
edge[ant].y = -edge[ant].y;
}
if (edge[ant].x <= 0 && edge[ant].y >= 0) //这里y的值可能由第一个x的值改变
{
edge[ant].x = -edge[ant].x;
edge[ant].y = -edge[ant].y;
}
ant++;
}
}
sort(edge , edge+ant , cmp);
int st = 0;
while (st < ant)
{
int i,j;
for (i = st ; edge[i].x == edge[st].x && edge[i].y == edge[st].y ; i++)
{
for (j = i + 1 ; edge[j].x == edge[st].x && edge[j].y == edge[st].y ; j++)
{
if (check(edge[i],edge[j]))
ans++;
}
}
st = i;
}
ans >>= 1;
printf ("Case %d: %d\n",Case++,ans);
}
return 0;
}
1058 - Parallelogram Counting
PDF (English) | Statistics | Forum |
Time Limit: 2 second(s) | Memory Limit: 32 MB |
as {A, B, C, D} such that AB || CD, and BC || AD. No four points are in a straight line.
Input
Input starts with an integer T (≤ 15), denoting the number of test cases.The first line of each test case contains an integer n (1 ≤ n ≤ 1000). Each of the next n lines, contains 2 space-separated integers x and y (the coordinates of a point)
with magnitude (absolute value) of no more than 1000000000.
Output
For each case, print the case number and the number of parallelograms that can be formed.Sample Input | Output for Sample Input |
2 6 0 0 2 0 4 0 1 1 3 1 5 1 7 -2 -1 8 9 5 7 1 1 4 8 2 0 9 8 | Case 1: 5 Case 2: 6 |
后来把线的向量全部放到一四象限(这一点出了小问题,查了俩小时),然后再计数的时候同时判断三点共线,这样就省时间了,最后终于查出来了。
代码如下:
#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;
#define CLR(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define LL long long
struct node
{
int x,y;
}dot[1011];
struct node2
{
int a,b;
int x,y;
}edge[500500];
bool check(node2 a,node2 b)
{
if (a.a == b.a || a.a == b.b || a.b == b.a || a.b == b.b)
return false; //三点共线
if ((dot[b.b].x - dot[a.a].x) * a.y == (dot[b.b].y - dot[a.a].y) * a.x)
return false;
return true;
}
bool cmp(node2 a,node2 b)
{
if (a.x == b.x)
return a.y < b.y;
return a.x < b.x;
}
int main()
{
int u;
int n;
int Case = 1;
scanf ("%d",&u);
while (u--)
{
scanf ("%d",&n);
for (int i = 0 ; i < n ; i++)
scanf ("%d %d",&dot[i].x,&dot[i].y);
int ans = 0;
int ant = 0;
for (int i = 0 ; i < n ; i++)
{
for (int j = i + 1 ; j < n ; j++)
{
edge[ant].x = dot[i].x - dot[j].x;
edge[ant].y = dot[i].y - dot[j].y;
edge[ant].a = i;
edge[ant].b = j;
if (edge[ant].x <= 0 && edge[ant].y <= 0)
{
edge[ant].x = -edge[ant].x;
edge[ant].y = -edge[ant].y;
}
if (edge[ant].x <= 0 && edge[ant].y >= 0) //这里y的值可能由第一个x的值改变
{
edge[ant].x = -edge[ant].x;
edge[ant].y = -edge[ant].y;
}
ant++;
}
}
sort(edge , edge+ant , cmp);
int st = 0;
while (st < ant)
{
int i,j;
for (i = st ; edge[i].x == edge[st].x && edge[i].y == edge[st].y ; i++)
{
for (j = i + 1 ; edge[j].x == edge[st].x && edge[j].y == edge[st].y ; j++)
{
if (check(edge[i],edge[j]))
ans++;
}
}
st = i;
}
ans >>= 1;
printf ("Case %d: %d\n",Case++,ans);
}
return 0;
}
相关文章推荐
- LightOJ-1284 Lights inside 3D Grid (概率&计数)
- lightoj-1058 - Parallelogram Counting
- Lightoj 1058
- lightoj 1294 - Positive Negative Sign 【基础计数】
- HDU-1058-Humble Numbers(暴力打表)
- LightOJ - 1259 Goldbach`s Conjecture 素数打表+暴力(我见过的最快的打表姿势)
- HDU-1058 Humble Numbers 暴力 Or 动态规划
- HDU 1058 Humble Numbers 【暴力(DFS)】
- LightOJ 1231 Coin Change (I) (背包计数模板题)
- Lightoj 1122【计数DP】
- lightoj-1058 - Parallelogram Counting【计算几何】(思维)
- hdu2089 不要62(暴力打表计数,数位DP)
- HDU 5952 2016沈阳现场赛E Counting Cliques (团计数暴力)
- LightOJ 1055 Going Together (暴力搜索……繁琐)
- Lightoj 1058 (组合数学)
- lightoj 1058 - Parallelogram Counting (几何,平行四边形)
- Again Array Queries---Lightoj1100(循环暴力)
- BZOJ 1016 最小生成树计数 暴力
- Ifter Party LightOJ - 1014(暴力枚举+set)
- HDU 5701 中位数计数 暴力