Problem Specs:
WX20201120-022507.png
Solution(in C):
/**
* A rather tricky(but interesting, INDEED!) solution to the problem; the code along is
* difficult to understand(or rather, nobody's ever able to understand it) so here
* I will reveal the idea behind it(very briefly, though).
* 1) Transform the figure into the following form(to intuitively show the relationship
* between the indices of s[] & z[] here I use decimal digits instead of alphabetical
* letters):
* i = 0 0
* i = 1 1
* i = 2 2
* i = 3 3 4 5 6
* 7
* 8
* 9 A B C
* D
* E
* F
* 2) From i = 0 to R-1(R denotes the number of lines), diagonally compute z[]'s
* corresponding indices into s(the original string) and use them(the computed
* indices) to copy the corresponding characters into z[] until we reach the
* end of s. Take the example above we have the indices in this order:
* for i = 0: 0---->6---->C(end)
* for i = 1: 1---->5---->7---->B---->D(end)
* for i = 2: 2---->4---->8---->A---->E(end)
* for i = 3: 3---->9---->F(end)
* which gives us the sequence 06C1578D248AE39F(More on this computation in
* the FOOTNOTE).
* 3) DONOT be alarmed on seeing the embeded for-loop here(especially the inner
* one's constrol line has its condition as 1(forver), the entire loops body's
* guaranteed to terminate after zi reaches n-1, which means this solution
* has an O(n) running time.
* FOOTNOTE: A CLOSE OBSERVATION into the figure above will reveal the fact that
* the strides between two consecutive indices are somewhat regular:
* for those i which are multiples of R-1, the strides fix at 2*(R - 1);
* for other i's, the strides alternate between 2i and 2*(R - 1 - i).
* NOTE: The driving program main() takes the input string from one of it's
* arguments(fed from cmd line) and R from the standard input.
*/
char * convert(char * s, int numRows){
int n = strlen(s);
int R = numRows;
if (n < 3 || R < 2) return s;
char *z = (char*)malloc((n + 1) * sizeof(*z));
int *strides = (int*)malloc(R * sizeof(*strides));
strides[0] = strides[R - 1] = 2 * (R - 1);
for (int i = 1; i < R - 1; i++) { strides[i] = 2 * (R - 1 - i); }
int zi = 0;
for (int i = 0; i < R; i++) {
int strideFlag = 0;
int idx = i;
for (int j = 0; 1; j++) {
int stride = i % (R - 1) == 0 ? strides[i] : (strideFlag ? strides[i] : 2 * i);
strideFlag = strideFlag == 1 ? 0 : 1;
idx += (j == 0 ? 0 : stride);
if (idx < n) {
z[zi++] = s[idx];
} else {
break;
}
}
}
z[n] = '\0';
return z;
}
int main(int argc, char *argv[]) {
int n;
scanf("%i", &n);
printf("%s\n", convert(argv[1], n));
return 0;
}









网友评论