/* 一道多项式相关的实训题 */
题面
单点时限: 2.0 sec
内存限制: 256 MB
在一个平面坐标系统中显示一个多次函数的图像。
为简化起见,设多次函数的最大次数为 3 3 3,系数最多为 2 2 2位数。函数表示为: f ( x ) = c 3 x 3 + c 2 x 2 + c 1 x + c 0 f(x)=c_3x^3+c_2x^2+c_1x+c_0 f(x)=c3x3+c2x2+c1x+c0。给出的函数是最简形式。 c i c_i ci为 1 1 1时可省略, c 3 c_3 c3为正数时可省略 + + +,次方为 1 1 1时可省略 ^1。
坐标系统的 x 轴和 y 轴范围限制在 [ − 20 , 20 ] [-20,20] [−20,20],具体格式见样例。
输入格式
不多于 20 行,每行一个最多为 3 次的函数。形式:
f
(
x
)
=
c
3
x
3
+
c
2
x
2
+
c
1
x
+
c
0
f(x)=c_3x^3+c_2x^2+c_1x+c_0
f(x)=c3x3+c2x2+c1x+c0。
输出格式
显示每个函数的图像。两个函数之间用一个空行分隔,最后一个函数之后没有空行。
样例
略
解题思路
- 把整个解题分为:多项式处理,计算,绘图。
class Solution
{
public:
void slove(char s[]);
Solution();
void read(char s[]);
void print();
private:
int ceof[4];
char dot[41][41];
};
- 处理多项式的思路和一元多项式乘法那题类似,按照元素出现顺序依次处理,将系数按照指数大小存进ceof数组。
void Solution::read(char s[])
{
int ceoft,exp;
int sign=1;
int i=5;
while(s[i])
{
ceoft=0,exp=0,sign=1;
if(s[i]=='+')
{
sign=1;
i++;
}
else if(s[i]=='-')
{
sign=-1;
i++;
}
if(s[i]=='x')
{
ceoft=1;
i++;
if(s[i]=='^')
{
i++;
while(s[i]>='0'&&s[i]<='9')
{
exp=exp*10+s[i]-'0';
i++;
}
}
else
{
exp=1;
}
ceof[exp]=sign*ceoft;
continue;
}
else if(s[i]>='0'&&s[i]<='9')
{
while(s[i]>='0'&&s[i]<='9')
{
ceoft=ceoft*10+s[i]-'0';
i++;
}
if(s[i]=='x')
{
i++;
if(s[i]=='^')
{
i++;
while(s[i]>='0'&&s[i]<='9')
{
exp=exp*10+s[i]-'0';
i++;
}
}
else
{
exp=1;
}
ceof[exp]=sign*ceoft;
continue;
}
else
{
exp=0;
ceof[exp]=sign*ceoft;
continue;
}
}
}
}
- 因为次数最高只有三次,所以可以手动乘而不需要把各项的指数分别记录下来。
void Solution::slove(char s[])
{
read(s);
for(int i=-20;i<21; i++)
{
int num=0;
num=ceof[3]*i*i*i+ceof[2]*i*i+ceof[1]*i+ceof[0];
if(num>-21 && num<21) dot[20-num][i+20]='*';
}
print();
}
- 把坐标系的初始化工作交给构造函数来做,注意一定要仔细,不然容易出错,最后计算完之后一起输出。
Solution::Solution()
{
for(int i=0; i<41; i++)//初始化坐标系
for(int j=0; j<41; j++)
{
if(i==20)
{
if(j==20) dot[i][j]='+';
else if(j==40) dot[i][j]='>';
else dot[i][j]='-';
}
else if(j==20)
{
if(i==0) dot[i][j]='^';
else if(i==20) dot[i][j]='+';
else dot[i][j]='|';
}
else dot[i][j]='.';
}
for(int i=0;i<4;i++)
ceof[i]=0;
}
void Solution::print()
{
for(int i=0; i<41; i++)
{
for(int j=0; j<41; j++)
printf("%c",dot[i][j]);
printf("\n");
}
}
- 因为题目对于最后的换行有要求,所以设置了一个check变量来检测是否到了EOF,是否要输出换行。
int main(int argc, char** argv)
{
char s[30];
int check=0;
check=scanf("%s",s);
while(check!=EOF)
{
Solution k;
k.slove(s);
check=scanf("%s",s);
if(check!=EOF) printf("\n");
else break;
}
return 0;
}
ac代码
#include<bits/stdc++.h>
using namespace std;
class Solution
{
public:
void slove(char s[]);
Solution();
void read(char s[]);
void print();
private:
int ceof[4];
char dot[41][41];
};
Solution::Solution()
{
for(int i=0; i<41; i++)//画坐标系
for(int j=0; j<41; j++)
{
if(i==20)
{
if(j==20) dot[i][j]='+';
else if(j==40) dot[i][j]='>';
else dot[i][j]='-';
}
else if(j==20)
{
if(i==0) dot[i][j]='^';
else if(i==20) dot[i][j]='+';
else dot[i][j]='|';
}
else dot[i][j]='.';
}
for(int i=0;i<4;i++)
ceof[i]=0;
}
void Solution::slove(char s[])
{
read(s);
for(int i=-20;i<21; i++)
{
int num=0;
num=ceof[3]*i*i*i+ceof[2]*i*i+ceof[1]*i+ceof[0];
if(num>-21 && num<21) dot[20-num][i+20]='*';
}
print();
}
void Solution::print()
{
for(int i=0; i<41; i++)
{
for(int j=0; j<41; j++)
printf("%c",dot[i][j]);
printf("\n");
}
}
void Solution::read(char s[])
{
int ceoft,exp;
int sign=1;
int i=5;
while(s[i])
{
ceoft=0,exp=0,sign=1;
if(s[i]=='+')
{
sign=1;
i++;
}
else if(s[i]=='-')
{
sign=-1;
i++;
}
if(s[i]=='x')
{
ceoft=1;
i++;
if(s[i]=='^')
{
i++;
while(s[i]>='0'&&s[i]<='9')
{
exp=exp*10+s[i]-'0';
i++;
}
}
else
{
exp=1;
}
ceof[exp]=sign*ceoft;
continue;
}
else if(s[i]>='0'&&s[i]<='9')
{
while(s[i]>='0'&&s[i]<='9')
{
ceoft=ceoft*10+s[i]-'0';
i++;
}
if(s[i]=='x')
{
i++;
if(s[i]=='^')
{
i++;
while(s[i]>='0'&&s[i]<='9')
{
exp=exp*10+s[i]-'0';
i++;
}
}
else
{
exp=1;
}
ceof[exp]=sign*ceoft;
continue;
}
else
{
exp=0;
ceof[exp]=sign*ceoft;
continue;
}
}
}
}
int main(int argc, char** argv)
{
char s[30];
int check=0;
check=scanf("%s",s);
while(check!=EOF)
{
Solution k;
k.slove(s);
check=scanf("%s",s);
if(check!=EOF) printf("\n");
else break;
}
return 0;
}