比赛的时候跳进这个大坑里,最后代码是写出来了。看到好像很多都是模拟退火做的,下面提供一个奇怪的思路吧。

ax^2+by^2+cz^2+dyz+exz+fxy=1(*)

通过一些奇特的YY我们可以知道这是由一个标准的椭球ax^2+by^2+cz^2=1旋转得到的,之所以有交叉项是因为绕了X,Y,Z轴旋转,所以我们的想法是要是能将这个椭球旋回去那么就可以知道最短的距离了。

首先我们是旋转z轴,希望使得xy项消掉,这个时候令z=0可以得到  ax^2+by^2+fxy=1

通过一些椭圆的旋转知识我们可以求出当旋转角为phi,将x,y做一个旋转代换就可以使得xy被消掉,具体的phi值求法可以百度一下椭圆,公式这里就是tan(2p)=f/(a-b)(对于上面那个式子),将这个代换弄到*里其实就会得到一个新的方程:

a'x^2+b'y^2+c'z^2+d'yz+e'xz+f'xy=1

这个时候f'=0,然后我们希望通过旋转x轴将d'=0,方法同样是令x=0得到

b'y^2+c'z^2+d'yz=1

利用相同的代换可以得到新的方程

a''x^2+b''y^2+c''z^2+d''yz+e''xz+f''xy=1

这个时候注意,d''=0,但原先的f''却不一定等于0了。

同样我们再令旋转y轴,使得e''=0。

经过一轮这样的操作后,我们可以发现,最后e=0是一定的,但是d和f不一定等于0,但是直觉上这样的操作只要重复的做最后一定会收敛,因此我们就重复地对这个椭球做这样的操作,做个100次(实测其实只要转4,5次)精度就已经非常足够了。

