robot moving on the surface of a square

題目java

機器人在形狀爲green house立方體的5個表面移動進行打掃,初始位置爲表面1上的某個給定位置,輸入一串由123組成的連續指令(1:向前移動1個單位;2:右轉方向;3:左轉方向)操做機器人,判斷最後機器人所處表面(1/2/3/4/5)。ios

細節數組

1) 當移動到當前表面邊界時執行前移操做(op=1)時會這樣移動到對應毗鄰的表面:函數

   好難畫啊口區spa

 

2) 機器人位於表面一、二、三、4的底層邊緣時試圖往下移動的操做將會失敗,位置不變。3d

i.e.指針

輸入:N(int,立方體棱長)、location_r(int,初始位置豎直座標)、loation_c(int,初始位置水平座標)、 ops(int[200],由1/2/3組成的指令串);code

輸出:執行完全部指令後機器人所在的表面編號。對象

 

例子:N=4,初始位置爲3,2(注意題目的輸入以1爲起點),輸入長度25的指令1, 1, 1, 2, 1, 1, 1, 2, 2, 1, 3, 1, 1, 3, 1, 2, 1, 1, 1, 1, 1, 1, 3, 1, 1。blog

 軌跡:

 

好醜啊救命

思路

[1] 把立方體表面展開並設定絕對方向;

絕對方向: 展開後的二維空間上的方向,只有上下左右4個。counterpart應該不能叫相對方向吧,反正是三維空間中根據當前所在具體平面+平面上的方向所肯定的∈R3的向量吧阿不要緊啦反正這個跟解題應該沒什麼關係

e.g. N=4,展開立方體並以表面1方向爲基準,每一個表面以左上角爲座標原點。//也能夠按別的方式展開 看我的偏好

 

[2] 用4個int變量grid, location_r, location_c, direction追蹤機器人每執行完一個指令後的狀態。

        grid:  機器人當前所在表面編號

        location_r: 機器人當前所在行座標 //我我的是以0爲起始的

        location_c: 機器人當前所在列座標

        direction: 機器人當前朝向 //這裏關聯前面提到的絕對方向

[3] 指令處理:可分爲 向前移動機器人 和 轉動方向

[3-1]  轉動方向

當op爲2或3的時候相應的順時針/逆時針改變方向 e.g. 當前方向爲up時,收到指令3,逆時針轉動90度因此方向更新爲left。

實現的時候能夠考慮用4個整形常量0 1 2 3標記上下左右 或者逆時針 上左下右 或者順時針 上右下左 隨便啦反正後面不要忽然弄混就是了 但我以爲這樣作可讀性不是很強,我我的偏向用枚舉enum directions{up, left, down, right}雖然考試系統的編譯器比較垃圾不認識enum因此我最後又只能默默改回用整數罷了

[3-2] 向前移動機器人

只要看當前的絕對方向是什麼再對座標作相應的更新(先無論可能會遇到座標越界須要更換所在表面的問題),e.g.direction爲up時座標r軸+=-1 c軸+=0

實現建議 上若是先前是用簡單的連續整數標記4個方向好比0/1/2/3分別表示up/left/down/right那麼能夠用一個4*2的二維數組存儲座標更新的可能delta值:deltas[4][2]={{0, -1}, {-1, 0}, {1, 0}, {0, 1}},這樣就能夠直接用方向值做爲下表獲取座標更新的delta值直接遞增在原座標上計算

固然若是題目想要再複雜一點可能一次不是隻移動一格那麼deltas裏的值也能夠改不過我也不想考慮這麼無聊的狀況了hehe

e.g.

enum directions {up, left, down, right};
int deltas[4][2]={{0, -1}, {-1, 0}, {1, 0}, {0, 1}};
//operates, change direction or move or whatever
...
//get an op==1 indicates that you need to move forward
location_r+=deltas[direction][0];
location_c+=deltas[direction][1];

  若是更新後的座標值是合法的 i.e. 在0和N-1之間 (固然若是是從1起始就是在1和N之間啊我爲何要打這些廢話)那就完了

 若是更新後的座標值不合法說明它可能要移動到另外一個平面 或者 試圖移動到最底下那個不能到達的平面但沒有成功,那就要對座標值進行再次更新使它合法,有時候方向也要根據狀況進行更新。

[3-2-2] 合法化非法座標 //聽起來爲何這麼詭異

根據以前的展開圖找規律進行相應變動

 

 

 

 e.g. 當在表面5時location_c<0時,說明機器人實際上已經移動到表面4的上側,對應的規律就是r變爲0【由於反正題目中只移動一步因此肯定是在表面4的第一行】而c變爲本來的r值。direction也會從原來的left變爲down。 其餘狀況以此類推。

當在與底面毗鄰的表面1/2/3/4試圖往底面移動時(e.g. grid==2, location_r<0)時會失敗,把當前非法的座標值更新爲邊界值,方向不變。

 

[4] 最後返回當前記錄的grid值

 

關於grid location和directon的追蹤

實現所有在main裏寫也是沒問題,可是我比較喜歡分紅幾個函數來寫。這樣的話爲了保證函數中作的變動能更新到main裏的表面/座標/方向的變量值就須要把它們按引用傳遞而不是按值傳遞, C/C++能夠把參數設爲引用或者指針,java的話好像基本數據類型參數是默認按值傳遞的,但好像也有個什麼途徑能夠把它們封裝成對象就能按引用傳遞了。

