UVALive 3295 Counting Triangles(组合计数)
2014-03-25 10:42
295 查看
题意:给出一个m×n的网格点中能组成的三角形的个数。
思路:直接算很难入手,可以发现任意三个点可以组成一个三角形当且仅当三点不共线,因此可以用总的方案数-三点共线的方案数。三点形成的直线是水平或者垂直的很好算。主要问题是不共线的方案的计数,受之前做的UVALive 3295 Counting Triangles的启发,用dp[i][j]表示以(0,0)为左上角,(i,j)为右下角的矩形中三点共线的方案数,则dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+lcnt[i][j],lcnt[i][j]为这个矩阵中,包含(i,j)这个点的方案数。这个数组可以预处理出来,把这个问题转化成(i,j)代表的矩阵中,和左上角相连的方案的个数,可以发现这两个是对称的。。。所以直接这么求就行,某一个点的方案数为gcd(i,j)-1,这里需要一点数论的知识就可以发现……注意这里dp[i][j]只算了斜线方向为左下方向的,所以最后要*2。
代码:
思路:直接算很难入手,可以发现任意三个点可以组成一个三角形当且仅当三点不共线,因此可以用总的方案数-三点共线的方案数。三点形成的直线是水平或者垂直的很好算。主要问题是不共线的方案的计数,受之前做的UVALive 3295 Counting Triangles的启发,用dp[i][j]表示以(0,0)为左上角,(i,j)为右下角的矩形中三点共线的方案数,则dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+lcnt[i][j],lcnt[i][j]为这个矩阵中,包含(i,j)这个点的方案数。这个数组可以预处理出来,把这个问题转化成(i,j)代表的矩阵中,和左上角相连的方案的个数,可以发现这两个是对称的。。。所以直接这么求就行,某一个点的方案数为gcd(i,j)-1,这里需要一点数论的知识就可以发现……注意这里dp[i][j]只算了斜线方向为左下方向的,所以最后要*2。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<map> #include<queue> #include<stack> #include<set> #include<cmath> #include<vector> #define inf 0x3f3f3f3f #define Inf 0x3FFFFFFFFFFFFFFFLL #define eps 1e-9 #define pi acos(-1.0) using namespace std; typedef long long ll; const int maxn=1000+10; ll lcnt[maxn][maxn],dp[maxn][maxn]; int gcd(int a,int b) {return b==0?a:gcd(b,a%b);} void Init() { memset(lcnt,0,sizeof(lcnt)); memset(dp,0,sizeof(dp)); for(int i=1;i<maxn;++i) for(int j=1;j<maxn;++j) lcnt[i][j]=gcd(i,j)-1; for(int i=1;i<maxn;++i) for(int j=1;j<maxn;++j) lcnt[i][j]+=lcnt[i-1][j]; for(int i=1;i<maxn;++i) for(int j=1;j<maxn;++j) lcnt[i][j]+=lcnt[i][j-1]; for(int i=1;i<maxn;++i) for(int j=1;j<maxn;++j) dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+lcnt[i][j]; } inline ll cal(int x) { if(x<3) return 0; return (ll)x*(x-1)*(x-2)/6; } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int m,n,tcase=0; Init(); while(~scanf("%d%d",&m,&n)) { if(n==0&&m==0) break; tcase++; ll ans=cal((m+1)*(n+1))-(m+1)*cal(n+1)-(n+1)*cal(m+1)-dp[m] *2; printf("Case %d: %lld\n",tcase,ans); } return 0; }
相关文章推荐
- 格点统计问题(UVALive 3295,UVALive 3720)
- UVALive 4807||SYSU 2379 Cocircular Points 几何
- uvalive3942(前缀树)
- UVALive 6437
- Boat - UVaLive 2511 价值改变的01背包
- UVaLive3942
- uvalive 3266 - Tian Ji -- The Horse Racing(贪心)
- UVALive 5066 - Fire Drill (BFS+01背包)
- Amritapuri 2009 (UValive 4676 ) - Geometry Problem
- UVALIVE 3713 Astronauts(2-SAT)
- 【UVALive】7338 Toll Management IV
- UVALive 6659 Dromicpalin Substrings 枚举判断
- hihocoder1426||UVALive - 7672 What a Ridiculous Election
- 【并查集】UVALive3027 Corporative Network
- UVa_Live 3664(精度坑)
- UVALive4886 E - Page Count 模拟
- UVaLive 7512 November 11th (思维漏洞)
- UVAlive 7511
- uvalive 3890 半平面交
- uvalive 3218 卷包裹算法