#pragma warning(disable:4996)
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#include <queue>
#include <string>
#include <map>
using namespace std; #define eps 1e-6
int dcmp(double x){
return (x > eps) - (x < -eps);
} double a, b, c, d, e, f;
double p, w, k; double pi = acos(-1.0); double get(double A, double B, double C)
{
if (dcmp(B) == 0) return 0; if (dcmp(A - C) == 0) {
return pi / 4;
}
double ret = atan(B / (A - C));
return ret / 2;
} double a1, a2, a3, b1, b2, b3, c1, c2, c3; double A, B, C, D, E, F; int main()
{
while (~scanf("%lf%lf%lf%lf%lf%lf", &a, &b, &c, &d, &e, &f))
{
int T = 100;
while (T--){
p = 0;
w = 0;
k = get(a, f, b); a1 = cos(p)*cos(k) - sin(p)*sin(w)*sin(k);
a2 = -cos(p)*sin(k) - sin(p)*sin(w)*cos(k);
a3 = -sin(p)*cos(w); b1 = cos(w)*sin(k);
b2 = cos(w)*cos(k);
b3 = -sin(w); c1 = sin(p)*cos(k) + cos(p)*sin(w)*sin(k);
c2 = -sin(p)*sin(k) + cos(p)*sin(w)*cos(k);
c3 = cos(p)*cos(w); A = a*a1*a1 + b*b1*b1 + c*c1*c1 + d*b1*c1 + e*a1*c1 + f*a1*b1;
B = a*a2*a2 + b*b2*b2 + c*c2*c2 + d*b2*c2 + e*a2*c2 + f*a2*b2;
C = a*a3*a3 + b*b3*b3 + c*c3*c3 + d*b3*c3 + e*a3*c3 + f*a3*b3;
D = a * 2 * a2*a3 + b * 2 * b2*b3 + c * 2 * c2*c3 + d*(b2*c3 + b3*c2) + e*(a2*c3 + a3*c2) + f*(a2*b3 + a3*b2);
E = a * 2 * a1*a3 + b * 2 * b1*b3 + c * 2 * c1*c3 + d*(b1*c3 + b3*c1) + e*(a1*c3 + a3*c1) + f*(a1*b3 + a3*b1);
F = a * 2 * a1*a2 + b * 2 * b1*b2 + c * 2 * c1*c2 + d*(b1*c2 + b2*c1) + e*(a1*c2 + a2*c1) + f*(a1*b2 + a2*b1); a = A; b = B; c = C; d = D; e = E; f = F; //haha
//cout << a << " " << b << " " << c << " " << d << " " << e << " " << f << endl; p = 0;
w = get(b, d, c);
k = 0; a1 = cos(p)*cos(k) - sin(p)*sin(w)*sin(k);
a2 = -cos(p)*sin(k) - sin(p)*sin(w)*cos(k);
a3 = -sin(p)*cos(w); b1 = cos(w)*sin(k);
b2 = cos(w)*cos(k);
b3 = -sin(w); c1 = sin(p)*cos(k) + cos(p)*sin(w)*sin(k);
c2 = -sin(p)*sin(k) + cos(p)*sin(w)*cos(k);
c3 = cos(p)*cos(w); A = a*a1*a1 + b*b1*b1 + c*c1*c1 + d*b1*c1 + e*a1*c1 + f*a1*b1;
B = a*a2*a2 + b*b2*b2 + c*c2*c2 + d*b2*c2 + e*a2*c2 + f*a2*b2;
C = a*a3*a3 + b*b3*b3 + c*c3*c3 + d*b3*c3 + e*a3*c3 + f*a3*b3;
D = a * 2 * a2*a3 + b * 2 * b2*b3 + c * 2 * c2*c3 + d*(b2*c3 + b3*c2) + e*(a2*c3 + a3*c2) + f*(a2*b3 + a3*b2);
E = a * 2 * a1*a3 + b * 2 * b1*b3 + c * 2 * c1*c3 + d*(b1*c3 + b3*c1) + e*(a1*c3 + a3*c1) + f*(a1*b3 + a3*b1);
F = a * 2 * a1*a2 + b * 2 * b1*b2 + c * 2 * c1*c2 + d*(b1*c2 + b2*c1) + e*(a1*c2 + a2*c1) + f*(a1*b2 + a2*b1);
a = A; b = B; c = C; d = D; e = E; f = F; //cout << a << " " << b << " " << c << " " << d << " " << e << " " << f << endl; p = get(a, e, c);
w = 0;
k = 0; a1 = cos(p)*cos(k) - sin(p)*sin(w)*sin(k);
a2 = -cos(p)*sin(k) - sin(p)*sin(w)*cos(k);
a3 = -sin(p)*cos(w); b1 = cos(w)*sin(k);
b2 = cos(w)*cos(k);
b3 = -sin(w); c1 = sin(p)*cos(k) + cos(p)*sin(w)*sin(k);
c2 = -sin(p)*sin(k) + cos(p)*sin(w)*cos(k);
c3 = cos(p)*cos(w); A = a*a1*a1 + b*b1*b1 + c*c1*c1 + d*b1*c1 + e*a1*c1 + f*a1*b1;
B = a*a2*a2 + b*b2*b2 + c*c2*c2 + d*b2*c2 + e*a2*c2 + f*a2*b2;
C = a*a3*a3 + b*b3*b3 + c*c3*c3 + d*b3*c3 + e*a3*c3 + f*a3*b3;
D = a * 2 * a2*a3 + b * 2 * b2*b3 + c * 2 * c2*c3 + d*(b2*c3 + b3*c2) + e*(a2*c3 + a3*c2) + f*(a2*b3 + a3*b2);
E = a * 2 * a1*a3 + b * 2 * b1*b3 + c * 2 * c1*c3 + d*(b1*c3 + b3*c1) + e*(a1*c3 + a3*c1) + f*(a1*b3 + a3*b1);
F = a * 2 * a1*a2 + b * 2 * b1*b2 + c * 2 * c1*c2 + d*(b1*c2 + b2*c1) + e*(a1*c2 + a2*c1) + f*(a1*b2 + a2*b1); a = A; b = B; c = C; d = D; e = E; f = F; //cout << a << " " << b << " " << c << " " << d << " " << e << " " << f << endl;
} A = sqrt(1.0 / A);
B = sqrt(1.0 / B);
C = sqrt(1.0 / C); double ans = min(min(A, B), C);
printf("%.10lf\n", ans);
}
return 0;
}

