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})\)

输出描述:

输出一行一个非负整数,为答案。

思路

  1. 向量\(I_1=(a,b),I_2=(c,d)\)围成的三角形面积\(S\)\(\frac {(I_1 \times I_2)} {2}\),即\(\frac {(a*d)-(b*c)} {2}\)
  2. 因此,只要\(a*d-b*c\)为奇数,\(S\)就不是整数
  3. 且当\(a,b,c,d\) 奇偶确定时,\(a*d-b*c\)的奇偶一定能确定
  4. 所以只要统计向量坐标的每种奇偶组合的个数,即可计算出总数

代码

#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;
}

标签

几何,组合,计数

posted @ 2022-02-21 22:57  qingmuhe  阅读(55)  评论(2)    收藏  举报