Gym 101667F Philosopher's Walk
Posted liqgnonqfu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gym 101667F Philosopher's Walk相关的知识,希望对你有一定的参考价值。
题目大意:
哲学家用递归的方式构造里一个地图并按其散步,现在,已知图的边长,以及哲学家的步数,求哲学家的位置坐标。构图方式如下:
输入保证边长为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 ",x,y); 107 return 0; 108 }
/*比赛是这个出了好多小错误,断断续续调了3个多小时,也因为以前一直用dev的单步调试,输入输出调试不熟练。*/
以上是关于Gym 101667F Philosopher's Walk的主要内容,如果未能解决你的问题,请参考以下文章
Dining-Philosopher's Monitor 解决方案:`pickup(i)` 是不是需要间接调用`self[i].signal()`?