HDU 6398 Pizza Hub 模拟,分内讨论

Pizza Hub

Time Limit: 3000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 765    Accepted Submission(s): 166
Special Judge

 

Problem Description

Coffee Chicken has started a new restaurant named Pizza Hu...b! It provides various styles of pizzas, hamburgers, sandwiches, coffee, chickens and many other awesome Western cuisines. Welcome to Pizza Hub after this Multi-University Training Contest!

Since the pizzas are so exquisite, it is never a bad thing to design nice paper pads for them. The pizzas provided in Pizza Hub are sliced into triangles. The rectangular-shaped paper pads are cut from a paper strip of fixed width which is long enough. The pizza should be placed entirely on the pad; however, their borders are allowed to touch. Also, you are allowed to rotate the pizza.

As the customized paper strip is rather expensive, minimizing the size of the pizza pad can save a lot of money. Can you determine the minimum possible height of the pizza pad, given the width of the paper strip? The following picture illustrates the first sample test case.
 

 

Input

The first line of the input is a single integer T (1≤T≤50000) , the number of test cases.

Each test case is a single line of seven integers x1,y1,x2,y2,x3,y3 (0≤x1,y1,x2,y2,x3,y3≤10000) and w (1≤w≤10000) , where (x1,y1) , (x2,y2) and (x3,y3) are Cartesian coordinates of the vertices of the pizza, and w is the width of the strip. It is guaranteed that the three vertices are not collinear.

 

Output

For each test case, display the minimum height of the pizza pad with an absolute or relative error of no more than 10−6 . If it is impossible to make a pizza pad, display impossible instead.

 

Sample Input

 

2 0 0 3 0 0 4 10 0 0 3 0 0 4 1

 

Sample Output

 

2.400000000 impossible

 

Source

2018 Multi-University Training Contest 8

题意: 给你一个宽一定,长无无限的矩形,再给你一个三角形,然后让你找一个面积最小的矩形使这个矩形刚好可以放下这个三角形,如果找不到那么就输出“impossible”。

思路:直接模拟就好,枚举每一条边,每一条边和长方形的宽比较如果比宽小,那么只要其余两条边最长的那条没有超出长方形的范围就好了,更新答案。如果比宽大那么就让这条边和矩形的组成一个直角三角形(尽量平),然后通过比较三角形的三个角的角度来判断三角形是否超出了这个直角三角形,如果没超出那么这个那么用除宽外的那条直角边来更新答案,如果超出了也不一定就是impossible,还可以让超出部分去长方形的上面,再判断一下是否超出宽,然后早判断一下更新答案

反思:超级无敌毫无体验感的大傻逼题。比赛的时候开始看的时候队友说题意是只要可以放下这个三角形就好了,不用最小,当是只过了那么几个人交了那么多,而且全是wa的,就不怎么敢写,不怎么敢想了,最后补题的时候自己独立认认真真的读题才明白还要面积最小,如果把题意读懂了这道题也不至于这么多人没过吧,当时如果我在认认真真的看一遍题,估计可能有一点希望。

代码:写的超级龊能看则看吧

//写的非常丑 
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<stdlib.h>
#include<time.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
#include<set>
#include<map>
#define ll long long
#define qq printf("QAQ\n");
using namespace std;
const int maxn=2e5+5;
const int inf=0x3f3f3f3f;
const ll linf=8e18+9e17;
const int mod=998244353;
const double e=exp(1.0);
const double pi=acos(-1);
const double eps=1e-6;
int coor[4][2],w;
double l[4],s,cos1[4];
double dis(int x,int y)
{
	return sqrt((coor[x][0]-coor[y][0])*(coor[x][0]-coor[y][0])+(coor[x][1]-coor[y][1])*(coor[x][1]-coor[y][1]));
}
double S()
{
	int s1=(abs(coor[1][0]-coor[2][0])+abs(coor[1][0]-coor[3][0]))*abs(coor[2][1]-coor[3][1]);
	//cout<<"s1="<<s1<<endl;
	int s2=abs(coor[1][0]-coor[2][0])*abs(coor[1][1]-coor[2][1])+abs(coor[1][0]-coor[3][0])*abs(coor[1][1]-coor[3][1]);
//	cout<<"s2="<<s2<<endl;	
	return 1.0*(s1-s2)/2;
}
double check(int id)
{
	double ans=1.0*inf;
	double maxlen=-1;
	int maxid=-1,otherid=-1;
	for(int i=1;i<=3;i++)//找出 除id边意外的最长边 
	{
		if(i==id)continue;
		if(l[i]>maxlen){
		maxlen=l[i];
		maxid=i;
		}
	}
	for(int i=1;i<=3;i++)if(i!=id&&i!=maxid)otherid=i;//找到剩下的哪一条边 	
	
	if(l[id]<=w)//如果可以完全躺在长方形底边 
	{
		if(maxlen*cos1[otherid]-w<=eps)
			ans=min(ans,maxlen*sqrt(1-cos1[otherid]*cos1[otherid]));	
	}
	else {//不能 
		double h=sqrt(l[id]*l[id]-w*w);
		double cosr=(l[id]*l[id]+h*h-w*w)/(2*l[id]*h);
		double cosl=(l[id]*l[id]+w*w-h*h)/(2*w*l[id]);
		if(cosl-cos1[otherid]<=eps&&cosr-cos1[maxid]<=eps||cosl-cos1[maxid]<=eps&&cosr-cos1[otherid]<=eps) 
		ans=min(ans,h);//max 和other 这两条边都没有超出 当前id边和长方形底边以及长方形的其中一条场组成的直角三角形的范围 
		else {	
			double cc=acos(cosl)+acos(cos1[maxid]);//超出了 只能放在直角三角形上面 
			if(cc-pi/2<=eps&&l[otherid]*cos(cc)-w<=eps&&l[otherid]*sin(cc)-h>=eps)
			ans=min(ans,l[otherid]*sin(cc));  //分内讨论这个三角形一条边固定了对角的位置固定了 还有两种情况分两个方向 
			cc=acos(cosl)+acos(cos1[otherid]);
			if(cc-pi/2<=eps&&l[maxid]*cos(cc)-w<=eps&&l[maxid]*sin(cc)-h>=eps)
			ans=min(ans,l[maxid]*sin(cc));
		}
	}
	return ans;
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		for(int i=1;i<=3;i++)
		scanf("%d%d",&coor[i][0],&coor[i][1]);
		scanf("%d",&w);
		l[3]=dis(1,2);
		l[1]=dis(2,3);
		l[2]=dis(1,3);
		cos1[1]=(l[2]*l[2]+l[3]*l[3]-l[1]*l[1])/(2*l[2]*l[3]);
		cos1[2]=(l[1]*l[1]+l[3]*l[3]-l[2]*l[2])/(2*l[1]*l[3]);
		cos1[3]=(l[2]*l[2]+l[1]*l[1]-l[3]*l[3])/(2*l[1]*l[2]);
		//s=S();
	//	cout<<s<<" "<<l[1]<<" "<<l[2]<<" "<<l[3]<<endl;		
		double ans=1.0*inf;
		for(int i=1;i<=3;i++)
		{
			ans=min(ans,check(i));//枚举每一条边放在最底端  
		}
		if(ans==inf)printf("impossible\n");
		else printf("%.6f\n",ans);
	}
	return 0;
}
/*
2
0 2 -2 0 2 0 4
*/

猜你喜欢

转载自blog.csdn.net/swust5120166213/article/details/81913084