这不纯粹是一个几何题 , 这道题可以给你很多关于长方体等价的思考 , 我先给大家看看代码(博主当时在网上看解法的时候就几乎只有代码) , 如果你能够像博主一样从代码中明白原理 , 你一定会大有收获 , 但如果碰到了些麻烦 , 剩下的分析在代码后
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <deque>
#include <stack>
#include <algorithm>
using namespace std;
int res;
void solve(int i , int j , int x1 , int y1 , int x2 , int y2 , int z2 , int l , int w , int h)
{
if(z2==0) { res = min(res , (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); }
else
{
if(i>=0 && i<=1) solve(i+1, j, x1+h, y1, h-z2, y2, x2, h, w, l);
if(i<=0 && i>-2) solve(i-1, j, x1-l, y1, z2, y2, l-x2, h, w, l);
if(j>=0 && j<=1) solve(i, j+1, x1, y1-w, x2, z2, w-y2, l, h, w);
if(j<=0 && j>-2) solve(i, j-1, x1, y1+h, x2, h-z2, y2, l, h, w);
}
}
int main(int argc, char *argv[]) {
int l, w, h, x1, y1, z1, x2, y2, z2;
while(cin>>l>>w>>h>>x1>>y1>>z1>>x2>>y2>>z2)
{
if(z1!=h && z1!=0)
{
if(y1!=w && y1!=0)
swap(x1, z1), swap(x2, z2), swap(l, h);
else swap(y1, z1) , swap(y2, z2), swap(w, h);
}
if(z1==h) z1 = 0 , z2 = h-z2;
res = 1<<29;
solve(0, 0, x1, y1, x2, y2, z2, l, w, h);
cout<<res<<endl;
}
return 0;
}
分析与提示
1. 不论第二个点在哪里 , 我们先尝试把第一个点转到xOy的平面内(当然一定要相应的把第二个点等效到自己的位置)
2. 精彩的是solve函数 ,总体目标是通过转动让第二个点与第一个点同样在xOy平面内(转动过程中第一个点永远在xOy平面但不必在长方体上);
这时你肯定有很多疑问,但我们先尝试转动 , 看看怎样的转动是有效的 , 你需要一个长方体橡皮 , 尝试以某条边为轴进行旋转 , 可以发现
1) 只有四个方向 ,且有两个方向是互逆的 2)如果转动次数过多或者进行互逆的转动是没有意义的
3. 我想你估计能大概知道怎么样能够把第二个点转到xOy平面了 , 但是存在一个关键问题: 怎样保证两点距离在转动时不变呢
这里我们坚持两个不变的因素来保证制约这个条件同时也方便递归
1) 原点 , aka (0,0,0) , 永远在长方体的左下角 2) 第一个点的坐标在转动的过程中永远和转动后的原点距离相等(转动后的原点在转动前并不是原点 , 所以相应的第一个点的坐标会改变)
注意: h , w , l , 和 x , y , z 的对应关系