题解:B3760 [信息与未来 2021] 掷骰子
Forever_Rain · · 题解
题意
有一个特殊的骰子,六个面上是
思路
枚举所有可能的骰子配置。
对于骰子的任意三个面,它们同时可见当且仅当这三个面相交于同一个顶点。一个骰子有
对于每个拍摄结果
#include <bits/stdc++.h>
using namespace std;
int n; // 拍摄次数
int x[25], y[25], z[25]; // 存储每次拍摄到的三个数字
int a, b, c, d, e, f; // 分别代表骰子六个面的数字(按特定展开顺序)
int mn = 50, mx = 0; // 最小和与最大和,初始值设为可能范围外的值
// 检查函数:判断当前骰子配置是否与所有拍摄结果一致
bool check() {
for (int i = 1; i <= n; i++) {
int u = x[i], v = y[i], w = z[i]; // 当前拍摄的三个数字
// 检查当前拍摄结果是否对应骰子的某个顶点视图
// 骰子的八个顶点,每个顶点连接三个面
// 每个顶点可能有多种观察顺序,这里列举了常见的四种
// 顶点1: 由面a,c,d组成
if ((u == a && v == c && w == d) || (u == a && v == d && w == f) ||
(u == a && v == f && w == b) || (u == a && v == b && w == c))
continue; // 匹配成功,检查下一个拍摄结果
// 顶点2: 由面b,e,c组成
if ((u == b && v == e && w == c) || (u == b && v == c && w == a) ||
(u == b && v == a && w == f) || (u == b && v == f && w == e))
continue;
// 顶点3: 由面c,e,d组成
if ((u == c && v == e && w == d) || (u == c && v == d && w == a) ||
(u == c && v == a && w == b) || (u == c && v == b && w == e))
continue;
// 顶点4: 由面d,e,f组成
if ((u == d && v == e && w == f) || (u == d && v == f && w == a) ||
(u == d && v == a && w == c) || (u == d && v == c && w == e))
continue;
// 顶点5: 由面e,f,d组成
if ((u == e && v == f && w == d) || (u == e && v == d && w == c) ||
(u == e && v == c && w == b) || (u == e && v == b && w == f))
continue;
// 顶点6: 由面f,e,b组成
if ((u == f && v == e && w == b) || (u == f && v == b && w == a) ||
(u == f && v == a && w == d) || (u == f && v == d && w == e))
continue;
return false; // 所有顶点都不匹配,当前骰子配置无效
}
return true; // 所有拍摄结果都匹配成功
}
int main() {
// 输入拍摄次数
cin >> n;
// 读入每次拍摄的三个数字
for (int i = 1; i <= n; i++) {
cin >> x[i] >> y[i] >> z[i];
}
// 枚举所有可能的骰子配置
// 每个面可以是1到6的数字,总共有6^6=46656种可能
for (a = 1; a <= 6; a++) // 上面
for (b = 1; b <= 6; b++) // 左面
for (c = 1; c <= 6; c++) // 前面
for (d = 1; d <= 6; d++) // 后面(c的对面)
for (e = 1; e <= 6; e++) // 下面(b的对面)
for (f = 1; f <= 6; f++) { // 底面(a的对面)
if (check()) { // 如果当前配置符合所有拍摄结果
int sum = a + b + c + d + e + f; // 计算六个面的和
mn = min(mn, sum); // 更新最小和
mx = max(mx, sum); // 更新最大和
}
}
// 输出所有可能骰子中数字和的最小值和最大值
cout << mn << " " << mx;
return 0;
}