码迷,mamicode.com
首页 > 其他好文 > 详细

zoj 3647 智商题

时间:2015-04-06 00:52:46      阅读:221      评论:0      收藏:0      [点我收藏+]

标签:

技术分享 技术分享

此题就是求格点中三角形的个数。

就是找出三点不共线的个数。

n*m的矩形中有(n+1)*(m+1)个格点。

选出三个点的总个数为:C((n+1)*(m+1),3).

减掉共线的情况就是答案了。

首先是水平和垂直共线的情况:C(n+1,3)*(m+1)+C(m+1,3)*(n+1);

然后斜的共线的情况就是枚举矩形。

斜着共线的三点用枚举法n*m的矩形,对角两个点中间共有gcd(m,n)-1个点,两条对角线,所以数量*2,大矩形里共有(N-n+1)*(M-m+1)个的矩形,一并去除

 1 #include<stdio.h>
 2 #include<iostream>
 3 #include<string.h>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 int gcd(int a,int b)
 8 {
 9     if(b==0)return a;
10     return gcd(b,a%b);
11 }
12 long long Com(int n,int r)
13 {
14     if(n<r)return 0;//这个一定要
15     if(n-r<r)r=n-r;
16     int i,j;
17     long long ret=1;
18     for(i=0,j=1;i<r;i++)
19     {
20         ret*=(n-i);
21         for(;j<=r&&ret%j==0;j++)ret/=j;
22     }
23     return ret;
24 }
25 int main()
26 {
27     int n,m;
28     while(scanf("%d%d",&n,&m)!=EOF)
29     {
30         long long  ans=Com((n+1)*(m+1),3);//选三个点的所有组合数
31         for(int i=2;i<=n;i++)
32           for(int j=2;j<=m;j++)
33           {
34               ans-=(long long)(gcd(i,j)-1)*(n-i+1)*(m-j+1)*2;
35           }
36         ans-=Com(n+1,3)*(m+1);
37         ans-=Com(m+1,3)*(n+1);
38         printf("%lld\n",ans);//ZOJ用lld,不能用I64d
39     }
40     return 0;
41 }

 

zoj 3647 智商题

标签:

原文地址:http://www.cnblogs.com/cnblogs321114287/p/4395025.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!