HDU 6398 Pizza Hub(计算几何 三角形放置)

2023-10-10 03:40

本文主要是介绍HDU 6398 Pizza Hub(计算几何 三角形放置),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

http://acm.hdu.edu.cn/showproblem.php?pid=6398

题意:

给一个可旋转的三角形,求一个宽为W的矩形的最小高度,使得这个三角形可以塞进去

解析:

一定有一个点在边上,所以枚举每个点P做(吉如一jls推荐的旋转平移流)

  • 平移坐标系使得P落在原点
    在这里插入图片描述

  • 选择第二个点K,尝试这样放
    在这里插入图片描述

  • 如果不行,就这样放
    在这里插入图片描述

  • 或者这样
    在这里插入图片描述

  • 通过K的旋转,计算得到最后一个点K2的位置

    • 这里需要注意由于精度误差,两个夹角为180度的向量,acos内的部分可能是 − 1.0000001 -1.0000001 1.0000001,这样acos的结果会是nan
      在这里插入图片描述
  • 用这三个点计算答案
    在这里插入图片描述

代码:

/**  Author : Jk_Chen*    Date : 2021-03-27-13.51.34*/
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i, a, b) for (int i = (int)(a); i <= (int)(b); i++)
#define per(i, a, b) for (int i = (int)(a); i >= (int)(b); i--)
#define mmm(a, b) memset(a, b, sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
void test()
{cerr << "\n";
}
template <typename T, typename... Args>
void test(T x, Args... args)
{cerr << "> " << x << " ";test(args...);
}
const LL mod = 1e9 + 7;
const int maxn = 1e5 + 9;
const int inf = 0x3f3f3f3f;
LL rd()
{LL ans = 0;char last = ' ', ch = getchar();while (!(ch >= '0' && ch <= '9'))last = ch, ch = getchar();while (ch >= '0' && ch <= '9')ans = ans * 10 + ch - '0', ch = getchar();if (last == '-')ans = -ans;return ans;
}
#define rd rd()
/*_________________________________________________________begin*/
#define F double
F eps=1e-9;
const F pi=acos(-1);struct point{F x,y;point(){}point(F x,F y):x(x),y(y){}
};
typedef point Vector;
typedef point Point;
Vector operator + (Vector a, Vector b){//向量加法return Vector(a.x + b.x, a.y + b.y);
}
Vector operator - (Vector a, Vector b){//向量减法return Vector(a.x - b.x, a.y - b.y);
}
Vector operator * (Vector a, F p){//向量数乘return Vector(a.x*p, a.y*p);
}
Vector operator / (Vector a, F p){//向量数除return Vector(a.x / p, a.y / p);
}
int dcmp(F x){//精度三态函数(>0,<0,=0)if (fabs(x) < eps)return 0;else if (x > 0)return 1;return -1;
}
bool operator == (const Point &a, const Point &b){//向量相等return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
}
F Dot(Vector a, Vector b){//内积return a.x*b.x + a.y*b.y;
}
F Length(Vector a){//模return sqrt(Dot(a, a));
}
F Cross(Vector a, Vector b){//外积return a.x*b.y - a.y*b.x;
}
F Angle(Vector a, Vector b)
{ //夹角,弧度制F d2 = Dot(a, b) / Length(a) / Length(b);if (d2 < -1)d2 = -1;if (d2 > 1)d2 = 1;F ang = acos(d2);if (Cross(a, b) < 0){ang = -ang;}return ang;
}
Vector Rotate(Vector a, F rad){//逆时针旋转return Vector(a.x*cos(rad) - a.y*sin(rad), a.x*sin(rad) + a.y*cos(rad));
}
Vector RotateTogether(Vector A1, Vector A2, Vector C){ //A1旋转到A2后,C应该旋转到哪里F ang = Angle(A1, A2);return Rotate(C, ang);
}
F Distance(Point a, Point b){//两点间距离return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));
}
F Area(Point a, Point b, Point c){//三角形面积return fabs(Cross(b - a, c - a) / 2);
}
bool Intersect(Point a, Point b, Point c, Point d){//线段相交(不包括端点)F t1 = Cross(c - a, d - a)*Cross(c - b, d - b);F t2 = Cross(a - c, b - c)*Cross(a - d, b - d);return dcmp(t1) < 0 && dcmp(t2) < 0;
}
bool StrictIntersect(Point a, Point b, Point c, Point d){ //线段相交(包括端点)returndcmp(max(a.x, b.x) - min(c.x, d.x)) >= 0&& dcmp(max(c.x, d.x) - min(a.x, b.x)) >= 0&& dcmp(max(a.y, b.y) - min(c.y, d.y)) >= 0&& dcmp(max(c.y, d.y) - min(a.y, b.y)) >= 0&& dcmp(Cross(c - a, d - a)*Cross(c - b, d - b)) <= 0&& dcmp(Cross(a - c, b - c)*Cross(a - d, b - d)) <= 0;
}
F DistanceToLine(Point A, Point M, Point N){//点A到直线MN的距离,Error:MN=0return fabs(Cross(A - M, A - N) / Distance(M, N));
}
Point GetLineIntersection(Point P, Vector v, Point Q, Vector w){//两直线的交点Vector u = P - Q;F t = Cross(w, u) / Cross(v, w);return P + v * t;
}
void check(F &ans, point a[3], F m)
{F X = max(max(a[0].x, a[1].x), a[2].x) - min(min(a[0].x, a[1].x), a[2].x);F Y = max(max(a[0].y, a[1].y), a[2].y) - min(min(a[0].y, a[1].y), a[2].y);if (dcmp(X - m) <= 0){ans = min(ans, Y);}if (dcmp(Y - m) <= 0){ans = min(ans, X);}
}
F rdF()
{double x;scanf("%lf", &x);return (F)x;
}
void __()
{point a[3];point b[3];F ans = 1e18;rep(i, 0, 2)a[i].x = rdF(),a[i].y = rdF();F m = rdF();rep(i, 0, 2){int k = (i + 1) % 3;int k2 = (i + 2) % 3;rep(j, 0, 2)b[j] = a[j];rep(j, 0, 2){if (j != i)b[j] = b[j] - b[i];}b[i] = {0, 0};if (Length(b[k]) <= m){point bb = {Length(b[k]), 0};b[k2] = RotateTogether(b[k], bb, b[k2]);b[k] = bb;check(ans, b, m);}else{if (1){point bb = {m, sqrt(Length(b[k]) * Length(b[k]) - m * m)};b[k2] = RotateTogether(b[k], bb, b[k2]);b[k] = bb;check(ans, b, m);}if (1){rep(j, 0, 2)b[j] = a[j];rep(j, 0, 2){if (j != i)b[j] = b[j] - b[i];}b[i] = {0, 0};point bb = {m, -sqrt(Length(b[k]) * Length(b[k]) - m * m)};b[k2] = RotateTogether(b[k], bb, b[k2]);b[k] = bb;check(ans, b, m);}}}if (ans > 1e17){puts("impossible");}else{printf("%.10f\n", (double)ans);}
}int main()
{int t = rd;while (t--){__();}return 0;
}/*_________________________________________________________end*/

