UVA1587 盒子 Box 数学表达式解析(给你整的明明白白)

本文解析了如何通过六个矩形拼成一个立方体的问题,探讨了几何条件,并提供了详细的判断逻辑及实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原理剖析

初看题目题主摸不着头脑,6个矩形的关系应该满足什么样的关系才能组成一个立方体?为了理清思路让我们画一个立方体观察(阅读过程中可随时跳到末尾代码处阅览以辅助理解):
在这里插入图片描述

得出事实:

  1. 立方体有3对对立面,对立面的形状一致;
  2. 三条邻接棱即可唯一描述一个立方体,如图所示标红的三条楞;

接下来按照以下步骤思考:

  1. 定义长边为hhh,短边为www,三对对立面分别为p1,p2,p3p_1,p_2,p_3p1,p2,p3,他们各自的h,wh,wh,w应该带上相应的下标1,2,31,2,31,2,3例如p1p_1p1hhh标记为h1h_1h1,hi>wih_i>w_ihi>wi
  2. 固定p1p_1p1即固定h1,w1h_1,w_1h1,w1,此时根据xxx的大小决定了h1h_1h1同时是p3p_3p3h3h_3h3w3w_3w3,w1w_1w1的情况同理.
  3. x≥h1x\geq h_1xh1,此时决定了xxx同时为h2h_2h2h3h_3h3
  4. w1≤x<h1w_1\leq{x}<h_1w1x<h1,此时决定了xxx同时为h2h_2h2w3w_3w3
  5. x<w1x<w_1x<w1,此时决定了xxx同时为w2w_2w2w3w_3w3

根据3,4,53,4,53,4,5画出下图便于理解:
在这里插入图片描述
三个立方体从左到右分别代表了3,4,53,4,53,4,5三种情况.
分别写出对应立方体成立等式

  1. w1=w2 and h1=w3 and h2=h3w_1=w_2 \ and \ h_1=w_3 \ and \ h_2=h_3w1=w2 and h1=w3 and h2=h3
  2. w1=w2 and h1=h3 and h2=w3w_1=w_2 \ and \ h_1=h_3 \ and \ h_2=w_3w1=w2 and h1=h3 and h2=w3
  3. w1=h2 and h1=h3 and w2=w3w_1=h_2 \ and \ h_1=h_3 \ and \ w_2=w_3w1=h2 and h1=h3 and w2=w3

如果我们对于每一对儿长方形定义hi>wih_i>w_ihi>wi,并对3对儿长方形按照hhh大小降序排列,此时对应图3的情况,注意p2,p3p_2,p_3p2,p3对应的长方形不一定和图中一致。确定下来p1,p2,p3p_1,p_2,p_3p1,p2,p3的位置关系即可确定对应的h,wh,wh,w大小关系了,详见代码。

代码

// #include <bits/stdc++.h>
// can mix cin/cout with scanf/printf with debug mode
// can only use cin/cout or scanf/printf without debug mode
// notice:
// 1) static map or tree can use Node
// 2) dynamic map or tree can only use Node* 
// 3) int bk[maxn] is much faster than unordered_set; bk << unordered_set << set
// 4) int bk[maxn] = {0} is much faster than memset(bk, 0, sizeof(bk));
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <deque>
#include <iostream>
#include <iomanip>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <stack>
#include <set>
#include <string>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <climits>

#define rep(i, n) for (int i = 0, size = (n); i < size; ++i)
#define repu(i, a, b) for (int i = (a), _upper_bound = (b); i < _upper_bound; ++i)
#define repd(i, a, b) for (int i = (a), _lower_bound = (b); i > _lower_bound; --i)
#define each(it, a) for(auto & (it) : (a))
#define pf printf
#define sf scanf
#define _max(a, b) ((a) > (b) ? (a) : (b))
#define _min(a, b) ((a) < (b) ? (a) : (b))

typedef long long ll;
const double eps = 1e-8;
#define lowbit(x) (x&(-x))
#define equ(a, b) (fabs(a - b) < eps)
#define lcm(a, b) (a / gcd(a, b) * b)
#define vi vector<int>
#define pii pair<int, int>

using namespace std;

int gcd(int a, int b){
    return !b ? a : gcd(b, a % b);
}

void print(vi &v){
    rep(i, v.size()){
        if(i == 0) cout << v[i];
        else cout << " " << v[i];
    }
    cout << endl;
}

struct Node{
    int w, h;
    int s;
};
vector<Node> node;

const char* msg[] = {
    "POSSIBLE",
    "IMPOSSIBLE",
};

int same(Node & n1, Node & n2){
    return n1.h == n2.h and n1.w == n2.w;
}


void solve(){
    
    int w, h;
    while(cin >> w >> h){
        Node x;
        if(w <= h){
            x.w = w;
            x.h = h;
        }
        else{
            x.w = h;
            x.h = w;
        }
        x.s = x.w * x.h;
        node.push_back(x);
        if(node.size() == 6){
            // process here
            sort(node.begin(), node.end(), [](Node & n1, Node & n2){
                return (n1.h != n2.h) ? n1.h > n2.h : n1.w > n2.w;
            });
            int ok = 1;
            if(same(node[0], node[1]) and same(node[2], node[3]) and same(node[4], node[5])){

            }
            else{
                ok = 0;
            }

            if(ok){
                if((node[0].h != node[2].h) or (node[0].w != node[4].h) or (node[2].w != node[4].w)){
                    ok = 0;
                }
            }
            if(ok) cout << msg[0] << endl;
            else cout << msg[1] << endl;
            
            node.clear();
        }
   
    }
}

int main(){
    #ifndef DEBUG
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    #endif
    #ifdef LOCAL
    freopen("in", "r", stdin);
    freopen("o", "w", stdout);
    #endif
    // cout << setiosflags(ios::fixed);
    // cout << setprecision(2);
    // cout << setw(2) << setfill('0');  // add this every time when cout int with width and left padding '0'
    solve();
    
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值