网易笔试编程题-不要二

来源:互联网 发布:ddms 数据库 编辑:程序博客网 时间:2024/06/05 19:57

题目描述:
二货小易有一个W*H的网格盒子,网格的行编号为0~H-1,网格的列编号为0~W-1。每个格子至多可以放一块蛋糕,任意两块蛋糕的欧几里得距离不能等于2。
对于两个格子坐标(x1,y1),(x2,y2)的欧几里得距离为:
( (x1-x2) * (x1-x2) + (y1-y2) * (y1-y2) ) 的算术平方根
小易想知道最多可以放多少块蛋糕在网格盒子里。
输入描述:
每组数组包含网格长宽W,H,用空格分割.(1 ≤ W、H ≤ 1000)
输出描述:
输出一个最多可以放的蛋糕数
输入例子:
3 2
输出例子:
4
分析:“任意两块蛋糕的欧几里得距离不能等于2”是解决这道题问题的关键。首先需要了解什么是“欧几里得距离”,通俗来讲,两点之间的距离就是欧几里得距离,因此,在网格中,只有横向和纵向才可能欧几里得距离为2,因此,可以将问题简化为“任意两块蛋糕的横向或纵向的距离不能为2”。
画图说明:
这里写图片描述

假设网格是一个 11 X 9 的网格,满足条件的蛋糕位置用红色方格标记,因此,我们只要算出网格中的总红方格数。为此,我们将网格分成四部分,分别用蓝色,紫色和黄色表示。蓝色部分的长宽为四的倍数,紫色部分又分为两部分,右侧长为四的倍数,宽为总宽减去蓝色部分的宽,底下部分的宽为四的倍数,长为总长度减去蓝色部分长度,黄色部分为右下角剩余部分,黄色部分显示如下:
这里写图片描述
因为网格的长宽是被四整除处理过的,所以右下角的黄色部分是不会出现4 x 4的网格的,但可能出现 3 x 4,2 x 4, 1 x 4等,所以方便起见,我还是贴出了4 x 4的网格方便大家查阅。黄色部分中的网格怎么计算呢?我分成了四种情况:
1. 黄色部分的长宽对4取余都小于等于2,则说明黄色部分的红框集中在左上角,那么只需将两个余数相乘即可得到红色方框的个数。
2. 黄色部分的长对4取余小于等于2且宽大于2,则说明红色方框集中于左半侧,那么红色方框个数为长对4的余数 乘以2。
3. 黄色部分的宽对4取余小于等于2且长大于2,则说明红色方框集中于上半侧,那么红色方框个数为 宽对4取余的余数 乘以 2
4. 其他情况是黄色部分的长宽均大于2,则说明红色方框个数为左上脚四个方框 加上 右下角多余出来的方框个数,右下角多出来的红色方框个数计算方法为:(长%4 - 2)* (宽%4 - 2)。
程序代码如下:

#include <iostream>using namespace std;int main(void){    int W, H;    cin >> W >> H;    int cakeNum = 0;    cakeNum += (W/4) * (H/4) * 8;    int last_W = W - W/4 * 4;    int last_H = H - H/4 * 4;    if (last_W != 0)    {        cakeNum += H/4 * 4 * last_W / 2;    }    if (last_H != 0)    {        cakeNum += W/4 * 4 * last_H / 2;    }    if (last_H != 0 && last_W != 0)    {        if (W%4 <= 2 && H%4 <= 2)        {            cakeNum += (W%4) * (H%4);        }        else if (W%4 > 2 && H%4 <= 2)        {            cakeNum += 2 * (H%4);        }        else if (H%4 > 2 && W%4 <= 2)        {            cakeNum += 2 * (W%4);        }        else        {            cakeNum += 4 + (H%4 - 2) * (W%4 - 2);        }    }    cout << cakeNum << endl;    return 0;}

值得注意的是 取余运算符的优先级 小于 乘除运算符的优先级,所以先取余再算乘除需要给取余的运算式加上括号,不要忘喽。
若有不对之处,敬请指正。

0 0
原创粉丝点击