[BZOJ4920][Lydsy六月月赛]薄饼切割
[BZOJ4920][Lydsy六月月赛]薄饼切割
试题描述
有一天,tangjz 送给了 quailty 一张薄饼,tangjz 将它放在了水平桌面上,从上面看下去,薄饼形成了一个 \(H \times W\) 的长方形。
tangjz 交给了 quailty 一根木棍,要求 quailty 将木棍轻轻放到桌面上。然后 tangjz 会以薄饼中心作为原点,将木棍绕着原点旋转一圈,将木棍扫过的部分切下来送给 quailty。
quailty 已经放好了木棍,请写一个程序帮助他们计算 quailty 得到了多少面积的薄饼。
输入
第一行包含一个正整数 \(T(1 \le T \le 1000)\),表示测试数据的组数。
每组数据包含一行 \(6\) 个整数 \(H,W,x_1,y_1,x_2,y_2(1 \le H,W \le 10000,|x_1|,|y_1|,|x_2|,|y_2| \le 10000)\),其中 \(H\) 和 \(W\) 表示薄饼的长和宽,\((x_1,y_1)\) 和 \((x_2,y_2)\) 分别表示木棍两端点的坐标。
输入数据保证木棍两端点不会重合。
输出
对于每组数据,输出一行一个实数,即 quailty 得到的面积,与标准答案的绝对或相对误差不超过 \(10^{-8}\) 时会被认为是正确的。
输入示例
2
3 2 -4 0 -4 -3
1 5 -4 -3 4 2
输出示例
0.0000000000000
4.4352192982310
数据规模及约定
见“输入”
题解
不难发现扫过的面就是一个大圆和长方形的交减去小圆和长方形的交。
下面令 \(P_1(x_1, y_1), P_2(x_2, y_2)\),\(O\) 为原点。
首先需要确定大圆小圆的半径。大圆的半径就是线段 \(P_1P_2\) 到原点的最大距离,即 \(\max \{ |OP_1|, |OP_2| \}\)。小圆的半径则是线段 \(P_1P_2\) 到原点的最小距离,如果过原点做 \(P_1P_2\) 所在直线的垂线与 \(P_1P_2\) 有交的话(这个可以用向量的点积判断),距离就是这个垂线段的长度,可以直接用面积法计算出来;如果没有交点那就是 \(\min \{ |OP_1|, |OP_2| \}\)。
接下来考虑如何计算一个半径为 \(r\),圆心为 \(O\) 的圆与四个顶点坐标分别为 \(\begin{Bmatrix} \left( -\frac{W}{2}, \frac{H}{2} \right), \left( \frac{W}{2}, \frac{H}{2} \right), \left( \frac{W}{2}, -\frac{H}{2} \right), \left( -\frac{W}{2}, -\frac{H}{2} \right) \end{Bmatrix}\) 的矩形的交集的面积。
这个东西还是分类讨论一下:
- 如果圆将整个矩形包含(即 \(2r \ge \sqrt{W^2 + H^2}\)),则面积为 \(W \cdot H\);
- 否则就是一个圆的面积减去几个弓形的面积(注意判断一下是否与上下、左右边界相交),这个弓形的面积就是扇形的面积减去一个三角形的面积,可以利用
acos(x)(即 \(\arccos(x)\))函数得到扇形的角度从而得到扇形面积,用叉积计算三角形的面积。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <cmath>
using namespace std;
#define rep(i, s, t) for(int i = (s), mi = (t); i <= mi; i++)
#define dwn(i, s, t) for(int i = (s), mi = (t); i >= mi; i--)
int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
}
const double pi = acos(-1.0);
struct Vec {
double x, y;
Vec() {}
Vec(double _, double __): x(_), y(__) {}
Vec operator - (const Vec& t) const { return Vec(x - t.x, y - t.y); }
double operator * (const Vec& t) const { return x * t.x + y * t.y; }
double operator ^ (const Vec& t) const { return x * t.y - y * t.x; }
double len() { return sqrt(x * x + y * y); }
};
double OutArea(double h, double a) {
double c = sqrt(a * a - h * h), S = pi * a * a * acos(h / a) / pi;
S -= abs(Vec(c, h) ^ Vec(-c, h)) / 2.0;
return S;
}
double Area(double H, double W, double r) {
if(H > W) swap(H, W);
if(r >= sqrt(H * H + W * W) / 2.0) return H * W;
double S = pi * r * r;
if(r > H / 2.0) S -= 2.0 * OutArea(H / 2.0, r);
if(r > W / 2.0) S -= 2.0 * OutArea(W / 2.0, r);
return S;
}
double calcDis(Vec p1, Vec p2) {
if(min((p1 - p2) * (Vec(0, 0) - p2), (p2 - p1) * (Vec(0, 0) - p1)) < 0) return min(p1.len(), p2.len());
return abs(p1 ^ p2) / (p1 - p2).len();
}
void work() {
int H = read(), W = read(), x1 = read(), y1 = read(), x2 = read(), y2 = read();
double l = calcDis(Vec(x1, y1), Vec(x2, y2)), r = max(Vec(x1, y1).len(), Vec(x2, y2).len());
printf("%.13lf\n", Area(H, W, r) - Area(H, W, l));
return ;
}
int main() {
int T = read();
while(T--) work();
return 0;
}
[BZOJ4920][Lydsy六月月赛]薄饼切割的更多相关文章
- BZOJ4920: [Lydsy1706月赛]薄饼切割
BZOJ4920: [Lydsy1706月赛]薄饼切割 Description 有一天,tangjz送给了quailty一张薄饼,tangjz将它放在了水平桌面上,从上面看下去,薄饼形成了一个H*W的 ...
- 【BZOJ4919】[Lydsy六月月赛]大根堆 线段树合并
[BZOJ4919][Lydsy六月月赛]大根堆 Description 给定一棵n个节点的有根树,编号依次为1到n,其中1号点为根节点.每个点有一个权值v_i. 你需要将这棵树转化成一个大根堆.确切 ...
- 【BZOJ4922】[Lydsy六月月赛]Karp-de-Chant Number 贪心+动态规划
[BZOJ4922][Lydsy六月月赛]Karp-de-Chant Number Description 卡常数被称为计算机算法竞赛之中最神奇的一类数字,主要特点集中于令人捉摸不透,有时候会让水平很 ...
- bzoj 4921: [Lydsy六月月赛]互质序列
4921: [Lydsy六月月赛]互质序列 Time Limit: 1 Sec Memory Limit: 256 MBSubmit: 188 Solved: 110[Submit][Status ...
- bzoj 4919: [Lydsy六月月赛]大根堆
Description 给定一棵n个节点的有根树,编号依次为1到n,其中1号点为根节点.每个点有一个权值v_i. 你需要将这棵树转化成一个大根堆.确切地说,你需要选择尽可能多的节点,满足大根堆的性质: ...
- 【BZOJ4919】[Lydsy六月月赛]大根堆
题解: 我觉得数据结构写成结构体还是有必要的 因为不然一道题里出现了两个相同的数据结构由于名字很像很容易出错 另外初始化用segmenttree(){ } 首先裸的dp很好想 f[i][j]表示在i点 ...
- 【bzoj4921】[Lydsy六月月赛]互质序列 暴力
题目描述 给出一个序列,要求删除一段非空区间,使得剩下的数的个数大于等于2.求所有删除方式剩下的数的最大公约数的和. 输入 第一行包含一个正整数n(3<=n<=100000),表示序列的长 ...
- 【bzoj4922】[Lydsy六月月赛]Karp-de-Chant Number 贪心+背包dp
题目描述 给出 $n$ 个括号序列,从中选出任意个并将它们按照任意顺序连接起来,求以这种方式得到匹配括号序列的最大长度. 输入 第一行包含一个正整数n(1<=n<=300),表示括号序列的 ...
- 【BZOJ5072】[Lydsy十月月赛]小A的树 树形DP
[BZOJ5072][Lydsy十月月赛]小A的树 题解:考虑我们从一个联通块中替换掉一个点,导致黑点数量的变化最多为1.所以我们考虑维护对于所有的x,y的最大值和最小值是多少.如果询问的y在最大值和 ...
随机推荐
- p标签内不能含有块元素。
原来一直听网上这样说.自己并没有实际遇到过.上例子. <!DOCTYPE html> <html> <head> <meta charset="ut ...
- 【tp5.1】七牛云上传图片
composer安装: composer require qiniu/php-sdk 配置使用: 在tp5.1的配置文件app.php中配置七牛云的参数 'qiniu' => [ 'access ...
- phpstudy配置域名后apache无法启动
1.设置域名后重启 apache停止了 检查步骤1.php路径不要有中文,phpstudy重新安装在无中文路径 2.检查80端口是否被占用,如果被占用可以停止该程序或者修改apache/nginx 端 ...
- CentOS下安装pip
CentOS下安装pip 通常情况下使用命令: yum -y install pip 也有可能报错,无法安装.这是应该使用第二种方法. 1.首先需要先安装扩展源EPEL: yum -y install ...
- 一个 mr 作业跑的比较慢,如何来优化。
mr跑的慢可能有很多原因,如:数据倾斜.map和reduce数设置不合理.reduce等待过久.小文件过多.spill 次数过多. merge 次数过多等. 1.解决数据倾斜:数据倾斜可能是parti ...
- 07 json与os模块(进阶)
json和os模块 阶段一 .数据交换 1.json的基本介绍 JSON全名是JavaScript Object Notation(即:JavaScript对象标记)它是JavaScript的子集. ...
- C语言Windows程序开发—CreateWindow函数介绍【第03天】
(一)CreateWindow函数的参数介绍: HWND CreateWindow( LPCTSTR lpClassName, //Windows窗口中预定义的控件结构体,包括:BUTTON(按钮), ...
- 洛谷U32670 小凯的数字(比赛)
题目网址 https://www.luogu.org/problemnew/show/U32670 题目背景 NOIP2018 原创模拟题T1 NOIP DAY1 T1 or DAY 2 T1 难度 ...
- Spyder在windows下常用快捷键
块注释/反块注释:Ctrl+4/5 行注释/反行注释:Ctrl+1 代码提示:Tab 复制一行:Ctrl+Alt+↓/↑ 删除一行:Ctrl+D 运行:F5 全屏:F11 撤销:Ctrl+Z 反撤销: ...
- PHP.39-扩展-锁机制解决并发-MySQL锁、PHP文件锁
锁机制适用于高并发场景:高并发订单.秒杀…… apache压力测试 Mysql锁详解 语法 加锁:LOCK TABLE 表名1 READ|WRITE, 表名2 READ|WRITE ......... ...