问题描述
九九乘法表是学习乘法时必须要掌握的。在不同进制数下,需要不同的乘法表。 例如,四进制下的乘法表如下所示:
1*1=1
2*1=2 2*2=10
3*1=3 3*2=12 3*3=21
请注意,乘法表中两个数相乘的顺序必须为样例中所示的顺序,不能随意交换两个乘数。
给定 P,请输出 P进制下的乘法表。
输入格式
输入一个整数 P。
输出格式
输出 P 进制下的乘法表。P 进制中大于等于 10 的数字用大写字母 A、B、C、··· 表示。
样例输入
4
样例输出
1*1=1
2*1=2 2*2=10
3*1=3 3*2=12 3*3=21
样例输入
8
样例输出
1*1=1
2*1=2 2*2=4
3*1=3 3*2=6 3*3=11
4*1=4 4*2=10 4*3=14 4*4=20
5*1=5 5*2=12 5*3=17 5*4=24 5*5=31
6*1=6 6*2=14 6*3=22 6*4=30 6*5=36 6*6=44
7*1=7 7*2=16 7*3=25 7*4=34 7*5=43 7*6=52 7*7=61
评测用例规模与约定
对于所有评测数据,2 ≤ P ≤ 36。
在解决这道题之前我们需要来读懂题。
一、题意理解
该题主要的意思是要我们打印不同进制下的乘法表,而且有一个要求就是“P 进制中大于等于 10 的数字用大写字母 A、B、C、··· 表示”。但是题目好像没说明P进制下的乘法表是P进制下的数*P进制下的数=P进制下的数,还是十进制下的数*十进制下的数=P进制下的数,或者是其他,这个我们要搞清楚,我们如果仔细看输出,而且验证一下的话,可以知道在P进制的乘法表中等号的左边的数还是十进制的,进行十进制乘法后得到等号右边的结果,题目要求的是让我们把等号右边的数变成P进制表示。
二、解题思路
在弄清楚题意后我们就可以开始解题了!
首先,要搭建好乘法表的基本框架,很简单,就是双层循环,P进制打印P-1行,第i行打印i个等式,此时要注意,需要判断等左边的数是否大于等于10,如果大于,需要用A,B,C...来代替。
其次,进制转换,这个想必大家比较熟悉,我们本题要做的工作就是把等式的结果转成P进制,十进制转P进制,使用短除法,余数从下往上排列就是所得的P进制数,这个正好对应我们所学的数据结构-栈,我们可以不断地对结果进行模P操作,将余数依次入栈,当该结果为0,退出循环。
最后,就是打印操作,我们有两个地方需要注意,第一个就是等号左边大于等于10的数要用A,B,C...来替代,第二个就是等号右边P进制数中大于等于10的数也要用A,B,C...来替代。
来看看具体代码实现。
#include <iostream>
#include <stack>
using namespace std;
//进制转换函数
void ans(int k,int jinzhi){
stack<int>s;
while(k){
s.push(k%jinzhi);
k/=jinzhi;
}
while(!s.empty()){
//对入栈的元素,出栈时进行判断,如果大于等于10,也用字母依次代替
if(s.top()>=10){
cout<<char('A'+s.top()-10);
}
else{cout<<s.top();
}
s.pop();
}
}
int main()
{ int P;
cin>>P;
for(int i=1;i<=P-1;i++){
for(int j=1;j<=i;j++){
//对等号左边大于等于10的数,将其用字母依次代替
if(i>=10&&j>=10){
cout<<char('A'+i-10)<<'*'<<char('A'+j-10)<<'=';
ans(i*j,P);
cout<<' ';
}
else if(i>=10){
cout<<char('A'+i-10)<<'*'<<j<<'=';
ans(i*j,P);
cout<<' ';
}
else if(j>=10){
cout<<i<<'*'<<j<<'=';
ans(i*j,P);
cout<<' ';
}
else{
cout<<i<<'*'<<j<<'=';
ans(i*j,P);
cout<<' ';
}
}
cout<<endl;
}
}