hdu5017 Ellipsoid(旋转)的更多相关文章

  1. hdu5017 Ellipsoid (模拟退火)

    Ellipsoid 原题链接 题目描述 给定.一个要满足的椭球的方程\(ax^2+by^2+cz^2+dyz+exz+fxy=1\) 求球面上一个点到原点\((0,0,0)\)的距离最小. 有多组输入 ...

  2. ACM学习历程——HDU5017 Ellipsoid(模拟退火)(2014西安网赛K题)

    ---恢复内容开始--- Description Given a 3-dimension ellipsoid(椭球面) your task is to find the minimal distanc ...

  3. 地球椭球体(Ellipsoid)、大地基准面(Datum)及地图投影(Projection)三者的基本概念

    地球椭球体(Ellipsoid) 众所周知我们的地球表面是一个凸凹不平的表面,而对于地球测量而言,地表是一个无法用数学公式表达的曲面,这样的曲面不能作为测量和制图的基准面.假想一个扁率极小的椭圆,绕大 ...

  4. Canvas绘图之平移translate、旋转rotate、缩放scale

    画布操作介绍 画布绘图的环境通过translate(),scale(),rotate(), setTransform()和transform()来改变,它们会对画布的变换矩阵产生影响. 函数 方法 描 ...

  5. Carousel 旋转画廊特效的疑难杂症

    疑难杂症 该画廊特效的特点就是前后元素有层级关系. 我想很多人应该看过或者用过这个插件carousel.js,网上也有相关的教程.不知道这个插件的原型是哪个,有知道的朋友可以告诉我. 该插件相对完美, ...

  6. jQuery可拖拽3D万花筒旋转特效

    这是一个使用了CSS3立体效果的强大特效,本特效使用jQuery跟CSS3 transform来实现在用户鼠标按下拖动时,环形图片墙可以跟随鼠标进行3D旋转动画. 效果体验:http://hovert ...

  7. css3制作旋转动画

    现在的css3真是强大,之前很多动画都是用jq来实现,但是css3制作的动画要比jq实现起来简单很多,今天呢,我自己也写了一个css旋转动画和大家分享.效果如下面的图片 思路:1.制作之前呢,我们先来 ...

  8. Android 旋转屏幕--处理Activity与AsyncTask的最佳解决方案

    一.概述 运行时变更就是设备在运行时发生变化(例如屏幕旋转.键盘可用性及语言).发生这些变化,Android会重启Activity,这时就需要保存activity的状态及与activity相关的任务, ...

  9. EasyPR--开发详解(4)形态学操作、尺寸验证、旋转等操作

    在上一篇深度分析与调优讨论中,我们介绍了高斯模糊,灰度化和Sobel算子.在本文中,会分析剩余的定位步骤. 根据前文的内容,车牌定位的功能还剩下如下的步骤,见下图中未涂灰的部分. 图1 车牌定位步骤 ...

随机推荐

  1. Android去除CPU占用过高时屏幕四周闪红框

    话说有些时间没有更新博客了,今天正好解决这个问题,顺便把它记录下来.. 今天遇到的情况是这样的,当CPU占用过高时,屏幕四周会出现一个红框. 闪一次两次算了,但是挺萌的(TMD)不停的闪,我的钛合金狗 ...

  2. Ruby on Rail学习笔记

    说明:只针对Windows8.1 Windows下,上rubyinstaller上下载最新的railsinstaller包含Ruby2.1的,然后更新gem 用命令: gem update --sys ...

  3. 判断Check复选框是否选中

    <div id="prm_div" style="font-size: 12px;" align="left"> <for ...

  4. ASP.NET MVC如何实现自定义验证(服务端验证+客户端验证)

    ASP.NET MVC通过Model验证帮助我们很容易的实现对数据的验证,在默认的情况下,基于ValidationAttribute的声明是验证被使用,我们只需 要将相应的ValidationAttr ...

  5. 【ExtJs】使用Cookie、切换主题和语言

    转自:http://witmax.cn/extjs-cookie-theme-lang.html 使用Cookie:   1 2 3 Ext.state.Manager.setProvider(new ...

  6. php xml转为xml或者json

    <?php class XmlToArray { private $xml; private $contentAsName="content" ; private $attr ...

  7. 5 给我们的c#程序添加注释

    注释是你的程序中的一个重要部分.在程序中添加注释是用来告诉你和其他人你的程序是做什么用的,你的思路是怎样的.注释可以用你熟悉的中文进行添加. 当你想暂时把你程序中的某些语句去掉的时候,不需要把他们删除 ...

  8. android 开发Parcelable 怎么传值ArrayList

    public class TradeEntity implements Parcelable{ public String id; //有关进度条的参数 ArrayList<TradeState ...

  9. C#日志编写

    在一个完整的信息系统里面,日志系统是一个非常重要的功能组成部分.它可以记录下系统所产生的所有行为,并按照某种规范表达出来.我们可以使用日志系统所记录的信息为系统进行排错,优化系统的性能,或者根据这些信 ...

  10. [转载]char * 和char []的区别---之第二篇

    原文地址:http://blog.sina.com.cn/s/blog_74a4593801019keb.html main() { char *p="abc123ABC";//c ...