问题描述
利用字母可以组成一些美丽的图形,下面给出了一个例子:
ABCDEFG
BABCDEF
CBABCDE
DCBABCD
EDCBABC
这是一个5行7列的图形,请找出这个图形的规律,并输出一个n行m列的图形。
输入格式
输入一行,包含两个整数n和m,分别表示你要输出的图形的行数的列数。
输出格式
输出n行,每个m个字符,为你的图形。
样例输入
5 7
样例输出
ABCDEFG
BABCDEF
CBABCDE
DCBABCD
EDCBABC
数据规模与约定
1 <= n, m <= 26。
思路:(看最终结果跳至第三个代码块)
我们先找出输出图形的规律。如下:每一行有m个字符,一共有n行。
好的。
第一行是按字母表顺序的一列字符,共有m个,对不对?
好的。
在第二行,我们发现除了第一个字符,后面的字符依旧是按照字母表的顺序。而第一个元素是第二个元素的字母表后一位。
下面几行同理。
于是我想到了,对于每一行,从末尾开始,后面的元素等于前一个元素,这样依次赋值,得到的结果就是从第二个元素开始和前一行的前m-1个元素是一样的,相当于把前一行的m-1个元素进行了后移。然后再让第一个字母等于第二个字母的后一个字母,即可得到答案。
对吧?
好的。
于是,上代码(此代码未完全正确,完全正确的代码见代码块2或代码块3)
theInput=input()
#初始化,去尾端空格
while theInput[-1] == ' ':
theInput=theInput[:-1]
n,m=map(int,theInput.split(' ')) #n为行数,m为列数
lis=['A']
for i in range(m-1):
lis.append(chr(ord(lis[-1])+1))
for i in range(n):
print(*lis,sep='')
for j in range(m-1):
lis[-j-1]=lis[-j-2]
lis[0]=chr(ord(lis[1])+1)
思路很棒,没错对吧?
但是测试出来的分数只有80分。
为什么呢?
因为如果列数是1的话,那么最后一行代码会报错,遗憾离场。
怎么办呢?
特殊讨论呗。
专门给m==1的情况做一下分类呗。
于是代码变成了这样:
theInput=input()
#初始化,去尾端空格
while theInput[-1] == ' ':
theInput=theInput[:-1]
n,m=map(int,theInput.split(' ')) #n为行数,m为列数
lis=['A']
for i in range(m-1):
lis.append(chr(ord(lis[-1])+1))
for i in range(n):
print(*lis,sep='')
for j in range(m-1):
lis[-j-1]=lis[-j-2]
if m !=1:
lis[0]=chr(ord(lis[1])+1)
else:
lis[0] = chr(ord(lis[0]) + 1)
可以,能运行。
要评价的话就是:
不错,加五分。
但是……
很丑陋。就像是我发现我的裤子有一处破洞的地方,于是我打上了一块补丁。
接下来我们尝试另一种思路,会让我们的代码变得统一一点:
我们来看,第一行我按照顺序打出字母列。
然后,第二行,我先在第一行的基础上,在最开始的位置添加一个字母元素,然后我再倒掉这一行的最后一个元素,是不是就成了第二行的字母列构成?
很好的思路,使我的CPU运转。
OK,那我们改代码呗。
改成这样:
theInput=input()
#初始化,去尾端空格
while theInput[-1] == ' ':
theInput=theInput[:-1]
n,m=map(int,theInput.split(' ')) #n为行数,m为列数
#作字母列表
lis=['A']
#完善第一行的元素
for i in range(m-1):
lis.append(chr(ord(lis[-1])+1))
for i in range(n):
#先打印
print(*lis,sep='')
#前插一个元素
lis.insert(0,chr(ord(lis[0])+1))
#后踢一个元素
lis.pop(-1)
先insert进去,然后pop出来,成了!
满分,能运行!