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 }
View Code

/*比赛是这个出了好多小错误,断断续续调了3个多小时,也因为以前一直用dev的单步调试,输入输出调试不熟练。*/

 


以上是关于Gym 101667F Philosopher's Walk的主要内容,如果未能解决你的问题,请参考以下文章

upc 9315 Philosopher’s Walk

Philosopher’s Walk(递归)

Dining-Philosopher's Monitor 解决方案:`pickup(i)` 是不是需要间接调用`self[i].signal()`?

Philosopher(set 线段树合并)

erlang和餐饮哲学家的并发[重复]

Gym101522A Gym101522C Gym101522D