多多君拼团购买了N个骰子,为了方便后面进行活动,多多君需要将这些骰子进行分类。
两个骰子为同类的定义是:
将其中一个骰子通过若干次上下、左右或前后翻转后,其与另一个骰子对应的6面数字均相等。
将其中一个骰子通过若干次上下、左右或前后翻转后,其与另一个骰子对应的6面数字均相等。
第一行1个整数N,表示骰子的数量。(1 <= N <= 1,000)接下来N行,每行6个数字(1~6,且各不相同)其中第i行表示第i个骰子当前上、下、左、右、前、后这6面的数字。
共2行:
第一行1个整数M,表示不同种类的骰子的个数
第二行M个整数,由大到小排序,表示每个种类的骰子的数量
2 1 2 3 4 5 6 1 2 6 5 3 4
1 2
第二个骰子相当于是第一个骰子从左向右旋转了一面得到,属于同类。
3 1 2 3 4 5 6 1 2 6 5 3 4 1 2 3 4 6 5
2 2 1
第三个骰子无法通过任何旋转变换成第一个或第二个骰子。
10 2 5 1 3 4 6 5 4 3 2 1 6 1 4 6 2 3 5 1 5 6 3 4 2 6 4 2 1 5 3 3 6 4 5 2 1 1 6 3 4 2 5 5 1 4 2 6 3 6 2 3 1 5 4 5 3 6 1 4 2
9 2 1 1 1 1 1 1 1 1
只有第4个骰子(1 5 6 3 4 2)与第8个骰子(5 1 4 2 6 3)属于同一类。一种可能的变换方式:1) 首先从右向左翻转1次
(1 5 6 3 4 2) -> (1 5 4 2 3 6)
2) 然后从上向下翻转2次
(1 5 4 2 3 6) -> (6 3 4 2 1 5) -> (5 1 4 2 6 3)
对于50%的数据,有: 1 <= N <= 50对于100%的数据,有:1 <= N <= 1,000
#include <bits/stdc++.h> using namespace std; const string dirs[] = {"上","下","左","右","前","后"}; // 默认的顺序 map<string, int> s_idx; // 维护字符串在dirs中的位置 /* 3种不同的旋转方式: ** 例如第一种为 ** [上 -> 右 ], [右 -> 下], [下 -> 左], [左 -> 上] ** 即 上 -> 右 -> 下 -> 左 -> ... */ const string turn[3][4] = { {"上","右","下","左"}, /*前后不动*/ {"上","前","下","后"}, /*左右不动*/ {"前","右","后","左"} /*上下不动*/ }; vector<vector<int> > get_nexts(vector<int> vv) { /** * 获取vv的3个下一种状态 */ vector<vector<int> > ret; for (int i = 0; i < 3; ++i){ auto v = vv; /* 完成“旋转”操作*/ int t = v[s_idx[turn[i][0]]]; for (int j = 1; j < 4; ++j){ v[s_idx[turn[i][j-1]]] = v[s_idx[turn[i][j]]]; } v[s_idx[turn[i][3]]] = t; ret.push_back(v); } return ret; } ostream & operator << (ostream &cout, vector<int> v) { cout << "["; for ( auto i : v ) { cout << i << " "; } cout << "]"; } vector<int> get_min(vector<int> v) { /** * 搜索一趟,获取v通过旋转可达的最小的 */ map<vector<int>, bool> vis; queue<vector<int> > q; vis[v] = 1; q.push(v); vector<int> ret = v; while (q.size()) { vector<int> curr = q.front(); q.pop(); if ( curr < ret ) { ret = curr; } auto nexts = get_nexts(curr); for ( auto next : nexts ) { if ( vis.find(next)==vis.end() ) { vis[next] = 1; q.push(next); } } } return ret; } int main(int argc, char const *argv[]){ for (int i = 0; i < 6; ++i){ s_idx[dirs[i]] = i; } /* vector<int> v = {1,2,3,4,5,6}; set<vector<int>> s; do{ s.insert(get_min(v)); }while(next_permutation(v.begin(), v.end())); for ( auto& item : s ) { for(auto i : item ) { cout << i << " "; } cout << "" << endl; } clog << "s.size() = " << s.size() << endl; //log return 0; // */ int n; cin>>n; map<vector<int>, int> mp; for ( int i = 0; i < n; ++i ) { vector<int> v; for ( int i = 0; i < 6; ++i ) { int x; cin>>x; v.push_back(x); } mp[get_min(v)]++; } vector<int> ans; for ( auto &item : mp ) { ans.push_back(item.second); } sort(ans.begin(), ans.end(), [](int a, int b) -> bool {return a>b;}); // 降序 cout << ans.size() << endl; for ( auto i : ans ) { cout << i << " "; } return 0; }
#include<bits/stdc++.h> using namespace std; int main() { int N; cin >> N; unordered_map<int, int> um; for(int n=1; n<=N; ++n){ int a[6]; for(int i=0; i<6; ++i) cin >> a[i]; int val = 0; for(int i=0; i<6; ++i) { if(a[i]==1) { if(i%2==0) val = a[(i+2)%6]*1000 + a[(i+4)%6]*100 + a[(i+3)%6]*10 + a[(i+5)%6]; else val = a[(i+4)%6]*1000 + a[(i+2)%6]*100 + a[(i+3)%6]*10 + a[(i+1)%6]; break; } } for(int i=0, tmp = val; i<3; ++i) { tmp = tmp/10 + (tmp%10*1000); val = min(val, tmp); } um[val]++; } vector<int> res; for(auto iter : um) res.push_back(iter.second); sort(res.begin(), res.end()); cout << res.size() << endl; for(int i=res.size()-1; i>=0; --i) cout << res[i] << " "; return 0; }
贴一个无脑枚举的方法,因为骰子只有 4 种旋转方法,所以每获得一个新的骰子,就 BFS 一下,把所有可能都遍历到(最多可能 24 种?),然后后面如果在遇到一样的,就可以直接判断它属于哪一种了。
记录每一种的数量,最后输出答案即可。
#include <bits/stdc++.h> #include <cstdio> #include <functional> #include <tuple> #include <unordered_map> #include <vector> using namespace std; struct sieve{ int up, down, left, right, front, back; string to_string() { static char t[15]; // cout << up << ' ' << down << ' ' << left << ' ' << right << ' ' << front << ' ' << back << endl; sprintf(t, "%d%d%d%d%d%d", up, down, left, right, front, back); return string(t); } }; sieve toUp(sieve s) { tie(s.front, s.down, s.back, s.up) = make_tuple(s.down, s.back, s.up, s.front); return s; } sieve toDown(sieve s) { tie(s.front, s.down, s.back, s.up) = make_tuple(s.up, s.front, s.down, s.back); return s; } sieve toLeft(sieve s) { tie(s.front, s.right, s.back, s.left) = make_tuple(s.right, s.back, s.left, s.front); return s; } sieve toRight(sieve s) { tie(s.front, s.right, s.back, s.left) = make_tuple(s.left, s.front, s.right, s.back); return s; } int main() { int n; cin >> n; // 筛子序列化 -> 种类编号 unordered_map<string, int> mp; vector<int> cnt(n); for (int i = 0; i < n; i++) { sieve s; cin >> s.up >> s.down >> s.left >> s.right >> s.front >> s.back; // cout << s.to_string() << endl; if (mp.count(s.to_string())) { cnt[mp[s.to_string()]]++; continue; } // 种类命名为 i cnt[i]++; queue<sieve> q; q.push(s); // cout << "s: " << s.to_string() << endl; while (q.size()) { auto x = q.front(); q.pop(); // cout << x.to_string() << endl; for (auto &y : vector<sieve>{toUp(x), toDown(x), toLeft(x), toDown(x)}) { if (mp.count(y.to_string())) continue; mp[y.to_string()] = i; q.push(y); } } } vector<int> res; for (int i = 0; i < n; i++) { if (cnt[i] > 0) res.push_back(cnt[i]); } sort(res.begin(), res.end(), greater<int>()); cout << res.size() << endl; for (auto x : res) { cout << x << " "; } }
import collections n = int(input()) counter = collections.Counter() finger={} res = [] for i in range(n): l=list(map(int,input().strip().split())) p1 = l[:2] p2 = l[2:4] p3 = l[4:] if min(p1)>min(p2): p1,p2=p2,p1[::-1] if min(p1)>min(p3): p1,p3=p3,p1[::-1] if min(p2)>min(p3): p2,p3=p3,p2[::-1] if p1[0]>p1[1]: p1,p3=p1[::-1],p3[::-1] if p2[0]>p2[1]: p2,p3=p2[::-1],p3[::-1] s = (p1[0],p1[1],p2[0],p2[1],p3[0],p3[1]) if s not in finger: finger[s]=len(res) res.append(1) else: res[finger[s]]+=1 print(len(res)) res=map(str,sorted(res,reverse=True)) print(' '.join(res))
#include <iostream> #include <bits/stdc++.h> // 筛子编码 using namespace std; typedef long long ll; unordered_map<ll, int> mp; // 上、下、左、右、前、后 // 0 1 2 3 4 5 int n; int a[6]; int b[4]; int cur[4]; // 这个很好写,比如2534就是5243翻一下(实在不行自己那个筛子看看) int r[6][4]{ {2,5,3,4},{5,2,4,3},{5,0,4,1},{0,5,1,4},{2,0,3,1},{0,2,1,3} }; ll func() { int ind = 0; // 找到1放在上面 for (int i = 0; i < 6; i++) if (a[i] == 1) { ind = i; break; } // 判断1的对立面是否是2 bool is2 = false; if (a[ind ^ 1] == 2) is2 = true; // 把和1相邻的面顺时针记录 for (int i = 0; i < 4; i++) b[i] = a[r[ind][i]]; // 把上述记录的值最小值放第一位 int miind = 0; if (is2) for (int i = 0; i < 4; i++) { if (b[i] == 3) miind = i; } else for (int i = 0; i < 4; i++) { if (b[i] == 2) miind = i; } // key用ll,省点空间 ll res = 0; for (int i = 0; i < 4; i++) { res |= b[(miind + i) % 4]; res <<= 3; } return res; } int main() { cin >> n; vector<int> vt; for (int i = 0; i < n; i++) { for (int j = 0; j < 6; j++) cin >> a[j]; mp[func()]++; } cout << mp.size() << endl; for (unordered_map<ll, int>::iterator it = mp.begin(); it != mp.end(); it++) { vt.push_back(it->second); } sort(vt.begin(), vt.end()); for (int i = vt.size() - 1; i >= 0; i--) cout << vt[i] << " "; return 0; } // 64 位输出请用 printf("%lld")
和大家一样的想法,想法子将骰子固定住,固定两个面就行了,我是1在上面,先固定上下两面,前后左右四面保证最小的在左侧,怎么转的就稍微想一下就行,很简单
import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[][] matrix = new int[n][6]; for (int i = 0; i < n; i++) { for (int j = 0; j < 6; j++) { matrix[i][j] = sc.nextInt(); } } getDiffNum(matrix, n); } private static void getDiffNum(int[][] matrix, int n) { for (int i = 0; i < n; i++) { // 将数据全转成 1 在上且左侧比右侧小的排序 int[] nums = matrix[i]; for (int j = 0; j < 6; j++) { if (1 == nums[j]) { rotate(nums, j); } } } Map<String, Integer> map = new HashMap<>(); // 进行次数统计 for (int i = 0; i < n; i++) { int[] nums = matrix[i]; StringBuilder sb = new StringBuilder(); for (int j = 0; j < 6; j++) { sb.append(nums[j]); } String key = sb.toString(); if (map.containsKey(key)) { map.put(key, 1 + map.get(key)); } else { map.put(key, 1); } } System.out.println(map.size()); map.values().stream().sorted((t1, t2) -> { return t2 - t1; }).forEach(item -> { System.out.print(item + " "); }); System.out.println(); } private static void rotate(int[] nums, int pos) { if (1 == pos) { swap(nums, 0, 1); swap(nums, 4, 5); } else if (2 == pos) { swap(nums, 0, 2); swap(nums, 1, 3); swap(nums, 2, 3); } else if (3 == pos) { swap(nums, 0, 2); swap(nums, 1, 3); swap(nums, 0, 1); } else if (4 == pos) { swap(nums, 0, 4); swap(nums, 1, 5); swap(nums, 4, 5); } else if (5 == pos) { swap(nums, 0, 4); swap(nums, 1, 5); swap(nums, 0, 1); } rotateLeftMin(nums); } private static void rotateLeftMin(int[] nums) { int idx = -1, min = Integer.MAX_VALUE; for (int i = 2; i < 6; i++) { if (min > nums[i]) { min = nums[i]; idx = i; } } rotate2(nums, idx); } /** * 将第三个位置置为后四个最小值 * @param nums * @param idx */ private static void rotate2(int[] nums, int idx) { if (3 == idx) { swap(nums, 2,3); swap(nums, 4,5); } else if (4 == idx) { swap(nums, 2,4); swap(nums, 3,5); swap(nums, 4,5); } else if (5 == idx) { swap(nums, 2,4); swap(nums, 3,5); swap(nums, 2,3); } } private static void swap(int[] nums, int i, int j) { int tmp = nums[i]; nums[i] = nums[j]; nums[j] = tmp; } }
#include <iostream> #include <bits/stdc++.h> using namespace std; //上下左右前后 //123456 /* 旋转 */ //unordered_map<vector<string,bool> mp; unordered_map<string,int> mp; multiset<int,greater<int>> st; int num[1000+30][7]; void vectortostring(int a[]){ string temp; for(int i=0;i<6;i++){ temp+=a[i]-0+'0'; } mp[temp]+=1; } int main() { int m; cin>>m; for(int i=0;i<m;i++){ for(int j=0;j<6;j++) cin>>num[i][j]; } for(int i=0;i<m;i++){ //label the smallest int sm1=0,sm1label=0; for(int j=0;j<6;j++) if(num[i][j]<num[i][sm1]) sm1=j; if(sm1%2==1){ if(sm1==1||sm1==3){ swap(num[i][0],num[i][1]);//对的 swap(num[i][2],num[i][3]); }else{ swap(num[i][0],num[i][1]); swap(num[i][4],num[i][5]); } sm1-=1; } sm1label=sm1+1; if(!(sm1==0)){ swap(num[i][0],num[i][sm1]); swap(num[i][1],num[i][sm1label]); swap(num[i][sm1],num[i][sm1label]); } int sm2=2,sm2label=2; for(int j=2;j<6;j++) if(num[i][j]<num[i][sm2]) sm2=j; if(sm2%2==1){ swap(num[i][2],num[i][3]); swap(num[i][4],num[i][5]); sm2-=1; } sm2label=sm2+1; if(sm2==4){ swap(num[i][4],num[i][2]); swap(num[i][5],num[i][3]); swap(num[i][sm2],num[i][sm2label]); } vectortostring(num[i]); } cout<<mp.size()<<endl; for(auto i=mp.begin();i!=mp.end();i++) st.insert(i->second); for(auto i=st.begin();i!=st.end();i++) cout<<*i<<" "; return 0; } // 64 位输出请用 printf("%lld")
#include <iostream> #include <bits/stdc++.h> #include <string> using namespace std; //给输入的筛子回归标准型:(上下左右前后) ==(1 2 3 * * *)或(1 * 2 * * *) void checkStdString(string& str) { //交换的逻辑:对子换到要去的位置,换回来的对子反转一下。例如1去第一组:452163 -> 215463 //翻转的逻辑:要翻转的对子反转,然后任一其他对子也要反转。例如反转21为12:215463 -> 125436 , //这样这个例子变成标准型只需要再: 125436 -> 123645 ,符合标准型。 //先把1换到上: int i=0; if(str[0]!='1') { //1不在上 for(i=1; i<6; i++) { if(str[i]!='1') continue; //str[i]是1: if(i==2 || i==4){ swap(str[i],str[0]); swap(str[i+1],str[1]); swap(str[i],str[i+1]); } else if(i==3 || i==5) { swap(str[i],str[0]); swap(str[i-1],str[1]); swap(str[i],str[i-1]); } else { //1在下 swap(str[1],str[0]); swap(str[3],str[2]); } break; } } //检查2或3的位置:除了上下位置中,有2找2,没2找3: char needFind = '2'; if(str[1]=='2') needFind = '3'; //把2或3换到左: for(int i=2; i<6; i++) { if(str[i]!=needFind) continue; if(i==2) break; if(i==3){ swap(str[3],str[2]); swap(str[4],str[5]); } else if(i==5){ swap(str[5],str[2]); swap(str[4],str[3]); swap(str[4],str[5]); } else if(i==4){ swap(str[4],str[2]); swap(str[5],str[3]); swap(str[4],str[5]); } } } int main() { int n; cin >> n; unordered_map<string,int> map; for(int i=0; i<n; i++) { string temp_str; for(int j=0; j<6; j++) { char c; cin >> c; temp_str += c; } checkStdString(temp_str); map[temp_str]++; } vector<int> vec; int ans=0; for(auto x : map){ vec.push_back(x.second); ans++; } sort(vec.begin(), vec.end(), [](const auto &a, const auto &b) {return a > b;} ); printf("%d\n", ans); for(auto x : vec){ printf("%d ", x); } return 0; } // 64 位输出请用 printf("%lld")
import sys from collections import defaultdict def validate_dice(dice): """验证骰子的6个面是否包含1到6且不重复""" return sorted(dice) == [1, 2, 3, 4, 5, 6] class Dice: def __init__(self, state): """初始化骰子状态""" if not validate_dice(state): raise ValueError("Invalid dice state: must contain numbers 1 to 6 without duplicates.") self.state = list(state) self.normalize() def normalize(self): """将骰子标准化:1朝上,最小数朝前""" # 将1旋转到上面 pos_1 = self.state.index(1) if pos_1 == 1: self._rotate_vertical() self._rotate_vertical() elif pos_1 == 2: self._rotate_vertical() elif pos_1 == 3: self._rotate_vertical() self._rotate_vertical() self._rotate_vertical() elif pos_1 == 4: self._rotate_horizontal() self._rotate_vertical() elif pos_1 == 5: self._rotate_horizontal() self._rotate_vertical() self._rotate_vertical() self._rotate_vertical() # 将最小数旋转到前面 min_number = min(self.state[2:]) min_number_index = self.state.index(min_number) if min_number_index == 3: self._rotate_horizontal() self._rotate_horizontal() elif min_number_index == 4: self._rotate_horizontal() elif min_number_index == 5: self._rotate_horizontal() self._rotate_horizontal() self._rotate_horizontal() def _rotate_vertical(self): """绕垂直轴旋转骰子""" self.state[0], self.state[1], self.state[2], self.state[3] = ( self.state[2], self.state[3], self.state[1], self.state[0] ) def _rotate_horizontal(self): """绕水平轴旋转骰子""" self.state[2], self.state[3], self.state[4], self.state[5] = ( self.state[4], self.state[5], self.state[3], self.state[2] ) def main(): # 读取输入 num_dices = int(sys.stdin.readline().strip()) dices = [] for _ in range(num_dices): dice_state = tuple(map(int, sys.stdin.readline().strip().split())) if not validate_dice(dice_state): raise ValueError("Invalid dice state: must contain numbers 1 to 6 without duplicates.") dices.append(dice_state) # 统计骰子类别 dice_count = defaultdict(int) for dice_state in dices: dice = Dice(dice_state) bottom, right, front = dice.state[1], dice.state[3], dice.state[4] dice_count[(bottom, right, front)] += 1 # 输出结果 num_categories = len(dice_count) counts = sorted(dice_count.values(), reverse=True) print(num_categories) print(' '.join(map(str, counts))) if __name__ == "__main__": main()
n = int(input()) abc = [] for i in range(n): line = tuple(map(int, input().split())) abc.append(line) def rotate(a, b, c, d, e, f): dt[(a, b, c, d, e, f)] = count dt[(a, b, e, f, d, c)] = count dt[(a, b, d, c, f, e)] = count dt[(a, b, f, e, c, d)] = count dt = dict() count = 0 res = [] for nums in abc: if nums not in dt: res.append(1) a, b, c, d, e, f = nums rotate(a, b, c, d, e, f) rotate(c, d, b, a, e, f) rotate(e, f, c, d, b, a) rotate(b, a, c, d, f, e) rotate(d, c, a, b, e, f) rotate(f, e, c, d, a, b) count += 1 else: index = dt[nums] res[index] += 1 print(count) res.sort(reverse=True) for cnt in res: print(cnt, end=' ')
import java.util.*; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static int getKey(int[] d,int i,int a,int b,int c,int k){ int ret = 0; if(i==a){ ret+=d[a]*1000+d[b]*100+d[c]*10+d[k]; }else if(i ==b){ ret+=d[b]*1000+d[c]*100+d[k]*10+d[a]; }else if (i == c){ ret+=d[c]*1000+d[k]*100+d[a]*10+d[b]; }else{ ret+=d[k]*1000+d[a]*100+d[b]*10+d[c]; } return ret; } public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); Map<Integer, Integer> map = new HashMap<>(); int[][] input = new int[n][6]; for (int i = 0 ; i < n; i++) { for (int j = 0 ; j < 6 ; j++) { input[i][j] = in.nextInt(); } } for (int i = 0 ; i < n; i++) { //先看1 int[] d = input[i]; for (int j = 0; j < 6; j++) { if (d[j] == 1) { //先看下是不是在上 if (j == 0) { int key = 100000; int a = d[1]; key += a * 10000; int min = 100; if (a != 2) { min = 2; } else { min = 3; } int index = 0; for (int f = 0; f < 6; f++) { if (d[f] == min) { index = f; break; } } //接下来,从2或3开始顺时针转一圈 key+= getKey(d,index,2,4,3,5); if(!map.containsKey(key)){ map.put(key,1); }else{ map.put(key,map.get(key)+1); } }else if(j==1){ int key = 100000; int a = d[0]; key += a * 10000; int min = 100; if (a != 2) { min = 2; } else { min = 3; } int index = 0; for (int f = 0; f < 6; f++) { if (d[f] == min) { index = f; break; } } //接下来,从2或3开始顺时针转一圈 key+= getKey(d,index,2,5,3,4); if(!map.containsKey(key)){ map.put(key,1); }else{ map.put(key,map.get(key)+1); } }else if (j==2){ int key = 100000; int a = d[3]; key += a * 10000; int min = 100; if (a != 2) { min = 2; } else { min = 3; } int index = 0; for (int f = 0; f < 6; f++) { if (d[f] == min) { index = f; break; } } //接下来,从2或3开始顺时针转一圈 key+= getKey(d,index,0,5,1,4); if(!map.containsKey(key)){ map.put(key,1); }else{ map.put(key,map.get(key)+1); } } else if (j==3){ int key = 100000; int a = d[2]; key += a * 10000; int min = 100; if (a != 2) { min = 2; } else { min = 3; } int index = 0; for (int f = 0; f < 6; f++) { if (d[f] == min) { index = f; break; } } //接下来,从2或3开始顺时针转一圈 key+= getKey(d,index,1,5,0,4); if(!map.containsKey(key)){ map.put(key,1); }else{ map.put(key,map.get(key)+1); } } else if (j==4){ int key = 100000; int a = d[5]; key += a * 10000; int min = 100; if (a != 2) { min = 2; } else { min = 3; } int index = 0; for (int f = 0; f < 6; f++) { if (d[f] == min) { index = f; break; } } //接下来,从2或3开始顺时针转一圈 key+= getKey(d,index,0,2,1,3); if(!map.containsKey(key)){ map.put(key,1); }else{ map.put(key,map.get(key)+1); } } else if (j==5){ int key = 100000; int a = d[4]; key += a * 10000; int min = 100; if (a != 2) { min = 2; } else { min = 3; } int index = 0; for (int f = 0; f < 6; f++) { if (d[f] == min) { index = f; break; } } //接下来,从2或3开始顺时针转一圈 key+= getKey(d,index,0,3,1,2); if(!map.containsKey(key)){ map.put(key,1); }else{ map.put(key,map.get(key)+1); } } break; } } } List<Integer> list = new ArrayList<>(map.values()); Collections.sort(list,new Comparator<Integer>(){ public int compare(Integer s,Integer t1 ){ return t1-s; } }); System.out.println(map.keySet().size()); for(int i = 0 ; i < list.size();i++){ System.out.print(list.get(i)+" "); } } }
import java.util.*; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); // 注意 hasNext 和 hasNextLine 的区别 int n = Integer.parseInt(in.nextLine()); HashMap<String, Integer> myhashMap = new HashMap<>(); for (int i = 0; i < n; i++) { String line = in.nextLine(); Touzi temp = new Touzi(line); myhashMap.put(temp.toString(),myhashMap.getOrDefault(temp.toString(),0)+1); } System.out.println(myhashMap.keySet().size()); ArrayList<Integer> result=new ArrayList<>(); for(String key:myhashMap.keySet()){ result.add(myhashMap.get(key)); } result.sort((x,y)->y-x); for(Integer i:result){ System.out.print(i+" "); } } } class Touzi { public int top; public int bottom; public int left; public int right; public int front; public int behind; Touzi(String line) { String [] temps = line.split(" "); top = Integer.parseInt(temps[0]); bottom = Integer.parseInt(temps[1]); left = Integer.parseInt(temps[2]); right = Integer.parseInt(temps[3]); front = Integer.parseInt(temps[4]); behind = Integer.parseInt(temps[5]); while (top != 1) { if (bottom == 1 || behind == 1 || front == 1) { verticalswap(); } else { horizontalswap(); } } while (left > right||front>behind) { horizontalswap(); } } public String toString() { return top+ "" + bottom +""+ left+"" + right+"" + front+"" + behind ; } public void horizontalswap() { int templeft = this.left; int tempright = this.right; int tempfront = this.front; int tempbehind = this.behind; this.left = tempfront; this.behind = templeft; this.right = tempbehind; this.front = tempright; } public void verticalswap() { int tempfront = this.front; int tempbehind = this.behind; int temptop = this.top; int tempbottom = this.bottom; this.front = temptop; this.bottom = tempfront; this.behind = tempbottom; this.top = tempbehind; } }
#include <iostream> #include <map> #include <vector> #include <algorithm> using namespace std; map<vector<pair<int, int>>, int> p; struct dice { vector<pair<int, int>> v; vector<pair<int, int>> f; dice(vector<pair<int, int>> v) : v(v) { } void dau() { f = {v[2], v[1], {v[0].second, v[0].first}}; v = f; if (v[0].first > v[0].second) { swap(v[0].first, v[0].second); swap(v[2].first, v[2].second); } } void lar() { f = {v[1], {v[0].second, v[0].first}, v[2]}; v = f; if(v[0].first > v[0].second) { swap(v[0].first, v[0].second); swap(v[1].first, v[1].second); } } void oao() { f = {v[0], v[2], {v[1].second, v[1].first}}; v = f; if (v[1].first > v[1].second) { swap(v[1].first, v[1].second); swap(v[2].first, v[2].second); } } void find() { int idx = 0; for (; idx < 3; idx++) { if (v[idx].first == 1 || v[idx].second == 1) break; } if (idx == 0) { lar(); lar(); oao(); if (v[1] > v[2] || v[1].first > v[2].second) oao(); } else if (idx == 1) { lar(); oao(); if (v[1] > v[2] || v[1].first > v[2].second) oao(); } else { dau(); oao(); if (v[1] > v[2] || v[1].first > v[2].second) oao(); } } }; vector<int> ans; int main() { int n; cin >> n; int a, b, c, d, e, f; for (int i = 0; i < n; i++) { cin >> a >> b >> c >> d >> e >> f; dice x({{a, b}, {c, d}, {e, f}}); x.find(); p[x.v]++; } for (auto &t: p) { ans.push_back(t.second); } sort(ans.begin(), ans.end(), greater<int>()); cout << ans.size() << endl; for (auto &t: ans) cout << t << " "; }
将每个骰子固定两个面,骰子的排序就是固定的,我选择将1转到上,剩下最大的转到左边 #include<bits/stdc++.h> using namespace std; string i2j(vector<int> a){ int id1; for(int i=0;i<6;i++){ if(a[i]==1) { id1=i; break; } } if(id1>1){ if(id1%2==0){ swap(a[id1],a[0]); swap(a[id1+1],a[1]); swap(a[id1+1],a[id1]); } else{ swap(a[id1],a[1]); swap(a[id1-1],a[0]); swap(a[1],a[0]); } } else{ if(id1==1){ swap(a[0],a[1]); swap(a[2],a[3]); } } int num_next=6; if(a[1]==6){ num_next=5; } int id_next; for(int i=2;i<6;i++){ if(a[i]==num_next){ id_next=i; break; } } if(id_next!=2){ if(id_next==3){ swap(a[2],a[3]); swap(a[4],a[5]); } else if(id_next==4){ swap(a[2],a[4]); swap(a[3],a[5]); swap(a[4],a[5]); } else{ swap(a[2],a[4]); swap(a[3],a[5]); swap(a[2],a[3]); } } string out=""; for(int i=0;i<6;i++){ out+=to_string(a[i]); } return out; } int main(){ int num=0; cin>>num; unordered_map<string , int> a; for(int i=0;i<num;i++){ vector<int> tmp(6,0); for(int j=0;j<6;j++){ cin>>tmp[j]; } string b=i2j(tmp); a[b]++; } cout<<a.size()<<endl; vector<int > c; for(auto i:a){ c.push_back(i.second); } sort(c.begin(),c.end(),greater<int>()); for(auto i:c){ cout<<i<<" "; } }
class dice(): def __init__(self, a): self.a=a def switch_out(self,i,j): if i!=j: self.a[2*i], self.a[2*i+1], self.a[2*j], self.a[2*j+1] = \ self.a[2*j], self.a[2*j+1], self.a[2*i+1], self.a[2*i] def switch_in(self,i): if self.a[2*i]>self.a[2*i+1]: self.a[2*i], self.a[2*i+1] = self.a[2*i+1], self.a[2*i] self.a[2*i+2], self.a[2*i+3] = self.a[2*i+3], self.a[2*i+2] def tidy(self): i1=self.a.index(1)//2 self.switch_out(0, i1) self.switch_in(0) i2=self.a.index(min(self.a[2:]))//2 self.switch_out(1, i2) self.switch_in(1) return tuple(self.a) n=int(input()) dc={} for i in range(n): nd=dice(list(map(int, input().split()))).tidy() dc[nd]=dc.get(nd, 0)+1 print(len(dc.keys())) for v in sorted(dc.values(), reverse=True): print(v, end=" ")
#include<iostream> #include<vector> #include<algorithm> using namespace std; int a[24][6] = { {1,2,3,4,5,6}, {4,3,1,2,5,6}, {2,1,4,3,5,6}, {3,4,2,1,5,6}, {1,2,4,3,6,5}, {3,4,1,2,6,5}, {2,1,3,4,6,5}, {4,3,2,1,6,5}, {1,2,6,5,3,4}, {5,6,1,2,3,4}, {2,1,5,6,3,4}, {6,5,2,1,3,4}, {1,2,5,6,4,3}, {6,5,1,2,4,3}, {2,1,6,5,4,3}, {5,6,2,1,4,3}, {6,5,3,4,1,2}, {4,3,6,5,1,2}, {5,6,4,3,1,2}, {3,4,5,6,1,2}, {5,6,3,4,2,1}, {4,3,5,6,2,1}, {6,5,4,3,2,1}, {3,4,6,5,2,1} }; int shai[6], tmp[6]; vector<int> cnt; int out[1010][6]; bool check(int a[6], int b[6]) { int flag = 1; for(int k = 0; k < 6; k++) { if(a[k] != b[k]) { flag = 0; break; } } return flag; } int main() { int N; cin >> N; for(int i = 0; i < N; i++) { for(int j = 0; j < 6; j++) cin >> shai[j]; int flag = 0; for(int c = 0; c < cnt.size(); c++) { // 和每一个做对比 // 有24种可能 for(int j = 0; j < 24; j++) { for(int k = 0; k < 6; k++) { tmp[k] = shai[a[j][k] - 1]; } if(check(out[c], tmp)) { cnt[c]++; flag = 1; break; } } if(flag) break; } if(flag == 0) { for(int k = 0; k < 6; k++) out[cnt.size()][k] = shai[k]; cnt.push_back(1); } } sort(cnt.begin(), cnt.end()); cout << cnt.size() << endl; for(int i = cnt.size() - 1; i >= 0; i--) cout << cnt[i] << ' '; }
from collections import * N = int(input()) _d = defaultdict(int) for l in range(N): tou = input().split() for i in range(6): tou[i] = int(tou[i]) # 旋转骰子 # 上0、下1、左2、右3、前4、后5 high ,low ,left ,right ,front ,back = 0,1,2,3,4,5 whereis1 = tou.index(1) if whereis1 == low:# 1在下面 tou[high], tou[low] ,tou[left] , tou[right] = tou[low], tou[high] ,tou[right] , tou[left] elif whereis1 == left: # 1在左边 tou[high], tou[low] ,tou[left] , tou[right] = tou[left], tou[right], tou[low], tou[high] elif whereis1 == right:#右边 tou[high], tou[low] ,tou[left] , tou[right] = tou[right], tou[left], tou[high] , tou[low] elif whereis1 == front: tou[high], tou[low] , tou[front], tou[back] = tou[front], tou[back], tou[low],tou[high] elif whereis1 == back: tou[high], tou[low] , tou[front], tou[back] = tou[back],tou[front],tou[high],tou[low] _str = str(low)#让1在最上面了 #左0、右1、前2、后3 left, right, front ,back = 0,1,2,3 tou = tou[2:] whereismin = tou.index(min(tou)) # 让min在左边 if whereismin == right: tou[left] , tou[right], tou[front], tou[back] = tou[right], tou[left], tou[back], tou[front] elif whereismin == front: tou[left] , tou[right], tou[front], tou[back] = tou[front], tou[back], tou[right], tou[left] elif whereismin == back: tou[left] , tou[right], tou[front], tou[back] = tou[back], tou[front], tou[left], tou[right] _str += str(tou[left])+str(tou[front])+str(tou[right])+str(tou[back]) _d[_str]+=1 print(len(_d)) A= list(_d.values()) A.sort() A = A[::-1] for i in range(len(A)): print(A[i],end=" ")
并查集
#include <bits/stdc++.h> using namespace std; int n; vector<int> fa, sz; int find(int x) { return x == fa[x] ? fa[x] : (fa[x] = find(fa[x])); } bool merge(int x, int y) { x = find(x), y = find(y); if (x == y) { return false; } if (sz[x] < sz[y]) { swap(x, y); } fa[y] = x; sz[x] += sz[y]; return true; } int main() { cin >> n; vector<vector<int>> S(n, vector<int>(6)); fa.resize(n), sz.resize(n, 1); iota(fa.begin(), fa.end(), 0); for (int i = 0; i < n; ++i) { for (int j = 0; j < 6; ++j) { cin >> S[i][j]; } } auto f = [&](int i) -> vector<int> { if (S[i][0] == 1) { return vector<int>{S[i][5], S[i][3], S[i][4], S[i][2]}; } else if (S[i][1] == 1) { return vector<int>{S[i][4], S[i][3], S[i][5], S[i][2]}; } else if (S[i][2] == 1) { return vector<int>{S[i][0], S[i][4], S[i][1], S[i][5]}; } else if (S[i][3] == 1) { return vector<int>{S[i][0], S[i][5], S[i][1], S[i][4]}; } else if (S[i][4] == 1) { return vector<int>{S[i][0], S[i][3], S[i][1], S[i][2]}; } return vector<int>{S[i][0], S[i][2], S[i][1], S[i][3]}; }; auto alike = [&](int i, int j) -> bool { auto a = f(i), b = f(j); for (int ii = 0; ii < 4; ++ii) { for (int jj = 0; jj < 4; ++jj) { if (a[ii] == b[jj]) { for (int k = 0; k < 4; ++k) { if (a[(ii + k) % 4] != b[(jj + k) % 4]) { return false; } } return true; } } } return false; }; for (int i = 0; i < n; ++i) { for (int j = i + 1; j < n; ++j) { if (alike(i, j)) { merge(i, j); } } } vector<int> T; for (int i = 0; i < n; ++i) { if (i == fa[i]) { T.emplace_back(sz[i]); } } sort(T.begin(), T.end(), greater<>()); int m = T.size(); cout << m << '\n'; for (int i = 0; i < m; ++i) { cout << T[i] << " \n"[i == m - 1]; } return 0; }