创建一个骰子类,含有 上下左右前后 6 个属性,表示 6 个面。然后把骰子做标准化。我的方案是:把 1 放到 top 位置,然后把 左右前后 4 个面中的最小值放到 left 位置。然后把骰子转为字符串,存到 map 里计数即可。
#include <vector> #include <iostream> #include <unordered_map> #include <algorithm> #include <numeric> #include <unordered_set> #include <functional> using namespace std; // touzi: 骰子 struct Touzi{ explicit Touzi(vector<int>& touzi){ top = touzi[0]; bottom = touzi[1]; left = touzi[2]; right = touzi[3]; front = touzi[4]; back = touzi[5]; } void rotate(){ // 把 1 放到 top if(bottom == 1){ swap(top, bottom); swap(front, back); }else if(left == 1){ int n = top; top = left; left = bottom; bottom = right; right = n; }else if(right == 1){ int n = top; top = right; right = bottom; bottom = left; left = n; }else if(front == 1){ int n = top; top = front; front = bottom; bottom = back; back = n; }else if(back == 1){ int n = top; top = back; back = bottom; bottom = front; front = n; } // 把左右前后四个面中最小值放到 left 位置 if(min(left, right) > min(front, back)){ int n = left; left = front; front = right; right = back; back = n; } if(left > right){ swap(left, right); swap(front, back); } // 经过上面两个变换,相同的骰子上下左右前后对应的值一定相等 } string to_string() const{ string s; s.push_back(top + '0'); s.push_back(bottom + '0'); s.push_back(left + '0'); s.push_back(right + '0'); s.push_back(front + '0'); s.push_back(back + '0'); return s; } private: int top; int bottom; int left; int right; int front; int back; }; void main(){ int n; cin >> n; unordered_map<string, int> counter; for(int i=0;i<n;i++){ vector<int> touzi(6, 0); for(int k = 0; k < 6; k++){ int m; cin >>m; touzi[k] = m; } Touzi t(touzi); t.rotate(); counter[t.to_string()] += 1; } vector<int> nums; for(auto & item : counter){ nums.push_back(item.second); } // 降序排列 sort(nums.begin(), nums.end(), greater<>()); cout << nums.size() << '\n'; for(int num: nums){ cout << num << ' '; } }