1. 程式人生 > >P1563 玩具謎題 題解

P1563 玩具謎題 題解

題目描述: 小南有一套可愛的玩具小人, 它們各有不同的職業。有一天, 這些玩具小人把小南的眼鏡藏了起來。 小南發現玩具小人們圍成了一個圈,它們有的面朝圈內,有的面朝圈外。如下圖:這時singersinger告訴小南一個謎題: “眼鏡藏在我左數第3個玩具小人的右數第11個玩具小人的左數第22個玩具小人那裡。 ”小南發現, 這個謎題中玩具小人的朝向非常關鍵, 因為朝內和朝外的玩具小人的左右方向是相反的: 面朝圈內的玩具小人, 它的左邊是順時針方向, 右邊是逆時針方向; 而面向圈外的玩具小人, 它的左邊是逆時針方向, 右邊是順時針方向。小南一邊艱難地辨認著玩具小人, 一邊數著:singersinger朝內, 左數第33個是archerarcher。archerarcher朝外,右數第11個是thinkerthinker。thinkerthinker朝外, 左數第22個是writewriter。所以眼鏡藏在writerwriter這裡!雖然成功找回了眼鏡, 但小南並沒有放心。 如果下次有更多的玩具小人藏他的眼鏡, 或是謎題的長度更長, 他可能就無法找到眼鏡了 。 所以小南希望你寫程式幫他解決類似的謎題。 這樣的謎題具體可以描述為:有 nn個玩具小人圍成一圈, 已知它們的職業和朝向。現在第11個玩具小人告訴小南一個包含mm條指令的謎題, 其中第 zz條指令形如“左數/右數第ss,個玩具小人”。 你需要輸出依次數完這些指令後,到達的玩具小人的職業。

題解: 作為演算法小白,看到這道題的時候,感覺和大一刷的noj後十題有一題比較像,感覺不需要複雜的演算法,然後就開始了自己的嘗試。題目規定按逆時針輸入玩具人的資訊,那麼就將逆時針作為正方向,每個玩具人依次按陣列下標0,1,2,···n排列。初始位置玩具人的下標為0,以k記錄當前玩具人的下標,每執行一次命令就更新一次k。每條命令的長度記為length。當玩具人朝向為內且命令要求左數或玩具人朝向為外且右數時,相當於朝負方向數length個玩具人,因為玩具人下標範圍為0~n-1,所以可以用(k -length+n)%n表示執行完該指令後指向的玩具人的下標;當玩具人朝向為內且命令要求右數或玩具人朝向為外且左數時,相當於朝正方向數length個玩具人,因為玩具人下標範圍為0~n-1,所以可以用(k +length+n)%n表示執行完該指令後指向的玩具人的下標;遍歷完所有命令後的k即代表題目所求玩具人的下標。 程式碼: #include using namespace std; struct ToolPerson{ int direction; string work; }; int main() { int n,m,k = 0,orderdir,orderlength;//k表示執行完之前指令後當前指向的玩具人的位置; ToolPerson tool[100000]; cin >> n >> m; for(int i = 0;i < n;i ++) { cin >> tool[i].direction >> tool[i].work; } for(int j = 0;j < m;j ++) { cin >> orderdir >> orderlength; if(tool[k].direction == orderdir) { k = (k - orderlength + n)%n; } else k = (k + orderlength + n)%n; } cout <<tool[k].work<<endl; return 0; }