C基于贪心思想实现网格盒子欧几里得距离不等于固定数的最大分布

题目:二货小易有一个W*H的网格盒子,网格的行编号为0 ~ H-1,网格的列编号为0 ~ W-1。每个格子至多可以放一块蛋糕,任意两块蛋糕的欧几里得距离不能等于2。对于两个格子坐标(x1,y1),(x2,y2)的欧几里得距离为: (x1-x2) * (x1-x2) + (y1-y2) * (y1-y2) ) 的算术平方根。小易想知道最多可以放多少块蛋糕在网格盒子里。

引用:引用原文链接

满足欧几里得距离不等于2,则同一行中任意两块蛋糕的距离一定大于等于2或者为0才可以,在任意斜对角线上的蛋糕都不可能满足欧几里得距离为2,贪心思想尽可能实现两个蛋糕一起放

  1. 先考虑最简单的情况:行数、列数都是 4 的倍数
    在这里插入图片描述
    如图,这是一个 4 × 8 大小的盒子:图中一个黄色圆占了四个空格,这四个空格可以放四块蛋糕并且满足欧几里得距离小于2,放完4块蛋糕蛋再隔两个空再放入, 我把四个格子看成一组
    从左上角开始四个一组放蛋糕,每放一组空一组:

    由于行列数都是 4 的倍数,而一组蛋糕只要占用两行两列,所以放入的黄点数量必定为偶数个,且放入蛋糕数量和空出的格子数量相等。
    若设总格子数为:S = W * H,则放入蛋糕数为 S / 2。
    并且,由下面四幅图我们可以推出:只要行数或列数为4的倍数,上式仍然成立(下图中半圆表示两块蛋糕,)
    在这里插入图片描述

  2. 如果行数和列数都不是4的整数倍,但是行数列数都为 2 的倍数,我们依然可以将每个盒子用四个一组的蛋糕放满,但是情况和 1 不一样了,于是出现了这种情况:
    . 在这里插入图片描述
    可以发现:黄圈总是比空圈多一个,若设总的组数为 S = W×H÷4,记蛋糕组数为 count,则使用int类型的除法可得,count = (S + 1)/2。蛋糕数即为4倍的count。

  3. 若只有行数或列数一方为 2 的倍数,另一个为奇数,则会出现某一行或列的黄圈被切了一半的情况,只需要补一个对称的盒子再使用情况2中的方法进行处理即可。 若是行列数都是奇数,同样可以补成2的形式,例如:
    在这里插入图片描述
    如果行和列只有一方是奇数则总的组数为S = W×H×2÷4,count = (S + 1)/2,蛋糕数即为count÷2×4,如果行和列都是奇数则总的组数为S = (W×2)×(H×2)÷4,count = (S + 1)/2,蛋糕数即为count÷4×4
    代码实现如下:
    由于在计算组数时候容易出现小数,因此在代码中尽量求避免单独的蛋糕组数

#include<stdio.h>
int main(){
    int L, H, S, count; //L列,H是行,count组数也用来表示是蛋糕得数量
    scanf(("%d %d"),&L,&H );
        //行或者列有一方是4的整数倍
        if(L% 4 == 0 || H % 4 == 0){
            S = L * H;
            count = S/2;
           
        //情况2:行和列都是2的整数倍
        else if(L % 2 == 0 && H % 2 == 0){ 
            S = L * H / 4;
            count = (S + 1) / 2;
            count *= 4;
        }
        
        //行和列有一方是2的整数倍,另一方奇数
        else if(L % 2 == 0 || H % 2 == 0){
            //S先乘2把它变成行列都是偶数的情况,再求组数除以4, 转成情况2
             S = (L * H *2)/4;
             count = (S + 1); 
        }
        
         //行和列都是奇数
        else{
            //扩充4倍, 转成情况2
            S = (L * 2) * (H * 2) / 4;
            count = (S + 1) / 2;  //直接计算避免小数出现
        }
        printf("%d\n",count);
    
    return 0;
}
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页