lightoj1366Pair of Touching Circles

来源:互联网 发布:php获取服务器ip地址 编辑:程序博客网 时间:2024/06/06 02:36

思路:给出一个矩形的宽w和高h,要在这个矩形中画两个圆,圆是外切的,且圆完全在矩形内部,圆心在整数点上面,两个的半径都是整数。求有多少种画法。

因为是相切的,所以两点之间的距离是其半径和,为整数。我们可以枚举两个圆A,B的相对位置,A在B的左下方,枚举的是B相对A的x,y值,x,y不同时为0。这样以来x <= h/2,y <= w/2。

这样之后就要求能装下这两个圆的最小矩形了(平行于坐标轴的)。看是否满足条件完全在大矩形内,最后求这个大矩形中有多少个小矩形。

有两种情况:

1:AB的圆心连线与坐标轴平行。

2:AB的圆心连线不与坐标轴平行。

主要是第二种情况,因为只枚举了B在A的右上方的情况,还有右下方没有枚举,但是又对称性可知,右上等于右下,乘2就是了。

// #pragma comment(linker, "/STACK:1024000000,1024000000")#include <iostream>#include <algorithm>#include <iomanip>#include <sstream>#include <string>#include <stack>#include <queue>#include <deque>#include <vector>#include <map>#include <set>#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <climits>using namespace std;#define DEBUG#ifdef DEBUG#define debug(...) printf( __VA_ARGS__ )#else#define debug(...)#endif#define CLR(x) memset(x, 0,sizeof x)#define MEM(x,y) memset(x, y,sizeof x)#define pk push_backtemplate<class T> inline T Get_Max(const T&a,const T&b){return a < b?b:a;}template<class T> inline T Get_Min(const T&a,const T&b){return a < b?a:b;}typedef long long LL;typedef unsigned long long ULL;typedef pair<int,int> ii;const double eps = 1e-10;const int inf = 1 << 30;const int INF = 0x3f3f3f3f;const int MOD = 1e9 + 7;const int maxn = 1010;int GetDistance(int x,int y){int m = (int)sqrt(x*x+y*y+0.1);if (m*m==x*x+y*y) return m;return 0;}int v[maxn][maxn];inline void Init(){for (int i = 0;i <= 500;++i)for (int j = 0;j <= 500;++j)v[i][j] = GetDistance(i,j);}int h,w;inline int In(int x,int y){return (h-x+1)*(w-y+1);}inline void Solve(){LL sum = 0;for (int i = 0;i <= h/2;++i){for (int j = 0;j <= w/2;++j){if (v[i][j]){for (int k = 1;k < v[i][j];++k){int y1 = Get_Min(-k,j-v[i][j]+k), y2 = Get_Max(k,j+v[i][j]-k);int x1 = Get_Min(-k,i-v[i][j]+k), x2 = Get_Max(k,i+v[i][j]-k);int x = x2 - x1;int y = y2 - y1;if (x>h || y>w) continue;int tmp = In(x,y);if (i>0&&j>0) tmp <<= 1;sum += 1LL*tmp;// debug("here\n");}}}}cout << sum << endl;}int main(){// freopen("in.txt","r",stdin);// freopen("out.txt","w",stdout);int t, icase = 0;scanf("%d",&t);Init();while(t--){scanf("%d%d",&h,&w);printf("Case %d: ", ++icase);Solve();}return 0;}


0 0