循环输入N的值,N为方阵的边长。
打印一个N*N的方阵,N为方阵边字符的个数(3<N<=22),定义最外层为“O”,第二层为“J”,从第三层起每层打印数字1,2,3….
打印出边长为N的方阵,多个方阵用换行符隔开。
例子:
解决该问题的主要关键点就是根据方阵的下标(行标或者列标,标号从1到n)判断某个元素属于方阵的第几层,然后按照要求打印字符即可,由观察下标规律和方阵对称性,从左下到右上画一条对角线(n,1)-(1,n)。这里用h和l分别代表行标、列标,c代表方阵的第几层(层次从外向内依次为1,2,3,4...),由下标确定元素位于第几层的关键代码为c = h <= l ? h : l,但这种确定方法只能判断所画对角线以上的元素的层数,因此我们需要对对角线以下元素进行关于对角线对称的翻折,翻折后元素所在层数并没有发生变化。判断元素在对角线以下的关键条件为h + l > n + 1;根据层数输出对应字符即可。实现代码如下:
#include<iostream>
using namespace std;
void print(int n,int h, int l){
int c;
if (h + l > n + 1) {
c = h + l - n - 1;
h -= c;
l -= c;
}//在对角线下方的元素翻折
c = h <= l ? h : l;//根据下标确定层数(只能判断对角线上方的 因此需要翻折操作)
if (c == 1)cout << "O";
else if (c == 2)cout << "J";
else cout << c - 2;
return;
}
int main() {
int n;
while (cin >> n) {
for (int h = 1; h <= n; ++h) {
for (int l = 1; l <= n; ++l) {
print(n, h, l);
}
cout << endl;//每行后加换行
}
}
return 0;
}
测试结果如下:
也有不翻折的操作,代码如下:
#include<iostream>
using namespace std;
void print(int n, int h, int l) {
int c;
if (h + l > n + 1)c = n + 1 - (h >= l ? h : l);
else c = h <= l ? h : l;
if (c == 1)cout << "O";
else if (c == 2)cout << "J";
else cout << c - 2;
return;
}
int main() {
int n;
while (cin >> n) {
for (int h = 1; h <= n; ++h) {
for (int l = 1; l <= n; ++l) {
print(n, h, l);
}
cout << endl;
}
}
return 0;
}