lightOJ 1366 Pair of Touching Circles(统计矩形内相切圆对)

题目链接:http://lightoj.com/volume_showproblem.php?problem=1366

题意:给出一个矩形,在内部画两个圆A和B使得AB都完全在矩形内且AB相切且AB的圆心和半径都是整数。求有多少个这样的画法?

思路:总的来说,相切有两种情况:(1)水平或垂直方向相切。这个比较简单,枚举两个圆的直径,然后分水平垂直两种情况,计算较小的那个圆可以移动的范围,其实可以移动的范围是一个矩形;(2)斜着相切。这时候两个圆心的距离必然是一个勾股数。所以枚举勾股数,然后再枚举小圆的半径,这时候我们可以计算出两个圆在X和Y方向的跨度,也就是一个矩形。然后判断这个矩形在整个大矩形中有多少可以放置的位置,这里可以横着放和竖着放两种情况。注意,在一种矩形中,两个圆可以左上右下或者左下右上两种方式。然后两个圆半径不等时还可以再交换位置。

 



vector<int> a,b,c;
int cnt,n,m;

void init()
{
    int i,j,k,t;
    FOR1(i,1000) FOR(j,i,1000)
    {
        k=i*i+j*j;
        t=sqrt(1.0*k);
        if(t*t==k) a.pb(i),b.pb(j),c.pb(t);
        else if((t-1)*(t-1)==k) a.pb(i),b.pb(j),c.pb(t-1);
        else if((t+1)*(t+1)==k) a.pb(i),b.pb(j),c.pb(t+1);
    }
    cnt=SZ(a);
}

i64 cal()
{
    if(n>m) swap(n,m);
    i64 ans=0;
    int i,j,x,y;
    for(i=2;i<=n;i+=2) for(j=i;j<=m;j+=2)
    {
        x=m-j+1-i;
        y=n-j+1;
        if(x>0&&y>0)
        {
            ans+=x*y;
            if(i!=j) ans+=x*y;
        }
        x=n-j+1-i;
        y=m-j+1;
        if(x>0&&y>0)
        {
            ans+=x*y;
            if(i!=j) ans+=x*y;
        }
    }
    int xx,yy;
    for(i=0;i<cnt&&a[i]<=n;i++) for(j=1;j+j<=c[i]&&c[i]<=m;j++)
    {
        xx=max(a[i]+c[i],(c[i]-j)*2);
        yy=max(b[i]+c[i],(c[i]-j)*2);
        x=n+1-xx;
        y=m+1-yy;
        if(x>0&&y>0)
        {
            ans+=x*y*2;
            if(j+j!=c[i]) ans+=x*y*2;
        }
        x=m+1-xx;
        y=n+1-yy;
        if(x>0&&y>0)
        {
            ans+=x*y*2;
            if(j+j!=c[i]) ans+=x*y*2;
        }
    }
    return ans;
}

int main()
{
    init();
    int num=0;
    rush()
    {
        RD(n,m);
        printf("Case %d: ",++num);
        PR(cal());
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Sigma函数是指一个数字的所有因子之和。给定一个数字n,需要求出有多少个数字的Sigma函数是偶数。\[2\] 为了解决这个问题,可以先筛选出n范围内的素数(范围在10^6即可),然后对n进行素因子分解。对于每个因子,如果它的Sigma函数中连乘的每一项都是偶数,那么整个Sigma函数就是偶数。具体实现中,可以判断每个因子的平方根是否为偶数,如果是偶数,则减去(平方根+1)/2。\[1\] 另外,还可以使用O(1)的做法来解决这个问题。根据观察,所有的完全平方数及其两倍的值都会导致Sigma函数为偶数。因此,可以直接计算n的平方根,然后减去(平方根+1)/2即可得到结果。\[3\] #### 引用[.reference_title] - *1* [Sigma Function](https://blog.csdn.net/PNAN222/article/details/50938232)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [【LightOJ1336】Sigma Function(数论)](https://blog.csdn.net/qq_30974369/article/details/79009498)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值