2021ACM河北省赛:E-求导

208 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第17天,点击查看活动详情

2021ACM河北省赛——7-5 E-求导

7-5 E-求导 (pintia.cn)

小E最近在学习求导,他给了你一个多项式,让你帮忙求出它的导数。

形式化地说,不妨假设 xi 项数的系数为 A,规定一个多项式的正确的表达方式如下:

  • 各项次数非负且递减。
  • 如果 A=0,不写出这一项,否则如果 A=1,且 i=0,不写出系数。
  • 对于 i=0 的项,表示成 A;对于 i=1 的项,表示成 Ax;对于其他项,表示成 Ax^i
  • 如果该项是负的,要在前面加上负号,否则加正号。注意,如果该项是正的且为第一项,则正号和负号都不用加。
  • 特别地,如果多项式为f(x)=0,它应该被表示成 f(x)=0

输入格式:

首先输入 f(x)= ,之后给出多项式,例如 x ^ 4−3x ^ 2−x+1,格式与题目描述中的一致。

数据保证输入的字符串长度不超过 106,输入多项式的系数和次数均不超过 105。

输出格式:

首先输出 f'(x)=,之后输出所给多项式的导数,格式与题目描述中的一致。

请注意其中 f'(x)' 在输出时应该输出英文符号。

输入样例:

f(x)=x^4-3x^2-x+1

输出样例:

f'(x)=4x^3-6x-1

问题解析

模拟题,我们一个项一个项的拆分字符串。

  1. 先将当前项的’+‘或’-‘接入答案字符串str的尾部。
  2. 然后看正负号后面的是否是数字,如果是,将它们转化成数存在num中;如果不是数字,则num=1。
  3. 再看后面的是否是’x',如果不是,说明当前项求导后会变成0,我们把之前接入到尾部的正负号删去。
  4. 如果是x,则还要看x后面是不是‘^',如果不是,说明当前项数为1,求导后当前项只剩num,我们把num接到答案字符串后面。
  5. 如果是’^‘,我们再把’^‘后面的数字转化成数存在num2中,求导之后,当前项的系数是num*num2,x的次幂变成num2-1。

要注意的是"f’(x)=0"的情况,我们可以用一个变量flag来记录求导过程中所有项的系数之和,如果flag为0,说明所有项的系数都是0,我们直接输出"f’(x)=0",反之就输出我们的答案字符串。

AC代码

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include <random>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<fstream>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>
#include<bitset>#pragma GCC optimize(2)
#pragma GCC optimize(3)#define endl '\n'
#define int ll
#define PI acos(-1)
#define INF 0x3f3f3f3f
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PII;
const int N = 4e5 + 50;
​
void solve()
{
    string s, str = "f'(x)=";
    cin >> s;
    int n = s.size(), sum = 0;
    for (int i = 5; i < n; i++)
    {
        if (s[i] == '+')
        {
            str += '+';
            i++;
        }
        else if (s[i] == '-')
        {
            str += '-';
            i++;
        }
        int num = 0, num2 = 0;
        while (i < n && s[i] >= '0' && s[i] <= '9')
        {
            num *= 10;
            num += s[i] - '0';
            i++;
        }
        if (num == 0)num = 1;
        if (i >= n || s[i] == '+' || s[i] == '-')
        {
            str.pop_back();
            if (i >= n)break;
            else i--;
            continue;
        }
        else if (s[i] == 'x')
        {
            if (i + 1 >= n || s[i + 1] != '^')
            {
                sum += num;
                str += to_string(num);
                break;
            }
            else
            {
                i += 2;
                while (i < n && s[i] >= '0' && s[i] <= '9')
                {
                    num2 *= 10;
                    num2 += s[i] - '0';
                    i++;
                }
                num *= num2;
                num2--;
                sum += num;
                str += to_string(num);
                str += "x^";
                if (num2 == 1)str.pop_back();
                else str += to_string(num2);
                i--;
            }
        }
    }
    if (sum == 0)
    {
        cout << "f'(x)=0" << endl;
    }
    else cout << str;
}
​
signed main()
{
​
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int t = 1;
    //cin >> t;
​
    while (t--)
    {
        solve();
    }
    return 0;
}