题目:给你一个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;
}
UVa 12373 - Pair of Touching Circles,布布扣,bubuko.com
UVa 12373 - Pair of Touching Circles
原文:http://blog.csdn.net/mobius_strip/article/details/22825549