UVa 503 - Parallelepiped walk

11 篇文章 0 订阅
2 篇文章 0 订阅

这不纯粹是一个几何题 , 这道题可以给你很多关于长方体等价的思考 , 我先给大家看看代码(博主当时在网上看解法的时候就几乎只有代码) , 如果你能够像博主一样从代码中明白原理 , 你一定会大有收获 , 但如果碰到了些麻烦 , 剩下的分析在代码后


#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 的对应关系

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值