原理剖析
初看题目题主摸不着头脑,6个矩形的关系应该满足什么样的关系才能组成一个立方体?为了理清思路让我们画一个立方体观察(阅读过程中可随时跳到末尾代码处阅览以辅助理解):
得出事实:
- 立方体有3对对立面,对立面的形状一致;
- 三条邻接棱即可唯一描述一个立方体,如图所示标红的三条楞;
接下来按照以下步骤思考:
- 定义长边为 h h h,短边为 w w w,三对对立面分别为 p 1 , p 2 , p 3 p_1,p_2,p_3 p1,p2,p3,他们各自的 h , w h,w h,w应该带上相应的下标 1 , 2 , 3 1,2,3 1,2,3例如 p 1 p_1 p1的 h h h标记为 h 1 h_1 h1, h i > w i h_i>w_i hi>wi
- 固定 p 1 p_1 p1即固定 h 1 , w 1 h_1,w_1 h1,w1,此时根据 x x x的大小决定了 h 1 h_1 h1同时是 p 3 p_3 p3的 h 3 h_3 h3或 w 3 w_3 w3, w 1 w_1 w1的情况同理.
- 当 x ≥ h 1 x\geq h_1 x≥h1,此时决定了 x x x同时为 h 2 h_2 h2和 h 3 h_3 h3
- 当 w 1 ≤ x < h 1 w_1\leq{x}<h_1 w1≤x<h1,此时决定了 x x x同时为 h 2 h_2 h2和 w 3 w_3 w3
- 当 x < w 1 x<w_1 x<w1,此时决定了 x x x同时为 w 2 w_2 w2和 w 3 w_3 w3
根据
3
,
4
,
5
3,4,5
3,4,5画出下图便于理解:
三个立方体从左到右分别代表了
3
,
4
,
5
3,4,5
3,4,5三种情况.
分别写出对应立方体成立等式
- w 1 = w 2 a n d h 1 = w 3 a n d h 2 = h 3 w_1=w_2 \ and \ h_1=w_3 \ and \ h_2=h_3 w1=w2 and h1=w3 and h2=h3
- w 1 = w 2 a n d h 1 = h 3 a n d h 2 = w 3 w_1=w_2 \ and \ h_1=h_3 \ and \ h_2=w_3 w1=w2 and h1=h3 and h2=w3
- w 1 = h 2 a n d h 1 = h 3 a n d w 2 = w 3 w_1=h_2 \ and \ h_1=h_3 \ and \ w_2=w_3 w1=h2 and h1=h3 and w2=w3
如果我们对于每一对儿长方形定义 h i > w i h_i>w_i hi>wi,并对3对儿长方形按照 h h h大小降序排列,此时对应图3的情况,注意 p 2 , p 3 p_2,p_3 p2,p3对应的长方形不一定和图中一致。确定下来 p 1 , p 2 , p 3 p_1,p_2,p_3 p1,p2,p3的位置关系即可确定对应的 h , w h,w h,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;
}