日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

字节--旋转魔方

發布時間:2024/4/11 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 字节--旋转魔方 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

字節–旋轉魔方

文章目錄

  • 字節--旋轉魔方
    • 一、題目描述
    • 二、分析
      • 三、代碼

一、題目描述

二階魔方又叫小魔方,是222的立方形結構。每一面都有4個塊,共有24個塊。每次操作可以將任意一面逆時針或者順時針旋轉90°,如將上面逆時針旋轉90°操作如下。

Nero在小魔方上做了一些改動,用數字替換每個塊上面的顏色,稱之為數字魔方。魔方上每一面的優美度就是這個面上4個數字的乘積,而魔方的總優美度就是6個面優美度總和。
現在Nero有一個數字魔方,他想知道這個魔方在操作不超過5次的前提下能達到的最大優美度是多少。

魔方展開后每一塊的序號如下圖:

  • 輸入描述:
輸入一行包含24個數字,按序號順序給出魔方每一塊上面的數字。 所有數大小范圍為[-100,100]
  • 輸出描述:
輸出一行包含一個數字,表示最大優美度。輸入例子1: 2 -3 -2 3 7 -6 -6 -7 9 -5 -9 -3 -2 1 4 -9 -1 -10 -5 -5 -10 -4 8 2輸出例子1: 8281

二、分析

這道題很多人一看題就有思路,這不就是一個搜索問題嘛,無非就是(順時針、逆時針)和(上下左右前后六個面)的組合情況嘛,但是難就難在怎么把每種旋轉給表示出來,用什么數據結構而已

  • 靜下心來仔細這道題目,其實也不難,只是過程很繁瑣,就是bfs搜索解決,核心是怎么將魔方旋轉時魔方方塊的位置變動表達出來,解決這個剩下的就很好辦了。
  • 這里魔方直接用一個數組vec保存,假設魔方底面右旋一次,對應位置變換
  • 同樣,每一面的右旋都可以求出位置變換矩陣來,剩下的就是dfs求解的過程了。
  • 為了方便,我們只考慮魔方逆時針的旋轉情況,因為順時針可以用逆時針旋轉3次模擬出來

三、代碼

#include<iostream> #include<vector> #include<algorithm> using namespace std;const int n = 24;//六個面在經過一次逆時針旋轉后的位置變化情況,可以畫圖驗證 const int Rotate[6][24] = {//FRONT{0, 1, 11, 5, 4, 16, 12, 6, 2, 9, 10, 17, 13, 7, 3, 15, 14, 8, 18, 19, 20, 21, 22, 23},//BEHIND{9, 15, 2, 3, 1, 5, 6, 7, 8, 19, 0, 11, 12, 13, 14, 18, 16, 17, 4, 10, 22, 20, 23, 21},//LEFT{20, 1, 22, 3, 10, 4, 0, 7, 8, 9, 11, 5, 2, 13, 14, 15, 6, 17, 12, 19, 16, 21, 18, 23},//RIGHT{0, 7, 2, 13, 4, 5, 6, 17, 14, 8, 10, 11, 12, 19, 15, 9, 16, 21, 18, 23, 20, 1, 22, 3},//UP{2, 0, 3, 1, 6, 7, 8, 9, 23, 22, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 5, 4},//DOWN{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 21, 20, 10, 11, 12, 13, 18, 16, 19, 17, 15, 14, 22, 23} };//魔方6個面的位置坐標 const int side[6][4] = {{0, 1, 2, 3},{4, 5, 10, 11},{6, 7, 12, 13},{8, 9, 14, 15},{16, 17, 18, 19},{20,21, 22, 23} };//旋轉操作 //vec就代表魔方,用數組表示 //i代表旋轉那個面 void rotateRC(vector<int>& vec, int i) {//拷貝一份vector<int> tmp(vec);//根據i,把旋轉完成后的面重新賦值給vec//n為24,相當于把旋轉后的內容給了vecfor (int j = 0; j < n; ++j){//Rotate[i][j]:i代表旋轉那個面,定位在Rotate數組的那個位置//找到正確的位置直接賦值即可vec[j] = tmp[Rotate[i][j]];}tmp.clear(); }//求整個魔方的優美度 long long getArea(const vector<int>& vec) {long long sum = 0, mul = 1;for (int i = 0; i < 6; ++i){for (int j = 0; j < 4; ++j){mul *= vec[side[i][j]];}sum += mul;mul = 1;}return sum; }//搜索 long long dfs(vector<int> vec, int count) {//獲取當前魔方狀態的優美度并保存long long ans = getArea(vec);//判斷操作次數if (0 == count) return ans;//用i分別模擬待旋轉的6個面for (int i = 0; i < 6; ++i){vector<int> tmp(vec);//代表逆時針旋轉一次rotateRC(tmp, i);//在旋轉一次的基礎上遞歸ans = max(ans, dfs(tmp, count - 1));//順時針旋轉(逆時針旋轉3次相當于順時針旋轉1次)rotateRC(tmp, i);rotateRC(tmp, i);//在順時針旋轉的基礎上遞歸ans = max(ans, dfs(tmp, count - 1));}return ans; } int main() {vector<int> vec(n);for (int i = 0; i < n; ++i)cin >> vec[i];//dfs搜索cout << dfs(vec, 5) << endl;system("pause");return 0; }
  • 總之發現這道題并不難,重點是怎么表示‘旋轉’而已

總結

以上是生活随笔為你收集整理的字节--旋转魔方的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。