Gym 101667F Philosopher's Walk(分治)

Gym 101667F Philosopher's Walk

Description

In Programming Land, there are several pathways called Philosopher’s Walks for philosophers to have a rest. A Philosopher’s Walk is a pathway in a squareshaped region with plenty of woods. The woods are helpful for philosophers to
think, but they planted so densely like a maze that they lost their ways in the maze of woods of a Philosopher’s Walk.
Fortunately, the structures of all Philosopher’s Walks are similar; the structure of a Philosopher’s Walk is designed and constructed according to the same rule in a 2௞ meter square. The rule for designing the pathway is to take a right-turn in 90 degrees after every 1-meter step when ݇ is 1, and the bigger one for which the integer ݇ is greater than 1 is built up using four sub-pathways with ݇െ1 in a fractal style. Figure F.1 shows
three Philosopher’s Walks for which ݇ is 1, 2, and 3. The Philosopher’s Walk ܹଶ consists of four ܹଵ structures with the lower-left and the lower-right ones are 90 degree rotated clockwise and counter-clockwise, respectively; the upper ones have the same structure with ܹଵ. The same is true for any ܹ௞ for which the integer ݇ is greater than 1. This rule has been devised by a mathematical philosopher David Hilbert (1862 – 1943), and the resulting pathway is usually called a HILBERT CURVE named after him. He once talked about a space filling method using this kind of curve to fill up a square with 2௞ sides, and every Philosophers’ Walk is designed according to this method.

Tae-Cheon is in charge of the rescue of the philosophers lost in Philosopher’s Walks using a hot air balloon.Fortunately, every lost philosopher can report Tae-Cheon the number of meter steps he has taken, and TaeCheon knows the length of a side of the square of the Philosopher’s Walk. He has to identify the location of the lost philosopher, the (ݔ ,ݕ (coordinates assuming that the Philosopher’s Walk is placed in the 1st quadrant of a Cartesian plain with one meter unit length. Assume that the coordinate of the lower-left corner block is (1, 1). The entrance of a Philosopher’s Walk is always at (1, 1) and the exit is always (݊, 1) where ݊ is the length of a side. Also assume that the philosopher have walked one meter step when he is in the entrance, and that he always go forward to the exit without back steps.
For example, if the number of meter-steps taken by a lost philosopher in the Philosopher’s Walk in ܹଶ in Figure F.1(b) is 10, your program should report (3, 4).
Your mission is to write a program to help Tae-Cheon by making a program reporting the location of the lost philosopher given the number of meter-steps he has taken and the length of a side of the square of the Philosopher’s Walk. Hurry! A philosopher urgently needs your help.

Input

Your program is to read from standard input. The input consists of a single line containing two positive integers, ݊ and ݉, representing the length of a side of the square of the Philosopher’s Walk and the number of meter-steps taken by the lost philosopher, respectively, where ݊ൌ2௞ and ݉൑2ଶ௞ for an integer ݇ satisfying 0 ൏ ݇ ൑ 15.

Output

Your program is to write to standard output. The single output line should contain two integers, ݔ and ݕ ,
separated by a space, where (ݔ ,ݕ (is the location of the lost philosopher in the given Philosopher’s Walk.

Sample Input 1

4 10

Output for the Sample Input 1

3 4

Sample Input 2

8 19

Output for the Sample Input 2

2 6

题解

题意

题目中定义了一种巡游路径,第一个值给出块数大小,第二个值给出第几块。问其位置

思路

分治法的经典例子,划分成4块。每次缩减一半,dfs到所在的位置。通过操作将其与最终递归重点建立联系。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 0x3f3f3f3f;
int T;

struct Point{
	int x,y;
};

Point dfs(int n, int m){
    Point tmp;
    if(n == 2){
        if(m == 0){
            tmp.x = 1;
            tmp.y = 1;
        }else if(m == 1){
            tmp.x = 1;
            tmp.y = 2;
        }else if(m == 2){
            tmp.x = 2;
            tmp.y = 2;
        }else if(m == 3){
            tmp.x = 2;
            tmp.y = 1;
        }
        return tmp;
    }
    int tn = m/(n*n/4);
    int mod = m%(n*n/4);
    tmp = dfs(n/2, mod);
    if(tn == 0){
        swap(tmp.x, tmp.y);
        return tmp;
    }else if(tn == 1){
        tmp.y += n/2;
        return tmp;
    }else if(tn == 2){
        tmp.y += n/2;
        tmp.x += n/2;
        return tmp;
    }else if(tn == 3){
        int x = n+1-tmp.y;
        int y = n/2+1 - tmp.x;
        return (Point){x, y};
    }
}
 
int main(){
    ll n, m;
    while(~scanf("%lld %lld",&n,&m)){
        Point ans = dfs(n, --m);
        printf("%d %d\n",ans.x,ans.y);
    
    }
}

posted @ 2018-09-20 09:35  caomp  阅读(436)  评论(0)    收藏  举报