题意: 题目意思就是将两个不同规则的字符数组进行相互转换。
思路: 将题目的解答分成两部分,第一部分是将 figure 1 的数组转换成一维数组,第二部分是将一维数组中的字符填入 figure 2 的数组中。
针对第一部分,将 figure 1 的二维数组旋转四十五度再观察,能够发现奇数行是从左往右,偶数行是从右往左;上半部分中,每行边上的结点移动是右、下不断更替,下半部分中,每行边上的结点移动是下、右不断更替。
对于第二部分,通过对当前位置的判断进行移动,直到填满为止。
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<stack>
#include<queue>
#include<utility>
#include<vector>
#include<cmath>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
#include<sstream>
using namespace std;
typedef long long LL;
int N;
char G[110][110];
char ch[10010];
char ans[110][110];
int main()
{
//freopen("in.txt", "r", stdin);
while(scanf("%d", &N) == 1){
for(int i=1; i<=N; i++){
scanf("%s", &G[i][1]);
}
int x=1, y=1;
int tot = 0;
bool right = true;
bool bhalf = true;
for(int i=1; i<=2*N-1; i++){
if(i == N) bhalf = false;
ch[tot++] = G[x][y];
for(int j=1; j<min(i, 2*N-i); j++){
if(i & 1){
x--; y++;
}
else{
x++; y--;
}
ch[tot++] = G[x][y];
}
if(right){
if(bhalf) y++;
else x++;
}
else{
if(bhalf) x++;
else y++;
}
right = !right;
}
ch[tot] = '\0';
//printf("%s\n", ch);
memset(ans, 0, sizeof(ans));
x = 1, y = 1;
tot = 0;
int mov = 0; //0 表示向右,1 表示向下,2 表示向左,3 表示向上
while(true){
ans[x][y] = ch[tot++];
if(tot == N*N) break;
if(x==1&&y==N || isupper(ans[x-1][y])&&!isupper(ans[x+1][y])&&isupper(ans[x][y-1])&&isupper(ans[x][y+1])) mov = 1;
else if(x==N&&y==N || isupper(ans[x-1][y])&&isupper(ans[x+1][y])&&!isupper(ans[x][y-1])&&isupper(ans[x][y+1])) mov = 2;
else if(x==N&&y==1 || !isupper(ans[x-1][y])&&isupper(ans[x+1][y])&&isupper(ans[x][y-1])&&isupper(ans[x][y+1])) mov = 3;
else if(y==1&&isupper(ans[x-1][y]) || isupper(ans[x-1][y])&&isupper(ans[x+1][y])&&isupper(ans[x][y-1])&&!isupper(ans[x][y+1])) mov = 0;
if(mov == 0) y++;
else if(mov == 1) x++;
else if(mov == 2) y--;
else if(mov == 3) x--;
}
for(int i=1; i<=N; i++){
for(int j=1; j<=N; j++){
putchar(ans[i][j]);
}
putchar('\n');
}
}
return 0;
}