拼多多-2020-08-02-后端笔试-第二题-思路和解法
创建一个骰子类,含有 上下左右前后 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 << ' ';
}
}




查看7道真题和解析