第一次为了一道编程题,花了快一天。而且还是一道很简单的题,带给我的收货是巨大的。

首先是题目描述


(5分)


题目内容:

一个多项式可以表达为x的各次幂与系数乘积的和,比如:


现在,你的程序要读入两个多项式,然后输出这两个多项式的和,也就是把对应的幂上的系数相加然后输出。

程序要处理的幂最大为100。

输入格式:

总共要输入两个多项式,每个多项式的输入格式如下:

每行输入两个数字,第一个表示幂次,第二个表示该幂次的系数,所有的系数都是整数。第一行一定是最高幂,最后一行一定是0次幂。

注意第一行和最后一行之间不一定按照幂次降低顺序排列;如果某个幂次的系数为0,就不出现在输入数据中了;0次幂的系数为0时还是会出现在输入数据中。

输出格式:

从最高幂开始依次降到0幂,如:



  1. 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点。


第一,一团乱麻,那就全部烧掉再来。


第二,思考方式的转变。编程是一门巧活,暴力想法虽然省脑子,但是在未来很难通用。