Parallelepiped walk

废话不多说,直接上题=V=

题目描述
Two points A (x1, y1, z1) and B (x2, y2, z2) are placed on the surface of parallelepiped with dimensions (see figure 1). These two points can be linked with various curves lying on the surface of P. You are to find out the square of the shortest curve length. Parallelepiped dimensions L, W, H and coordinates of the points are integers, .
在这里插入图片描述

输入
Input contains (in indicated order): L, W, H, x1, y1, z1, x2, y2, z2. The numbers are separated with spaces and end-of-line characters.

输出
Output should contain the square of the shortest curve length between points A and B on the surface of P.

样例输入
5 5 2
3 1 2
3 5 0
样例输出
36

这个题其实理解清楚了,也没有那么难,代码量还是比较少的

切记一定要结合着图写,俺当初就是因为没有看出让我直接把长和宽弄反了,直接当场有种吐血的感觉😭

这个题的思路相信大家在高中或者小学都学过吧,就是把六面体展开,那么怎么展开呢,首先用递归的思想进行展开

可能你会想我能想到把他展开,但是就是不知道咋个用代码写出来,如果你能想到思路(非常好),我第一次写该题时是通过枚举,作为菜鸡在看了其它的发现自己是真的菜,如果你能想到这一步总之比我牛哈哈
我们要翻转有四个方向可以翻转,向右翻转,向左翻转,向前翻转,向后翻转
并且将六面体展开我们知道每个方向最多翻两次就可以了,每次反转后以左上方顶点为原点
那我们先举个例子看一下吧
如果向右翻转的话:
在这里插入图片描述
是不是就把最右侧的那个面翻转到地面上了,此时俯视图就可以想象成在这里插入图片描述
奥忘记说了如果某个面翻转到地面后就假设它已经在地面了,以后的翻转就不考虑该面了接下来看看代码吧

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int res = 0x3f3f3f3f;
/*
    如果a + 1表示向右翻转(相当于将其六面体向右推倒,但是我们要认为最底面那个就在原地),反之a - 1表示向左翻转
    如果b + 1表示向前面翻转(也就是朝我们这个方向翻转), b - 1 表示向里翻转
*/
void unfold(int a, int b, int x1, int y1, int z1, 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));
        return;
    }
    if(a >= 0 && a < 2) unfold(a + 1, b, x1, -(W - y1), z1, x2, z2, (W - y2), L, H, W);
    if(a <= 0 && a > -2) unfold(a - 1, b, x1, (H + y1), z1, x2, (H - z2),  y2, L, H, W);
    if(b >= 0 && b < 2) unfold(a, b + 1, -(L - x1), y1, z1, z2, y2, (L - x2), H, W, L);
    if(b <=0 && b > - 2) unfold(a, b - 1, (H + x1), y1, z1, (H - z2), y2, x2, H, W, L);
}
int main() {
    int L, W, H, x1, y1, z1, x2, y2, z2;
    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;
    }
    unfold(0, 0, x1, y1, z1, x2, y2, z2, L, W, H);
    cout << res << endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值