Non-interger Area
链接+内容
链接:https://ac.nowcoder.com/acm/contest/11185/B
来源:牛客网
题目描述
给定平面上 \(n\) 个整点(横纵坐标均为整数的点)(可能重合),编号为 \(A_1\sim A_n\),从中选出三个编号不同的点 \(A_i,A_j,A_k\)(其中 \(i\) 小于 \(j\) 小于 \(k\))组成一个三角形。有几种选法使得三角形的面积不是整数?
输入描述:
第一行一个正整数 \(n\ (1\le n\le 10^5)\)。
接下来 \(n\) 行,第 \(i\) 行两个整数 \(x,y\),表示 \(A_i=(x,y)\)。\((|x|,|y|\le 10^{18})\)
输出描述:
输出一行一个非负整数,为答案。
思路
- 向量\(I_1=(a,b),I_2=(c,d)\)围成的三角形面积\(S\)为\(\frac {(I_1 \times I_2)} {2}\),即\(\frac {(a*d)-(b*c)} {2}\)
- 因此,只要\(a*d-b*c\)为奇数,\(S\)就不是整数
- 且当\(a,b,c,d\) 奇偶确定时,\(a*d-b*c\)的奇偶一定能确定
- 所以只要统计向量坐标的每种奇偶组合的个数,即可计算出总数
代码
#include<bits/stdc++.h>
#define N 100005
using namespace std;
typedef long long ll;
int n,a,b,c,d;
ll ax,ay,anscnt=0;
int cnt[4];ll x[N],y[N];//11 22 12 21
//1111 2 2222 2 1212 2 1112 1 1211 1 1222 2 2221
inline void solve(){
for(int i=1;i<=n-2;++i){
if(x[i]%2 && y[i]%2) a=cnt[1],b=--cnt[0],c=cnt[3],d=cnt[2];
else if(!(x[i]%2) && y[i]%2) a=cnt[2],b=--cnt[3],c=cnt[0],d=cnt[1];
else if(x[i]%2 && !(y[i]%2)) a=cnt[3],b=--cnt[2],c=cnt[1],d=cnt[0];
else if(!(x[i]%2) && !(y[i]%2)) a=cnt[0],b=--cnt[1],c=cnt[2],d=cnt[3];
anscnt+=a*(c+d)+c*d;
}
cout<<anscnt<<'\n';
}
int main(){
cin>>n;
for(int i=1;i<=n;++i){
scanf("%lld%lld",&ax,&ay);
x[i]=ax,y[i]=ay;
if(ax%2 && ay%2) ++cnt[0];
else if(ax%2 && !(ay%2)) ++cnt[2];
else if(!(ax%2) && !(ay%2)) ++cnt[1];
else if(!(ax%2) && ay%2) ++cnt[3];
}
solve();
return 0;
}
标签
几何,组合,计数

浙公网安备 33010602011771号