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

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. WPF DragDrop事件元素跟随

    前一段时间项目里面要实现一个鼠标拖动一个元素到另外一个元素上面并且赋值的功能,由于要在surface上运行,拖动的时候手指会挡住系统默认的拖动图标,导致用户意识不到自己是不是在拖动着东西,所以要解决这 ...

  2. arm 基本

    ARMr0-r4 传递参数与返回值r7 帧指针 指向母函数被调用子函数在栈看中的交界栈帧指针(Frame Pointer).指向前一个保存的栈帧(stack frame)和链接寄存器(link reg ...

  3. Oracle Study Note : Users and Basic Security

    1. view the default user account SQL> select username from dba_users; 2. lock all users and set t ...

  4. 迭代器、泛型和增强For

    Iterator hasNext  next Iterator 迭代器 Collection提供了一个遍历集合的通用方式,迭代器(Iterator). 获取迭代器的方式是使用Collection定义的 ...

  5. 九度oj 1349 数字在排序数组中出现的次数

    原题链接:http://ac.jobdu.com/problem.php?pid=1349 二分.. #include<algorithm> #include<iostream> ...

  6. Amazon Kindle Device is hiring in Beijing Shanghai and Shenzhen!

    This is Angela from recruitment team of Amazon Kindle Device Software & Applications, we are exp ...

  7. ios中怎么样调节占位文字与字体大小在同一高度

    在设置好字体以后,在占位文字中设置leading这个字体属性,用leading来乘以一个比例(CGFloat)来调节位置.

  8. 别跟我来这套 Hot Swap 热插拔

    如果你觉得我们演的不好,可以随时打断,如果你觉得怎么演好可以随时来改,你都可以直接来演.

  9. JSP的7个动作指令

    动作指令与编译指令不同,编译指令是通知Servlet引擎的处理信息,而动作指令知识运行时的动作.编译指令在将JSP编译成Servlet时起作用,而处理指令通常可替换成JSP脚本,它知识JSP脚本的标准 ...

  10. PB建数据窗口的时候会报内存错误

     同事碰到了这个问题,百度了一下,按照下边的方法解决了 ------解决方案--------------------我遇到过,是powerbuilder的注册表出问题了,找到注册表中HKEY_USER ...