TZOJ 2519 Regetni(N个点求三角形面积为整数总数)

时间:2024-01-01 00:04:08

描述

Background
Hello Earthling. We're from the planet Regetni and need your help to make lots of money. Maybe we'll even give you some of it.
You
see, the problem is that in our world, everything is about integers.
It's even enforced by law. No other numbers are allowed for anything.
That said, it shouldn't surprise you that we use integer coordinate
systems to plan our cities. So far only axis-aligned rectangular plots
of land have been sold, but our professor Elgnairt recently had the
revolutionary idea to sell triangular plots, too. We believe that the
high society will love this concept and it'll make us rich.
Unfortunately
the professor patented his idea and thus we can't just do it. We need
his permission and since he's a true scientist, he won't give it to us
before we solve some damn riddle. Here's where you come in,because we
heard that you're a genius.

Problem
The professor's riddle
goes like this: Given some possible corners for the triangles, determine
how many triangles with integral size can be built with them.
Degenerated triangles with empty area (i.e. lines) have to be counted,
too, since 0 is an integer. To be more precise, count the number of
triangles which have as corners three different points from the input
set of points. All points in a scenario will be distinct, i.e. there
won't be duplicates. Here are some examples:

TZOJ 2519 Regetni(N个点求三角形面积为整数总数)
Example
a) shows a triangle with integral area (namely 3), b) shows one with
non-integral size, c) shows a degenerated triangle with empty area (i.e.
zero, so count it!), d) shows four points of which you can choose any
three to build an integral area triangle and e) shows four points where
you can't build any integral area triangles at all.
Hint: The area A of a triangle with corners (x1, y1), (x2, y2) and (x3, y3) can be computed like this:
A=|x1y2 - y1x2 + x2y3 - y2x3 + x3y1 - y3x1|/2
Try to make clever use of this formula.

输入

The
first line contains the number of scenarios. For each scenario, there
is one line containing first the number N of distinct points in that
scenario (0 <= N <= 10000) and after that N pairs of integers,
each pair describing one point (xi, yi) with -100000 <= xi, yi <=
100000. All these numbers are separated by single blanks.

输出

Start
the output for every scenario with a line containing "Scenario #i:",
where i is the number of the scenario starting at 1. Then print a single
line containing the number of triangles with integral area whose three
distinct corners are among the points given. Terminate the output for
each scenario with a blank line.

样例输入

6
3 0 0 2 0 1 -3
3 0 0 2 1 1 -3
3 0 0 2 2 3 3
4 0 0 2 0 0 2 2 2
4 0 0 1 0 0 1 1 1
9 0 0 0 1 0 2 1 0 1 1 1 2 2 0 2 1 2 2

样例输出

Scenario #1:
1

Scenario #2:
0

Scenario #3:
1

Scenario #4:
4

Scenario #5:
0

Scenario #6:
48
题意

给你N个点,求三角形面积为整数的总数

题解

A=|x1y2 - y1x2 + x2y3 - y2x3 + x3y1 - y3x1|/2

要使公式为整数,|x1y2 - y1x2 + x2y3 - y2x3 + x3y1 - y3x1|为偶

三个点P(x1,y1),Q(x2,y2),C(x3,y3)

可以发现上面的公式和PQC三点的x和y的奇偶性有关

令0=x偶y偶,1=x偶y奇,2=x奇y偶,3=x奇y奇。

打表完后利用组合数求个和。

代码

 #include<bits/stdc++.h>
using namespace std; struct point
{
int p,q,c;
bool operator<(const point &d)const{
if(p<d.p)return true;
else if(p==d.p)
{
if(q<d.q)return true;
else if(q==d.q)
{
if(c<d.c)return true;
}
}
return false;
}
};
set<point>v;
void cs()
{
pair<int,int>po[];
po[]={,};
po[]={,};
po[]={,};
po[]={,};
for(int p=;p<;p++)
for(int q=;q<;q++)
for(int c=;c<;c++)
{
int x1,x2,x3,y1,y2,y3;
x1=po[p].first;y1=po[p].second;
x2=po[q].first;y2=po[q].second;
x3=po[c].first;y3=po[c].second;
if((x1*y2-y1*x2+x2*y3-y2*x3+x3*y1-y3*x1)%==)
{
int d[];
d[]=p;
d[]=q;
d[]=c;
sort(d,d+);
v.insert({d[],d[],d[]});
}
}
}
long long C(int n,int m)
{
if(m>n)return ;
long long sum=;
for(int i=;i<=m;i++)
sum=sum*(n-i+)/i;
return sum;
}
int main()
{
cs();
int t,n,ca=;
scanf("%d",&t);
while(t--)
{
int d[]={};
scanf("%d",&n);
for(int i=;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
if(x%==&&y%==)d[]++;
if(x%==&&y%!=)d[]++;
if(x%!=&&y%==)d[]++;
if(x%!=&&y%!=)d[]++;
}
long long sum=;
for(auto x:v)
{
int p=x.p;
int q=x.q;
int c=x.c;
printf("%d %d %d\n",p,q,c);
int f[]={};
f[p]++;f[q]++;f[c]++;
sum+=C(d[],f[])*C(d[],f[])*C(d[],f[])*C(d[],f[]);
}
printf("Scenario #%d:\n%lld\n\n",ca++,sum);
}
return ;
}