UVALive 5815 Pair of Touching Circles

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3826


题意:给出一个N*M的方格,要求2个相切的圆的圆心(x,y)都在方格上,且半径为整数,问一共有多少种情况


思路:刚开始时想要枚举每一个点,在枚举2个圆的半径,求出所有情况,但是没有想到圆的半径为勾当数的情况,后来研究了下标程,枚举的思路是可行的,但是有几个地方没看懂+_+,然后还看到有人用枚举半径画矩阵的方法做,通过枚举半径,把不同大小的矩阵里可以有多少方案预处理,在枚举累加便可以


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define LL long long
#define maxn 1011
using namespace std;


LL g[maxn][maxn];
short int f[2000000];
void init()
{
    for (int i=0;i<maxn;i++)
     for (int j=0;j<maxn;j++)
     {
         if (i==0 && j==0) continue;
         int tem=i*i+j*j;
         int tem2=sqrt(tem);
         if (tem2*tem2!=tem) continue;
         for (int r1=1;r1<tem2;r1++)
         {
             int r2=tem2-r1;
             int x=max(i+r1+r2,2*max(r1,r2));
             int y=max(j+r1+r2,2*max(r1,r2));
             if (x>maxn || y>maxn) continue;
             if (i==0 || j==0) g[x][y]++;
             else g[x][y]+=2;
         }
     }

}

int main()
{
    init();
    int t,cas=0;
    scanf("%d",&t);
    while (t--)
    {
        cas++;
        int l,h;
        LL res=0;
        scanf("%d%d",&l,&h);

        for (int i=1;i<=l;i++)
         for (int j=1;j<=h;j++)
          res+=g[i][j]*(l-i+1)*(h-j+1);

        printf("Case %d: %lld\n",cas,res);
    }

}


你可能感兴趣的:(UVALive 5815 Pair of Touching Circles)