您的位置:首页 > 其它

取三角形(排列组合 )

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);

代码:

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: