BSOJ 3899 -- 【CQOI2014】 數三角形
阿新 • • 發佈:2018-12-11
Description
給定一個n*m的網格,請計算三個點都在格點上的三角形共有多少個。下圖為4*4的網格上的一個三角形。 注意三角形的三點不能共線。
Input
輸入一行,包含兩個空格分隔的正整數m和n。
Output
輸出一個正整數,為所求三角形的數量。
Sample Input
樣例輸入1:1 1
樣例輸入2:2 2
Sample Output
樣例輸出1:4
樣例輸出2:76
先求出全集,再去掉三點共線的情況。
那如何列舉三點共線的情況呢?先將橫豎兩種情況算了,再考慮斜著的。列舉斜著的方法有很多,但比較可行的是先固定兩個點,再計算兩個點之間的點數。具體實現就是列舉兩點的相對位置,也可以理解為向量
這麼列舉的好處是,兩點之間的相對位置去確定了之後,中間點的數量就確定了。
程式碼:
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<queue> #include<set> #include<map> #include<vector> #include<ctime> #define ll long long using namespace std; inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;} ll n,m; ll ans,tot; ll gcd(ll a,ll b) {return !b?a:gcd(b,a%b);} int main() { n=Get(),m=Get(); n++,m++; tot=n*m; ans=tot*(tot-1)/2*(tot-2)/3; if(n>=3) ans-=n*(n-1)/2*(n-2)/3*m; if(m>=3) ans-=m*(m-1)/2*(m-2)/3*n; for(int i=1;i<n;i++) { for(int j=1;j<m;j++) { ans-=(n-i)*(m-j)*(gcd(i,j)-1)*2; } } cout<<ans; return 0; }