紫书刷题进行中,题解系列点这里
习题3-10 UVA1587 Box(30行AC代码)
思路分析
给定6个已知长宽的矩形,判断是否能构成长方体。判定的等价条件如下:
- 6个面,分三组,因此可用
map<set<int>,int>
记录每个面出现次数,由于存在正方体(6),两个正方形面(2,4),三个长方形(2,2,2),因此,每个面出现次数为2/4/6
,即2的倍数。 - 12条边,分三组,因此可用
map<int,int>
记录每条边长出现次数,遇上同理,存在4/8/12
三种情况,即4的倍数。
STL使用技巧
- map初始化:对于不存在的key,使用mp[k]时自动初始化value,比如以下实例:
map<int,int>mpInt;
cout <<mpInt[1]; // 输出0
map<int,set<int>> mpSet;
cout <<mpSet[1].size(); // 输出0
map<int,vector<int>> mpVec;
cout <<mpVec[1].size(); // 输出0
AC代码(C++11,长方体判定条件,STL)
#include<bits/stdc++.h>
using namespace std;
map<set<int>, int> box;
map<int, int> edge;
int a, b;
int main() {
while(cin >>a >> b) {
bool isBox = false, flag = true, flag2 = true;
box.clear(); edge.clear();
for (int i = 0; i < 6; i ++) {
if (i != 0) cin >>a >>b;
box[{a,b}] ++;
edge[a] ++;
edge[b] ++;
}
for (auto p : box) { // 每个面出现次数为2,4,6
if (p.second % 2 != 0) {
flag = false; break;
}
}
for (auto p : edge) { // 每条边出现次数为4,8,12
if (p.second % 4 != 0) {
flag2 = false; break;
}
}
if (flag && flag2) isBox = true; // 满足两个条件可构造长方体
printf("%s\n", isBox ? "POSSIBLE" : "IMPOSSIBLE");
}
return 0;
}