n×m 網格點((n+1)×(m+1) 個點)。選 3 點組成三角形(非共線)。求三角形總數。n,m ≤ 1000,多測試案例。
P = (n+1)*(m+1),任選 3 點:C(P, 3)(n+1) * C(m+1, 3)(m+1) * C(n+1, 3)2 * (g-1) * (n+1-dx) * (m+1-dy)(2 為正負斜率)#include#include using namespace std; typedef long long ll; ll C3(ll x) { return x*(x-1)*(x-2)/6; } ll gcd(ll a, ll b) { return b ? gcd(b, a%b) : a; } int main() { ll n, m; while (~scanf("%lld%lld", &n, &m)) { ++n; ++m; // 點數 ll ans = C3(n*m) - C3(n)*m - C3(m)*n; for (ll dx = 2; dx < n; ++dx) for (ll dy = 2; dy < m; ++dy) { ll g = gcd(dx, dy) - 1; if (g > 0) ans -= g * (n-dx) * (m-dy) * 2; } printf("%lld\n", ans); } return 0; }
gcd(dx,dy)-1 為向量內部網格點數此題展示了組合數學 + 數論(gcd)解決幾何計數問題,看似暴力實則最優。