1. 程式人生 > >Gym 101667F Philosopher's Walk

Gym 101667F Philosopher's Walk

手寫 現在 lap ems scanf color 修改 2-0 print

題目大意:

哲學家用遞歸的方式構造裏一個地圖並按其散步,現在,已知圖的邊長,以及哲學家的步數,求哲學家的位置坐標。構圖方式如下:

技術分享圖片技術分享圖片技術分享圖片

輸入保證邊長為2^k的形式,且0<k<=15。

思路:
先判斷哲學家在記錄當前圖的哪一個方框(主要是左下和右下可能加的不一樣),從那個方框的起點,走了多少步到目標位置;在將圖縮小到上一個,做同樣操作。最後從最小的圖開始按照記錄走回來,就求出坐標了。

//顯然是要寫遞歸的,但我開始想錯了寫成了一個簡單的循環,修改時直接加了個手寫棧,所以我的代碼可能比較長。

技術分享圖片
  1 #include<cstdio>
  2 #include<cstring>
  3
#include<algorithm> 4 #include<iostream> 5 using namespace std; 6 7 int k; 8 long long m; 9 long long add[1000][4]; 10 int n,p; 11 12 int cas(long long x) 13 { 14 int cnt=0; 15 while(x>(1<<(2*k))) 16 { 17 x=x-(1<<(2*k)); 18 cnt++;
19 } 20 return cnt+1; 21 } 22 23 int main() 24 { 25 scanf("%d",&n); 26 cin>>m; 27 while(n) 28 { 29 n>>=1; 30 k++; 31 } 32 k--; 33 add[p][1]=0; 34 add[p][2]=0; 35 memset(add,0,sizeof(add)); 36 while(m) 37 {
38 p++; 39 if(k==1) 40 { 41 add[p][1]=1;add[p][2]=1; 42 for(int i=1;i<m;i++) 43 { 44 if(i==1)add[p][2]++; 45 if(i==2)add[p][1]++; 46 if(i==3)add[p][2]--; 47 } 48 break; 49 } 50 k--; 51 if(cas(m)==1) 52 { 53 m=(1<<(2*k))-m+1; 54 add[p][3]=1; 55 add[p][1]=1; 56 add[p][2]=(1<<k); 57 } 58 if(cas(m)==2) 59 { 60 m=m-(1<<(k*2)); 61 add[p][2]=(1<<k)+1; 62 add[p][1]=1; 63 } 64 if(cas(m)==3) 65 { 66 m=m-(1<<(k*2))*2; 67 add[p][1]=1+(1<<(k)); 68 add[p][2]=1+(1<<(k)); 69 } 70 if(cas(m)==4) 71 { 72 m=m-(1<<(2*k))*3; 73 m=(1<<(k*2))-m+1; 74 add[p][1]=(1<<(k+1)); 75 add[p][2]=1; 76 add[p][3]=4; 77 } 78 } 79 int x,y; 80 x=1; 81 y=1; 82 while(p) 83 { 84 x--; 85 y--; 86 if(add[p][3]==4) 87 { 88 int yy=y; 89 y=add[p][2]+x; 90 x=add[p][1]-yy; 91 } 92 if(add[p][3]==1) 93 { 94 int yy=y; 95 y=add[p][2]-x; 96 x=add[p][1]+yy; 97 } 98 if(add[p][3]==0) 99 { 100 int yy=y; 101 x+=add[p][1]; 102 y+=add[p][2]; 103 } 104 p--; 105 } 106 printf("%d %d\n",x,y); 107 return 0; 108 }
View Code

/*比賽是這個出了好多小錯誤,斷斷續續調了3個多小時,也因為以前一直用dev的單步調試,輸入輸出調試不熟練。*/

Gym 101667F Philosopher's Walk