1. 程式人生 > >IQ使命2 Tikal 提卡爾(旋轉的通道)攻略

IQ使命2 Tikal 提卡爾(旋轉的通道)攻略

IQ使命2 

目錄:


本章規則:


把硬幣移入洞內,如果移動到帶有旋轉箭頭的格子,這個格子就會按照箭頭的方向旋轉90°

(1)


右上下右

(2)


紅色的格子會全部一起旋轉

左下上左上

(3)


左下右左上下右右右上左

(4)


左上下左下上右下

(5)


下左上左上左下下右下右右

(6)


上下上上下右右左右下右上左上

(7)


右上上左左下上左左下下上右

(8)


右上右下下上下下上左下左左

(9)


右上右右左右右下下左右左左下左下左上

(10)


左下右左右右左右下右

(11)


到這一關,我就程式設計解決了。

因為每一步移動的可選擇項很少,所以直接用深度優先搜尋就能得到答案

程式碼:

#include<iostream>
#include<stack>
#include<string>
using namespace std;

const int M = 25;//最多需要的步數
int l[6][6];//每個格子的旋轉方向
bool red[6][6];//每個格子是否為紅格子
bool con[6][6][4];//每個格子的每個方向是否有介面
int sr, sc, er, ec;//起點和終點的位置
int dr[4] = { -1, 0, 1, 0 };
int dc[4] = { 0, 1, 0, -1 };
stack<int>
s, s2; bool ok(int k) { int tr = sr + dr[k], tc = sc + dc[k]; if (tr<0 || tr>5 || tc<0 || tc>5||l[tr][tc]<0)return false; return con[sr][sc][k] && con[tr][tc][(k+2)%4]; } void turn(int i, int j, int times) { while (times--) { bool temp = con[i][j][3]; con[i][j][3] = con[
i][j][2]; con[i][j][2] = con[i][j][1]; con[i][j][1] = con[i][j][0]; con[i][j][0] = temp; } } void turn(int i, int j,bool flag)//flag=true表示正向,false表示回溯 { if (flag) { if (red[i][j]) { for (int i = 0; i < 6; i++)for (int j = 0; j < 6; j++)if (red[i][j])turn(i, j, l[i][j]); } else turn(i, j, l[i][j]); } else if (red[i][j]) { for (int i = 0; i < 6; i++)for (int j = 0; j < 6; j++)if (red[i][j])turn(i, j, 4 - l[i][j]); } else turn(i, j, 4-l[i][j]); } bool trys(int deep) { if (deep > M)return false; if (sr == er && sc == ec)return true; for (int i = 0; i < 4; i++)if (ok(i)) { sr += dr[i], sc += dc[i]; turn(sr, sc, true); s.push(i); if (trys(deep + 1))return true; //深度優先搜尋 s.pop(); turn(sr, sc, false); //這裡的順序尤其喲注意 sr -= dr[i], sc -= dc[i]; } return false; } int main() { int r, c, a; cout << "依次輸入36個格子的4種類型\n-1是無效格子,0是不轉的格子,1是順時針轉的格子,3是逆時針轉的格子\n"; for (int i = 0; i < 6; i++)for (int j = 0; j < 6; j++) { cin >> l[i][j]; red[i][j] = false; for (int k = 0; k < 4; k++)con[i][j][k] = false; } cout << "輸入每個紅格子在第幾行第幾列,以(-1,-1)結尾\n"; while (cin >> r >> c && r >= 0)red[r][c] = true; cout << "輸入每個有效格子有哪些介面,0是上面,1是右邊,2是下面,3是左邊,以4結尾\n"; for (int i = 0; i < 6; i++)for (int j = 0; j < 6; j++) if(l[i][j]>=0)while (cin >> a && a != 4)con[i][j][a] = true; cout << "輸入起點和終點的位置\n"; cin >> sr >> sc >> er >> ec; while (!s.empty())s.pop(); trys(0); while (!s.empty()) { s2.push(s.top()); s.pop(); } cout << "答案是:"; stringstr[4] = { "上", "右", "下", "左" }; while (!s2.empty()) { cout << str[s2.top()]; s2.pop(); } cout << " END"; return 0; }

其中M是需要的步數,通過不斷調整M重新執行,還可以求出所需的最小步數

執行結果:


(12)


左上左左下上下下右下左右下右左右右右上左下上左

(13)


下右上右左右右下下左左左下下上下下右上右右右上右下上下下

(14)


左下上左下左上上左下下左上上下上上下上上上下右

(15)


下左左上上下上上右右右右左右右下上左右下左左右左右右上左左左右左左右左左下上右左下下下右右右下上右

這是我自己一步步嘗試得到的答案,一共49步

用我的程式可以算出來,最少需要38步,38步的方案是:

下左左上上下上上右右右右左右右下左下右下下下上下左右左左左左右上左上右下上右

(16)


下下上右右下右上下右上左右上右下上下下上下下左下左左上下左右上右左上下下左左

(17)


左下右下右右左右上下左左上右

(18)


左右右左下左下下右上左左上下上上上下上上右

(19)


下右下右上下上上右右下右左左下右上上右

(20)


右下左左上右上上上右左上右左左下上左左下下下上下上上下上上左

(21)


上左上左上下右左下下上右左右右下上右右上右下下下下上左上左

(22)


左左下上上上上下上上右右左右左左下上左下上左左右左下

(23)


右左上右左左左下下上下下右右下上左右下下右右左右右上

(24)


左右左左上上左上右左左右左左上右右上左左

(25)


左下上左上下上下下上下下上右左右右下右下右左上下右左上上

(26)


下右下左右上上右左上右上上右右左右右下下

(27)


右上左右上下下左右下下上下下左左右左左左上左下上上右

(28)


右上左右上下下右上右左上

(29)


上右上左左下上左右右下上左下左下左右下下右下右上右左右右上上下上上下上上

(30)


下左右下上右左上下左下左右上下左左左右右左右右上下左右上左左下左上下上上上右

(31)


左左右左下右下下左下右上下右上右右上下右下上左下上左右上右上下下下下左左左

(32)


左上下右左上左上下下上下下右上右左下右下下左上下右右左右右右上下上上左上下左 


這是一個彩蛋,其實就是猜數遊戲,規則:猜數遊戲


成就:


the grand champion of rotation 通關即可

the secret of 10 steps 在10步之內完成整個遊戲(這到底是什麼意思我也不知道,反正按照我這樣完成每一關就能完成這個成就)

π of the mayan people 移動到所有固定的邊界(還是不知道是什麼意思,而且第6關的固定的邊界明顯無法達到)