这种方式比较好理解
原数组:
0 1 2 3 4 5
6 7 8 9 10 11
12 13 14 15 16 17
18 19 20 21 22 23
期待输出的数组:
0 1 6 12 7 2 3 8 13 18 19 14 9 4 5 10 15 20 21 16 11 17 22 23
状态机的转换主要用于处理下一步的走法,这一个题目的复杂点只能是逐步走,不能上来就确定8位置是怎么走,没有动态规划的特征。只能是硬解:
比如0是起点:下一步向右,nextState=Right, column++;
到1点 nextState = leftdown, 左下方向,row++,column--;
到6点newState = down, column=0, 无法--,只能向下走,column不变,row++;
。。。
到12点,向右上。。
按照这个规率找到各个状态机之间的切换原理,就可以解决这个题目,
状态机切换用 if (state)...else if (....).或者switch(state)....case.....
#include <vector>
#include <iostream>
#include <string>
#define M 4
#define N 6
enum EState
{
RIGHT,
RIGHTUP,
LEFTDOWN,
DOWN,
NONE
};
std::string GetState(EState state) {
switch (state)
{
case EState::RIGHT:
return "right";
case EState::RIGHTUP:
return "rightup";
case EState::LEFTDOWN:
return "leftdown";
case EState::DOWN:
return "down";
default:
break;
}
return "none";
}
int main(int argc, char const *argv[])
{
std::vector<std::vector<int>> arr;
int val = 0;
for (int i = 0; i < M; i++) {
std::vector<int> tmp;
for (int j = 0; j < N; j++) {
tmp.emplace_back(val++);
}
arr.emplace_back(tmp);
}
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
printf("%3d ", arr[i][j]);
}
printf("\n");
}
printf("=====================\n");
int row = 0, col = 0; // row, col
EState nextState = EState::NONE;
int idx = 0;
int target[M][N];
target[0][0] = arr[0][0];
while (idx < M * N) {
// target[row][col] = arr[row][col];
// printf(">>>>>>%3d %s\n", arr[row][col], GetState(nextState).c_str());
printf("%3d ", arr[row][col]);
if (row == 0 && col == 0) {
col++;
nextState = EState::RIGHT;
idx++;
continue;
}
switch (nextState)
{
case EState::RIGHT:
if (row == 0) { // left edge
row++;
col--;
nextState = EState::LEFTDOWN;
} else { // right up
row--;
col++;
nextState = EState::RIGHTUP;
}
break;
case EState::RIGHTUP:
if (row == 0) {
if (col == N - 1) {
row ++;
nextState = EState::DOWN;
} else {
col++;
nextState = EState::RIGHT;
}
} else {
if (col == N - 1) {
row ++;
nextState = EState::DOWN;
} else {
row--;
col ++;
nextState = EState::RIGHTUP;
}
}
break;
case EState::LEFTDOWN:
if (col == 0) {
if (row == M - 1) {
col++;
nextState = EState::RIGHT;
} else {
row++;
nextState = EState::DOWN;
}
} else {
if (row == M -1) {
col++;
nextState = EState::RIGHT;
} else {
col--;
row++;
nextState = EState::LEFTDOWN;
}
}
break;
case EState::DOWN:
if (row == M - 1) {
if (col == 0) {
row --;
col ++;
nextState = EState::RIGHTUP;
} else {
col ++;
nextState = EState::RIGHT;
}
} else {
if (col == N - 1) {
row++;
col--;
nextState = EState::LEFTDOWN;
} else {
row --;
col ++;
nextState = EState::RIGHTUP;
}
}
break;
default:
break;
}
idx++;
}
printf("\n");
return 0;
}