1. 程式人生 > 實用技巧 >『題解』鋪地毯

『題解』鋪地毯

題目描述

\(k\) 走進圖書館,看到一群工人正在新裝修過的圖書館大廳裡緊鑼密鼓地佈置場地。他們在大廳裡鋪了一張紅色的圓形地毯,地毯很大,蓋住了許多方形地磚。一位清潔工路過,無意中說了一句:“這下我可以少拖不少地了。”程式設計的學習,已經使 \(小\) k對萬事萬物充滿了好奇和探索之心,這簡單的一句話,引發了小 \(k\) 的思考:
假設圖書館大廳的正方形地磚邊長為 \(1\) ,鋪上一張半徑為 \(r\) 的圓形地毯,且該圓的圓心在某個格點上,如下圖所示。編寫一個程式,計算有多少方形地磚會被這個圓形地毯完全覆蓋。

題意簡化

向半徑為 \(r\) 的圓中填充邊長為 \(1\) 的小正方形,最多可以填充多少個。

解題思路

圓畢竟是一個正圓,可以求解圓的 \(\frac{1}{4}\) 甚至是更小。(此處選擇 \(\frac{1}{4}\) 個圓)

考慮到正方形組成的形狀不規則,按正方形的位置列舉理論上沒有問題,但是並不好實現,加之如果資料過大會面臨 \(TLE\)

那如何判斷某個正方形是否在圓內呢?不難發現,圓的位置事固定的,即圓心是固定,那麼只要判斷圓心到某正方形最遠點的對角線是否大於圓的半徑即可說明該正方形是否在圓內。

(只列出了部分對角線)

反正都是暴力列舉直接列舉各個點的橫縱座標。

然後記錄圓內正方形的數量,最後乘以 \(4\) 即可。

CODE

/*

Name: 鋪地毯

By Frather_

*/
#include <iostream>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>
#include <set>
#include <map>
#include <stack>
#define ll long long
#define InF 0x7fffffff
#define kMax 10e5
#define kMin -10e5
#define kMod 998244353
#define kMod2 19260817
#define kMod3 19660813
#define base 1331
using namespace std;
/*=========================================快讀*/
int read()
{
    int x = 0, f = 1;
    char c = getchar();
    while (c < '0' || c > '9')
    {
        if (c == '-')
            f = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9')
    {
        x = (x << 3) + (x << 1) + (c ^ 48);
        c = getchar();
    }
    return x * f;
}
/*=====================================定義變數*/
double r;
int ans;
/*===================================自定義函式*/
/*=======================================主函式*/
int main()
{
    scanf("%lf", &r);
    for (int i = (int)r; i >= 1; i--)
        for (int j = (int)r; j >= 1; j--)
        {
            if (sqrt(i * i + j * j) > r)
                continue;
            ans++;
        }
    printf("%d\n", ans * 4);
    return 0;
}

友情提示

注意本題給定資料可能存在小數,如果將半徑預設為整型會導致記錄範圍過小,遺漏部分符合條件的正方形。