题目:给你一个n*m的矩形的空间,在里面放入,圆心和半径都是整数的2个相切圆。
有多少种不同的方法,旋转后相同的认为是不同的。
分析:数论。两圆有一个最小的放置边界矩形,求出矩形的摆放个数即可。
能够符合题目条件的只有两种情况:
1.两圆的连心线与矩形的边界平行;
2.两圆的连心线是斜边,但是是勾股数组中的斜边。
#include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> using namespace std; typedef struct dnode { int a,b,c; dnode( int A, int B, int C ) {a = A;b = B;c = C;} dnode(){} }data; data D[1000]; int maps[1005][1005]; int main() { //打表计算勾股数组,共881个 int count = 0; D[count ++] = data( 3, 4, 5 ); for ( int i = 10 ; i <= 1000 ; ++ i ) for ( int j = 8 ; j < i ; ++ j ) for ( int k = 5 ; k < j ; ++ k ) if ( k*k + j*j == i*i ) { D[count].a = k; D[count].b = j; D[count].c = i; count ++; } //计算这些勾股数组组成的矩形 memset( maps, 0, sizeof(maps) ); for ( int i = 0 ; i < count ; ++ i ) for ( int j = 1 ; j < D[i].c ; ++ j ) { int W = max( D[i].a+D[i].c, (max(j,D[i].c-j))<<1 ); int H = max( D[i].b+D[i].c, (max(j,D[i].c-j))<<1 ); if ( W <= 1000 && H <= 1000 ) { maps[W][H] += 2; maps[H][W] += 2; } } int T,H,W; while ( scanf("%d",&T) != EOF ) for ( int t = 1 ; t <= T ; ++ t ) { scanf("%d%d",&H,&W); long long sum = 0LL; for ( int h = 2 ; h <= H ; h += 2 ) for ( int w = 2 ; w <= W ; w += 2 ) { if ( h < w && w < 2*h || w < h && h < 2*w ) sum += (W-w+1)*(H-h+1)*2; if ( h == 2*w || w == 2*h ) sum += (W-w+1)*(H-h+1); } for ( int h = 2 ; h <= H ; ++ h ) for ( int w = 2 ; w <= W ; ++ w ) sum += maps[h][w]*(W-w+1)*(H-h+1); printf("Case %d: %lld\n",t,sum); } return 0; }
原文:http://blog.csdn.net/zhumaill/article/details/22821843