首页 > 代码库 > zoj3647(组合数学)
zoj3647(组合数学)
题意:n*m的矩阵任选三个点,可以有多少种不同的三角形。
解法:组合数学C((n+1)*(m+1),3)是所有三个点的情况。然后在减掉共线的。共线的分为两种:
1、共横线或竖线:C(n+1,3)*(m+1)+C(m+1,3)*(n+1);
2,斜线的:这个要枚举矩形,然后三个点有两个取矩形的对角线,另一点枚举(对角线上的整数点个数是gcd(i,j)+1),这样可以做到不重复计算。
代码:
/****************************************************** * author:xiefubao *******************************************************/ #pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <vector> #include <algorithm> #include <cmath> #include <map> #include <set> #include <stack> #include <string.h> //freopen ("in.txt" , "r" , stdin); using namespace std; #define eps 1e-8 #define zero(_) (abs(_)<=eps) const double pi=acos(-1.0); typedef long long LL; const int Max=10100; const int INF=1000000007; LL C3(LL n) { return n*(n-1)*(n-2)/6; } LL C2(LL n) { return n*(n-1)/2; } int gcd(int a,int b) { return b==0?a:gcd(b,a%b); } int main() { LL n,m; while(scanf("%lld%lld",&n,&m)==2) { int grid=(n+1)*(m+1); LL ans=C3(grid); ans-=C3(n+1)*(m+1)+C3(m+1)*(n+1); for(int i=2;i<=n;i++) for(int j=2;j<=m;j++) ans-=(n-i+1)*(m-j+1)*(gcd(i,j)-1)*2; cout<<ans<<endl; } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。