網易筆試編程題-不要二

題目描述:
二貨小易有一個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;
}

值得注意的是 取餘運算符的優先級 小於 乘除運算符的優先級,所以先取餘再算乘除需要給取餘的運算式加上括號,不要忘嘍。
若有不對之處,敬請指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章