1. 程式人生 > 其它 >學習隨筆——POJ題目2965:The Pilots Brothers' refrigerator解答

學習隨筆——POJ題目2965:The Pilots Brothers' refrigerator解答

本題題目連結:http://poj.org/problem?id=2965

本題前置題目:POJ1753  相關講解連結:https://www.cnblogs.com/johnsonstar/p/15981589.html

題目截圖如下:

思路依然和POJ1753一樣是列舉,區別如下:①最終判定條件為所有字元全為“-” ②需要記錄經過的點的座標

關於座標的記錄,本處思路是開闢一個棧和一個最終輸出陣列來記錄座標。當棋子第一次被翻轉,便將座標壓入棧中;當棋子二次翻轉(也即復位)後,我們再將座標彈出。每當最小步數更新時,我們便將臨時座標填入最終輸出實現更新。

程式碼如下:

 1 #include <stdio.h>
 2
#include <iostream> 3 using namespace std; 4 typedef struct M_Stack{ 5 int x_pos[30]; 6 int y_pos[30]; 7 int num; 8 }M_Stack; 9 M_Stack pos_ans; 10 int mem[16]={0};//記憶化 11 int ans=100;//最終解答 12 int x_ans[30]={0}; 13 int y_ans[30]={0};//x座標與y座標最終輸出 14 int Stack_num=0; 15 void Stack_In (int
x,int y){ 16 x_ans[Stack_num]=x; 17 y_ans[Stack_num]=y; 18 Stack_num++; 19 }//將棧元素壓入 20 void Stack_Out (){ 21 Stack_num--; 22 x_ans[Stack_num]=0; 23 y_ans[Stack_num]=0; 24 }//將棧元素彈出 25 void Stack_change (){ 26 for (int i=0;i<Stack_num;i++){ 27 pos_ans.x_pos[i]=x_ans[i];
28 pos_ans.y_pos[i]=y_ans[i]; 29 } 30 pos_ans.num=Stack_num; 31 }//更新棧元素 32 int find_x (int i){ 33 return i/4+1; 34 }//座標轉換 35 int find_y (int i){ 36 return i%4+1; 37 }//座標轉換 38 void change (int i){ 39 int x_pos=i/4; 40 int y_pos=i%4; 41 mem[i % 16] =! mem[i % 16]; 42 mem[(i + 4) % 16] = !mem[(i + 4) % 16]; 43 mem[(i + 8) % 16] = !mem[(i + 8) % 16]; 44 mem[(i + 12) % 16] = !mem[(i + 12) % 16]; 45 mem[x_pos * 4 + y_pos % 4] = !mem[x_pos * 4 + y_pos % 4]; 46 mem[x_pos * 4 + (y_pos + 1) % 4] = !mem[x_pos * 4 + (y_pos + 1) % 4]; 47 mem[x_pos * 4 + (y_pos + 2) % 4] = !mem[x_pos * 4 + (y_pos + 2) % 4]; 48 mem[x_pos * 4 + (y_pos + 3) % 4] = !mem[x_pos * 4 + (y_pos + 3) % 4]; 49 mem[i] = !mem[i]; 50 }//翻轉 51 bool Judge (){ 52 for (int i=0;i<16;i++){ 53 if (mem[i]!=1) 54 return false; 55 } 56 return true; 57 }//判斷是否滿足終止條件 58 void Enum (int num,int count){ 59 if (Judge()){ 60 if (count<ans){ 61 ans=count; 62 Stack_change();//更新 63 return ; 64 } 65 } 66 if (num>=16) 67 return ; 68 int x_pos=find_x(num); 69 int y_pos=find_y(num); 70 change(num); 71 Stack_In (x_pos,y_pos);//第一次翻轉將座標壓入 72 Enum (num+1,count+1); 73 change(num); 74 Stack_Out();//復位將座標彈出 75 Enum (num+1,count); 76 return ; 77 } 78 int main (int argc,char* argv[]){ 79 char temp; 80 for (int i=0;i<16;i++){ 81 cin>>temp; 82 if (temp=='-') 83 mem[i]=1; 84 } 85 Enum(0,0); 86 printf("%d\n",ans); 87 for (int i=0;i<pos_ans.num;i++) 88 printf("%d %d\n",pos_ans.x_pos[i],pos_ans.y_pos[i]); 89 return 0; 90 }