这篇关于HDU 6398 Pizza Hub(计算几何 三角形放置)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/177684

相关文章

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

hdu 2093 考试排名(sscanf)

模拟题。 直接从教程里拉解析。 因为表格里的数据格式不统一。有时候有"()",有时候又没有。而它也不会给我们提示。 这种情况下,就只能它它们统一看作字符串来处理了。现在就请出我们的主角sscanf()! sscanf 语法: #include int sscanf( const char *buffer, const char *format, ... ); 函数sscanf()和

hdu 2602 and poj 3624(01背包)

01背包的模板题。 hdu2602代码: #include<stdio.h>#include<string.h>const int MaxN = 1001;int max(int a, int b){return a > b ? a : b;}int w[MaxN];int v[MaxN];int dp[MaxN];int main(){int T;int N, V;s

uva 10387 Billiard(简单几何)

题意是一个球从矩形的中点出发,告诉你小球与矩形两条边的碰撞次数与小球回到原点的时间,求小球出发时的角度和小球的速度。 简单的几何问题,小球每与竖边碰撞一次,向右扩展一个相同的矩形;每与横边碰撞一次,向上扩展一个相同的矩形。 可以发现,扩展矩形的路径和在当前矩形中的每一段路径相同,当小球回到出发点时,一条直线的路径刚好经过最后一个扩展矩形的中心点。 最后扩展的路径和横边竖边恰好组成一个直

hdu 1754 I Hate It(线段树,单点更新,区间最值)

题意是求一个线段中的最大数。 线段树的模板题,试用了一下交大的模板。效率有点略低。 代码: #include <stdio.h>#include <string.h>#define TREE_SIZE (1 << (20))//const int TREE_SIZE = 200000 + 10;int max(int a, int b){return a > b ? a :

hdu 1166 敌兵布阵(树状数组 or 线段树)

题意是求一个线段的和,在线段上可以进行加减的修改。 树状数组的模板题。 代码: #include <stdio.h>#include <string.h>const int maxn = 50000 + 1;int c[maxn];int n;int lowbit(int x){return x & -x;}void add(int x, int num){while

hdu 3790 (单源最短路dijkstra)

题意: 每条边都有长度d 和花费p,给你起点s 终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。 解析: 考察对dijkstra的理解。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstrin

hdu 2489 (dfs枚举 + prim)

题意: 对于一棵顶点和边都有权值的树,使用下面的等式来计算Ratio 给定一个n 个顶点的完全图及它所有顶点和边的权值,找到一个该图含有m 个顶点的子图,并且让这个子图的Ratio 值在所有m 个顶点的树中最小。 解析: 因为数据量不大,先用dfs枚举搭配出m个子节点,算出点和,然后套个prim算出边和,每次比较大小即可。 dfs没有写好,A的老泪纵横。 错在把index在d

hdu 1102 uva 10397(最小生成树prim)

hdu 1102: 题意: 给一个邻接矩阵,给一些村庄间已经修的路,问最小生成树。 解析: 把已经修的路的权值改为0,套个prim()。 注意prim 最外层循坏为n-1。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstri