第一次为了一道编程题,花了快一天。而且还是一道很简单的题,带给我的收货是巨大的。
首先是题目描述
(5分)
题目内容:
一个多项式可以表达为x的各次幂与系数乘积的和,比如:
现在,你的程序要读入两个多项式,然后输出这两个多项式的和,也就是把对应的幂上的系数相加然后输出。
程序要处理的幂最大为100。
输入格式:
总共要输入两个多项式,每个多项式的输入格式如下:
每行输入两个数字,第一个表示幂次,第二个表示该幂次的系数,所有的系数都是整数。第一行一定是最高幂,最后一行一定是0次幂。
注意第一行和最后一行之间不一定按照幂次降低顺序排列;如果某个幂次的系数为0,就不出现在输入数据中了;0次幂的系数为0时还是会出现在输入数据中。
输出格式:
从最高幂开始依次降到0幂,如:
- 2x6+3x5+12x3-6x+20
注意其中的x是小写字母x,而且所有的符号之间都没有空格,如果某个幂的系数为0则不需要有那项。
输入样例:
6 2
5 3
3 12
1 6
0 20
6 2
5 3
2 12
1 6
0 20
输出样例:
4x6+6x5+12x3+12x2+12x+40
时间限制:500ms内存限制:32000kb
一开始我的想法,是从最终结果出发,一项一项考虑。但是这个想法即使输入正确,也是只能通过2个用例。从11点半熬到2点半,还是没能解决。
import java.util.Scanner;
//记录自己写的
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
int a=in.nextInt();
int[] powers=new int[a+1];
int max=a;//最高次幂
int Zero=0;//记录第几次录入0
int b=in.nextInt();
do {
if(a==0) {
//第一个0正常循环
if(Zero==0)
{
Zero++;
}
//第二个0算完滚蛋。
else if(Zero==1) {
powers[a]+=b;
break;
}
}//输入系数是否为0
powers[a]+=b;//系数运算
a=in.nextInt();
b=in.nextInt();
}while(Zero!=2);
//下面开始输出多项式
int cnt=powers.length-1;//从最高次幂开始输出
int isFirst=1;//判断是否首次输出
//输出所有2次及以上的次数
while(cnt>1){
if(max<=1) {
break;
}//如果最高次小于等于一次,直接跳出循环
if(powers[cnt]==0) {
cnt--;
continue;
}//系数为0不输出
if(isFirst==1) {
isFirst=0;
if(powers[cnt]==1)
System.out.print("x"+cnt);
else
System.out.print(powers[cnt]+"x"+cnt);
cnt--;
continue;
}//第一项不输出+号
//下面是第二个及以后,要考虑正负号
if(powers[cnt]>0) {
if(powers[cnt]==1)
System.out.print("+"+"x"+cnt);
else
System.out.print("+"+powers[cnt]+"x"+cnt);
}
else {
System.out.print(powers[cnt]+"x"+cnt);//负系数要减去
}
cnt--;
}
//输出1次项
if(cnt==1) {
//如果之前都没有输出的话,那么不需要符号
if(isFirst==1) {
if(powers[cnt]!=0) {
isFirst=0;
if(powers[cnt]==1)
System.out.print("x");
else
System.out.print(powers[cnt]+"x");
}
//若一次项系数为0,则不输出
else {
;
}
}
//不是第一次输出时就要注意符号
else {
if(powers[cnt]>0) {
if(powers[cnt]==1)
System.out.print("x");
else
System.out.print("+"+powers[cnt]+"x");
}else if(powers[cnt]<0) {
System.out.print("-"+Math.abs(powers[cnt])+"x");//负系数要减去
}else {
;
}
}
cnt--;
}
if(cnt==0) {
//如果之前都没有输出的话,那么不需要符号
if(isFirst==1) {
System.out.print(powers[cnt]);//直接输出这个数
}
//常数项不是第一项的时候
else {
if(powers[cnt]>0) {
System.out.print("+"+powers[cnt]);
}else if(powers[cnt]<0) {
System.out.print("-"+Math.abs(powers[cnt]));//负系数要减去
}
}
}
}
}
问了同学,才知道没有考虑系数为1的情况。当情况是一团乱麻的时候怎么办?全部点着重新写呗。于是我删掉了所有的输出代码,重写了输出逻辑。
import java.util.Scanner;
//记录自己写的
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
int a=in.nextInt();
int[] powers=new int[a+1];
int max=a;//最高次幂
int b;
int zero=0;
while(a>=0&&a<=100) {
if(a==0) {
//第一个0,只需要记录一下
if(zero==0) {
zero++;
}else {
//第二个0,记录完b然后就退出输入
b=in.nextInt();
powers[a]+=b;
break;
}
}
b=in.nextInt();
powers[a]+=b;//系数运算
a=in.nextInt();
}
//下面开始准备输出
boolean isFirst=true;//是否是第一个输出,有关于符号
//i是阶数
for(int i=max;i>=0;i--)
{
//如果最高次幂是0,那么直接输出常数项然后跳出循环
if(max==0) {
System.out.println(powers[0]);
break;
}
//0系数项不需要输出,直接下一次循环
if(powers[i]==0) {
continue;
}
//关于正负号的讨论
//非0系数项,第一次输出时不用考虑符号
if(isFirst) {
isFirst=false;
}
//不为第一次输出
else if(powers[i]>0) {
//正系数要有加号
System.out.print("+");
}
//关于系数的讨论
//非1的系数需要输出
if(powers[i]!=1) {
System.out.print(powers[i]);
}
//关于X的讨论
//非0阶需要输出
if(i!=0) {
System.out.print("x");
}
//关于阶数的讨论
//大于等于2阶要输出次数
if(i>=2) {
System.out.print(i);
}
}
}
}
这一次的想法,是从通项出发。
这道题的通项,是±AxN,所以只需要讨论4部分即可。
对于符号,要考虑写不写,写+还是-;对于系数,要考虑不写1;对于x,0次的不写;对于N,N=1和0不写。
这道题带给我的启发就2点。
第一,一团乱麻,那就全部烧掉再来。
第二,思考方式的转变。编程是一门巧活,暴力想法虽然省脑子,但是在未来很难通用。