题目链接
用递归把面展开
先把一个点移到最底面,之后开始展开操作。
整体向右展开,即除了当前底面之外,这个六面体往右边旋转,旋转后以底面左上角为(0,0)
整体向左展开,即除了当前底面之外,这个六面体往左边旋转,旋转后以底面左上角为(0,0)
整体向前展开,即除了当前底面之外,这个六面体往前边旋转,旋转后以底面左上角为(0,0)
整体向后展开,即除了当前底面之外,这个六面体往后边旋转,旋转后以底面左上角为(0,0)
如果你想暴力,那情况不能少。 惨痛教训
当另一个点转到底面时,就计算出它们之间的值。
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
//#include<bits/stdc++.h>
#include<iostream>
#define int long long
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const double eps = 1e-5;
const int mod = 999911659;
const int N = 1e6+10;
int ans = INF;
int l,w,h,x1,x2,y1,y2,z1,z2;
void slove(int zy, int qh, int x0, int y0, int x, int y, int z, int l, int w, int h){
if (z == 0)
ans = min((x0 - x) * (x0 - x) + (y0 - y) * (y0 - y), ans);
else{
if (zy >= 0 && zy < 2)//向右转 (以转点为(0,0)点)
slove(zy + 1, qh, x0, y0 - w, x, z, w - y, l, h, w);
if (zy <= 0 && zy > -2)//向左转
slove(zy - 1, qh, x0, y0 + h, x, h - z, y, l, h, w);
if (qh >= 0 && qh < 2)//向前
slove(zy, qh + 1, x0 - l, y0, z, y, l - x, h, w, l);
if (qh <= 0 && qh > -2)//向后
slove(zy, qh - 1, x0 + h, y0, h - z, y, x, h, w, l);
}
}
signed main(){
IOS;
#ifdef ddgo
freopen("C:\\Users\\asus\\Desktop\\ddgoin.txt","r",stdin);
#endif
while(cin>>l>>w>>h>>x1>>y1>>z1>>x2>>y2>>z2){
//预处理让第一个点在下方
if (z1 != 0 && z1 != h){
if (y1 != 0 && y1 != w) 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;
ans = 1e18;
slove(0, 0, x1, y1, x2, y2, z2, l, w, h);
cout<<ans<<endl;
}
return 0;
}
总结:我是傻逼