浅谈AC中的抽象思维-P1067多项式输出

题目链接:https://www.luogu.com.cn/problem/P1067

显然这道题是一道水题.但往往水题的解法可以看出解题人的水平.

在讨论之前,我们先看看此题的两种AC代码:

代码一:

#include<bits/stdc++.h>
using namespace std;	
int main()
{
	string str="";
	int n,m;
	cin>>n;
	m=n;
	string a[n+1];
	
	for(int i=0;i<m+1;i++)
	cin>>a[i];
		
	for(int j=0;j<m+1;j++){
		stringstream ss;
		ss<<n;
		string sn=ss.str();
		//首位!=0 
		if(j==0){//判断是否首位,进行首位下的逻辑 
			if(n!=0){
				if(a[j]=="1") {//首位是否为1
					if(sn!="1") str=str+"x^"+sn; //指数是否为1 
					else        str=str+"x";
				} 
				else if(a[j]=="-1"){
					 if(sn!="1") str=str+"-"+"x^"+sn;
					 else        str=str+"-"+"x";
					 } 
				else{   
					if(sn!="1")  str=str+a[j]+"x^"+sn;
					else         str=str+a[j]+"x";
					} 
			}		
			else{
				if(a[j]=="1") {
					if(sn!="1")   str=str+"x^"+sn;
					else          str=str+"x";
					}
				else if(a[j]=="-1"){
					if(sn!="1")   str=str+"-"+"x^"+sn;
					else          str=str+"-"+"x";
				} 
				else              str=str+a[j];
			}
			
		}
		else if(a[j]=="0")
			str+="";
		else if(a[j]!="1"&&a[j]!="-1"){
			if(a[j][0]!='-'){
				if(n!=0){
					if(sn!="1") str=str+"+"+a[j]+"x^"+sn;
					else        str=str+"+"+a[j]+"x"; 
				} 
				else   str=str+"+"+a[j];
			}
			else{
				if(n!=0) {
					if(sn!="1") str=str+a[j]+"x^"+sn;
					else 		str=str+a[j]+"x";
					} 
				else     		str=str+a[j];
			} 
		}		
		else{ //if(a[j]=="1"&&a[j]=="-1"){
			if(a[j][0]!='-'){
				if(n!=0){
					if(sn!="1")	str=str+"+"+"x^"+sn;
					else        str=str+"+"+"x";
				} 
				else 	 str=str+"+"+a[j];
			} 
			else{
				if(n!=0) {
					if(sn!="1") str=str+"-"+"x^"+sn;
					else        str=str+"-"+"x";
				}
				else     str=str+a[j];
			} 
		}
		n--;
	}
	cout<<str;
	return 0;
}

代码二:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,a;
    cin>>n;
    for(int i=n;i>=0;i--){
        cin>>a;
        if(a){    判0系数
            if(i!=n&&a>0)cout<<"+";    根据正负、是否为最高此项决定加号
            if(abs(a)>1||i==0)cout<<a;    输出系数(系数不为正负1或指数为0)
            if(a==-1&&i)cout<<"-";    -1系数特判,常数项已特判
            if(i>1)cout<<"x^"<<i;    二次及以上输出指数
            if(i==1)cout<<"x";    一次项
        }
    }
}

简单的一看,我们大致就能看出高低了.

那么,为什么差别这么大呢?

其实就是解题者抽象思维差异.

在拿到一道题的时候,首先应该冷静的分析,用数学思维抽象出他的具体逻辑.越简单越好,最好是把他变为一个公式或者数学书中的定义概念一样.而不是着急着去写代码,那样写出来的代码即便能够AC,我想也是经过编译器不断的调试,然后对逻辑的不断补充和优化.最终得到的是一个打满补丁的程序,甚至最终遗憾离场.而不是一个从一开始就是思维逻辑的产物,可以经得住无数测试示例的狂轰乱炸.

那么,应该怎么办呢?

以此题为例:拿到题之后,三分钟时间不要去敲代码.

首先,去思考分析题意.

大致看一遍题之后,就能明白题意,根据输入的各种参数,输出一个一元n次多项式.(输出格式和数学表达式书写习惯一样).

一个多项式包含什么呢?无外乎三个,系数,元,指数.而此题有明确告诉是一元,所以就是x,且指数>0,系数!=0

知道了结构(也就是单项式)之后,应该在注意这三个东西组合成一个多项式的时候应该注意什么.也就是中间的符号衔接问题.

明显,如果是系数为负,则不用添加.若为正,因为人类的书写习惯正号省略,所以要填上正号+.

假设系数是a,指数是b.那么"一般"就是像aX^b这样的单项式通过正负号链接的组合

接着继续拆分,一项一项分析系数项和元和指数.

所以思维是:多项式--->单项式--->系数项和元和指数.

如果a=0,单项式为空.

如果a=正负1,则不用输出系数,但需考虑正负号

如果b=0,为常数项,只需输出系数

如果b=1,为一次项,只需输出元X

如果不是首项,且a>0.要填上+,最后一项(指数为0)只用输出系数a,中间项需要根据系数正负来判定加不加+.是正数就加.

如果系数的绝对值大于1,系数也要输出a

现在就可以写代码了.只需要把思维过程用代码表现出来.

cin>>n;n代表了这个多项式中单项式的个数,他又和指数有关

for(int i=n;i>=0;i--){  指数从5开始到0结束,此处的i即为上面分析的b
        cin>>a; 输入系数
        if(a){    判0系数,是0不输入
            if(i!=n&&a>0)cout<<"+";       不是首项,即中间项,则根据正负为此项决定加不加+号
            if(abs(a)>1||i==0)cout<<a;    输出系数(系数不为正负1或指数为0)
            if(a==-1&&i)cout<<"-";           -1系数特判且不为常数项(即指数不为0)
            if(i>1)cout<<"x^"<<i;              二次及以上输出指数
            if(i==1)cout<<"x";                   一次项
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值