若是大家直接把它們用做返回值當我沒說

用全局變量也能夠啦但我不是很喜歡

 

整體

int grid = 1, location_r, location_c, direction;

void robot_move(int& location_r, int& location_c, int& direction);
bool locationInvalid(const int location_r, const int location_c, const int N);
void robot_rectify(int& grid, int& location_r, int& location_c, int& direction, const int N);
void changeDirection(int& direction, const int op);

//依此執行輸入指令
for (int op : ops) {
    switch (op) {
        case 1: //move forward
            robot_move(location_r, location_c, direction); //update location
            if (locationInvalid(location_r, location_c, N))
                robot_rectify(grid, location_r, location_c, direction, N); //rectify the illegal location values and udpate direction perhaps
            break;
        case 2:
        case 3:
            changeDirection(direction, op);
            break;
    }
}

 

 

 完整代碼:

#include <iostream>
using namespace std;

enum directions { up, left, down, right };
int deltas[4][2] = { { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 } };


void robot_move(int& location_r, int& location_c, int& direction) {
    //increment locations with specific delta according to the current direction
    location_r += deltas[direction][0];
    location_c += deltas[direction][1];
}

bool locationInvalid(const int location_r, const int location_c, const int N) {
    return location_r < 0|| location_r >= N || location_c < 0 || location_c >= N;
}

void robot_rectify(int& grid, int& location_r, int& location_c, int& direction, const int N) {
    switch (grid) {
        case 1:
            if (location_r < 0) {
                grid = 5;
                location_r = N - 1;
            }
            else if (location_r >= N) {
                location_r = N - 1;
            }
            else if (location_c < 0) {
                grid = 4;
                location_c = N - 1;
            }
            else if (location_c >= N) {
                grid = 3;
                location_c = 0;
            }
            break;
        case 2:
            if (location_r < 0) {
                location_r = 0;
            }
            else if (location_r >= N) {
                grid = 5;
                location_r = 0;
            }
            else if (location_c < 0) {
                grid = 4;
                direction = directions::right;
                location_r = N - 1 - location_r;
                location_c = 0;
            }
            else if (location_c >= N) {
                grid = 3;
                direction = directions::left;
                location_r = N - 1 - location_r;
                location_c = N - 1;
            }
            break;
        case 3:
            if (location_r < 0) {
                grid = 5;
                direction = directions::left;
                location_r = N-1-location_c;
                location_c = N - 1;
            }
            else if (location_r >= N) {
                location_r = N - 1;
            }
            else if (location_c < 0) {
                grid = 1;
                location_c = N - 1;
            }
            else if (location_c >= N) {
                grid = 2;
                direction = directions::right;
                location_r = N - 1 - location_r;
                location_c = N - 1;
            }
            break;
        case 4:
            if (location_r < 0) {
                grid = 5;
                direction = directions::right;
                location_r = location_c;
                location_c = 0;
            }
            else if (location_r >= N) {
                location_r = N - 1;
            }
            else if (location_c < 0) {
                grid = 2;
                direction = directions::right;
                location_r = N - 1 - location_r;
                location_c = 0;
            }
            else if (location_c >= N) {
                grid = 1;
                location_c = 0;
            }
            break;
        case 5:
            if (location_r < 0) {
                grid = 2;
                location_r = N - 1;
            }
            else if (location_r >= N) {
                grid = 1;
                location_r = 0;
            }
            else if (location_c < 0) {
                grid = 4;
                direction = directions::down;
                location_c = location_r;
                location_r = 0;
            }
            else if (location_c >= N) {
                grid = 3;
                direction = directions::down;
                location_c = N-1-location_r;
                location_r = 0;
            }
            break;
    }

}
void changeDirection(int& direction, const int op) {
    switch (op) {
        case 2://turn right
            if (direction == directions::up)
                direction = directions::right;
            else
                --direction;
            break;
        case 3://turn left
            if (direction == directions::right)
                ++direction;
            else
                ++direction;
            break;
    }
}

int main() {
    //input & initialization
    
    int N, grid, location_r, location_c, direction, k, ops[200];
    cin >> N >> location_r >> location_c >> k;
    --location_r;
    --location_c;
    for (int i = 0; i < k; i++)
    cin >> ops[i];
    /* test case
    int N = 4, grid, location_r = 2, location_c = 1, direction, k = 25;
    int ops[200] = { 1, 1, 1, 2, 1, 1, 1, 2, 2, 1, 3, 1, 1, 3, 1, 2, 1, 1, 1, 1, 1, 1, 3, 1, 1 };
    */
    grid = 1;
    direction = directions::up;
    //依次執行輸入指令
    for (int i = 0; i < k; i++) {
        switch (ops[i]) {
        case 1: //move forward
            robot_move(location_r, location_c, direction); //update location
            if (locationInvalid(location_r, location_c, N))
                robot_rectify(grid, location_r, location_c, direction, N); //rectify the illegal location values and udpate direction perhaps
            break;
        case 2:
        case 3:
            changeDirection(direction, ops[i]);
            break;
        }
    }
    cout << grid << endl;
    return 0;
}
相關文章
相關標籤/搜索