取三角形(排列组合 )
2017-02-17 18:17
686 查看
Bzoj3505 数三角形
题意:在一个n * m的方格中数出有多少以顶点组成的三角形;
思路:一共有(n + 1)* (m + 1)个点,首先有C(3,(n+ 1)*(m + 1))种组成方法,然后除去三点共线的情况就行了;
三点共线的情况如下,1,首先是在水平线上或者在垂直线上的,为(n + 1)* C(3,m+ 1) + (m + 1) * C(3,n + 1);
2,接下来就是考虑斜线的情况,设i,j,代表的是两个点在一个长宽分别为i,j的矩形的两个对点,那么这两个点当成组成三角形的两个点,那么使三点共线的第三个点自然在两点之间,根据性质,中间的点的个数为gcd(i,j) - 1;然后可以正斜和负斜,*2,这个矩形可以进行上下和左右平移,所以*(m + 1 - i) *(n + 1 - j);
代码:
题意:在一个n * m的方格中数出有多少以顶点组成的三角形;
思路:一共有(n + 1)* (m + 1)个点,首先有C(3,(n+ 1)*(m + 1))种组成方法,然后除去三点共线的情况就行了;
三点共线的情况如下,1,首先是在水平线上或者在垂直线上的,为(n + 1)* C(3,m+ 1) + (m + 1) * C(3,n + 1);
2,接下来就是考虑斜线的情况,设i,j,代表的是两个点在一个长宽分别为i,j的矩形的两个对点,那么这两个点当成组成三角形的两个点,那么使三点共线的第三个点自然在两点之间,根据性质,中间的点的个数为gcd(i,j) - 1;然后可以正斜和负斜,*2,这个矩形可以进行上下和左右平移,所以*(m + 1 - i) *(n + 1 - j);
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; #define MOD 2147493647 const int maxn = 26; ll combine(ll y) { ll ans = y *(y - 1) * (y - 2) / 6; return ans; } ll gcd(ll x,ll y) { if(y == 0) return x; return gcd(y,x % y); } int main() { ll n,m; while( ~ scanf("%lld%lld",&n,&m ) ) { ll ans = combine((n + 1)*(m + 1)); ll sum = 0; for(int i = 1; i <= n; i ++) { for(int j = 1; j <= m; j ++) { sum += (gcd(i,j) - 1)*(n + 1 - i) * (m+ 1 - j); } } ans -= (combine(m+1)*(n + 1) + combine(n+ 1)*(m+ 1)); cout << ans - 2 * sum << endl; } return 0; }
相关文章推荐
- 【排列组合】bzoj3505 [Cqoi2014]数三角形
- 组合与排列的表达:pascal三角形和母函数
- bzoj 3505: [Cqoi2014]数三角形 排列组合+数学
- 组合数学中排列组合一点理解
- 回溯实现数组元素的排列组合
- 【排列组合 乘法逆元】【bzoj 3398】: [Usaco2009 Feb]Bullcow 牡牛和牝牛
- 结果值在int类型内的排列组合计算
- 字符串的排列组合问题
- 2012ICPC长春站 B Candy 【快速排列组合】
- 轻松用python实现排列组合功能
- 使用php计算排列组合的方法
- 字符串的全排列和组合算法
- 生成某字符串的所有排列组合
- 字符串的排列组合问题
- Java版排列组合工具类 - Java Permutation and Combination Tools
- 排列组合问题
- VB.NET 排列组合算法实现
- 排列组合实现
- 康拓展开(八数码编码、排列组合)
- 一中OJ #3167 排列组合数计算[2] | 高级数论 组合计数 | 解题报告