要求按照如下格式循环转圈打印数字:
1 2 3 4 514 15 16 17 613 20 19 18 712 11 10 9 8
受Jon Bentley(Programming Pearls的作者)的教诲,我对题目进行了重新的清晰定义:
输入:输入要打印矩阵的行(width)和列(high),起始值(矩阵左上角的的元素值)initvalue
输出:符合要求的转圈打印数字的矩阵
分析,在程序中我们只能按照行扫描打印,即打印函数主体是个双重循环
for(i = 0; i < high; ++i) { for(j = 0; j < width; ++j) cout << point(i, j) << ' '; }
所以现在问题的关键转化为如何根据程序输入的起始值(initvalue),矩阵宽度(width)
,矩阵高度(high)来确定point(i,j)的值。
观察上面的矩阵,我们不难发现,对于该矩阵的最外层外壳,次外层内壳,........,它们的区别
仅是起始值和宽度和高度的不同,其生成逻辑完全一致,这就要我想到了递归,对了,就是递归
下面是我对该point(x,y)函数的实现:
int point(int x, int y, int lt, int width,int high) { if(x == 0) return lt+y; else if(x == high-1) return lt+width*2+high*1-3-y; else if(y == width-1) return lt+width-1+x; else if(y == 0) return lt+(width + high)*2-4-x; else return point(x-1, y-1, lt+(width +high-2)*2, width-2,high-2); }
ok,下面附上整个程序和运行测试结果:
#include <iostream> #include <iomanip> using namespace std; int point(int x, int y, int lt, int width,int high) { if(x == 0) return lt+y; else if(x == high-1) return lt+width*2+high*1-3-y; else if(y == width-1) return lt+width-1+x; else if(y == 0) return lt+(width + high)*2-4-x; else return point(x-1, y-1, lt+(width +high-2)*2, width-2,high-2); } int main() { int initvalue, i, j,width,high; cin >> high>>width>>initvalue; for(i = 0; i < high; ++i) { for(j = 0; j < width; ++j) cout << setw(4) << point(i, j, initvalue, width,high) << ' '; cout.put('/n'); } return 0; }
请将文件保存为RotatingPrintNums.cc
[jim@ts850 algoriths]$ g++ -o RotatingPrintNums RotatingPrintNums.cc
[jim@ts850 algoriths]$ ./RotatingPrintNums 5 6 1 1 2 3 4 5 6 18 19 20 21 22 7 17 28 29 30 23 8 16 27 26 25 24 9 15 14 13 12 11 10 [jim@ts850 algoriths]$
2011-04-15