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

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. 从0 开始 WPF MVVM 企业级框架实现与说明 ---- 第三讲 WPF中 DataTemplate

    后面在我们这项目中会大量用到模板,主要指的是空间模板,数据模板会用得比较少,下面我想介绍下控件模板和数据模板,我看到有位大神写得比较不错,我整理了下,让大家能更好理解,供大家参考, 首先介绍 Data ...

  2. Java当中的异常

    异常:中断了正常指令流的事件,是JVM虚拟机产生的对象 异常是程序运行时产生的,和编译无关 class Test{ public static void main(String args[]){ Sy ...

  3. Linux如何开机自动运行自己的脚本

    博客分类: LINUX 脚本LinuxCentOSWindowsBash      记录这个事情是上次完成之后,今天要新加一个文件夹,一时之间忘记以前怎么做了,因为有几种方法,起码我知道三种方法,这里 ...

  4. iOS学习之Object-C语言内存管理高级

    一.属性的内存管理

  5. Swift Explore - 关于 Swift 中的 isEqual 的一点探索

    在我们进行 App 开发的时候,经常会用到的一个操作就是判断两个对象是否相等.比如两个字符串是否相等.而所谓的 相等 有着两层含义.一个是值相等,还有一个是引用相等.如果熟悉 Objective-C ...

  6. mysql取整,小数点处理函数floor(), round()

    mysql数值处理函数floor与round    在mysql中,当处理数值时,会用到数值处理函数,如有一个float型数值2.13,你想只要整数2,那就需要下面的函数floor与round.   ...

  7. Hive与HBase区别

    对于刚接触大数据的用户来说,要想区分Hive与HBase是有一定难度的.本文将尝试从其各自的定义.特点.限制.应用场景等角度来进行分析,以作抛砖引玉之用. ====Hive是什么?Apache Hiv ...

  8. CRC校验算法

    typedef unsigned char UCHAR;typedef unsigned char BOOL; /* 计算cnt字节数据的crc,最后一个字节的低7比特必须是0,实际上求的是(cnt× ...

  9. 网页设计师必备的10个CSS技巧

    CSS是网页设计师的基础,对CSS的了解能使他们能够设计出更加美观别致的网页.使用CSS技巧来巧妙地处理CSS是非常令设计师着迷的事情.在CSS的深海世界里有很多有意思的东西,你只需要找到最适合你的就 ...

  10. Oracle 11g 11201_RHEL5.5_RAC_VBOX 详细搭建步骤

    1.安装好vbox,创建好虚拟机(红帽5.5),注意:VBOX全局设置VBOX磁盘的位置和备份位置     IP.hostname 规划:              hostname          ...