『题解』铺地毯

题目描述

(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
", ans * 4);
    return 0;
}

友情提示

注意本题给定数据可能存在小数,如果将半径默认为整型会导致记录范围过小,遗漏部分符合条件的正方形。

原文地址:https://www.cnblogs.com/Frather/p/14304688.html