zoukankan      html  css  js  c++  java
  • FZU 2215 Simple Polynomial Problem(简单多项式问题)

    Description

    题目描述

    You are given an polynomial of x consisting of only addition marks, multiplication marks, brackets, single digit numbers, and of course the letter x. For example, a valid polynomial would be: (1+x)*(1+x*x+x+5)+1*x*x.

    You are required to write the polynomial into it's minimal form by combining the equal terms.

    For example, (1+x)*(1+x) would be written as x^2+2*x+1.

    Also, (1+x)*(1+x*x+x+5)+1*x*x would be written as x^3+3*x^2+7*x+6.

    给你一个由加号、乘号、括号、一位数以及未知数x组成的多项式。例如,一个有效多项式可以是:(1+x)*(1+x*x+x+5)+1*x*x。

    现在你需要写出与原式等价的最小多项式形式。

    例如,(1+x)*(1+x)应该改写成x^2+2*x+1。

    同理,(1+x)*(1+x*x+x+5)+1*x*x 应该改写成x^3+3*x^2+7*x+6。

    Input

    输入

    The first line contains an integer T, meaning the number of the cases. 1 <= T <= 50.

    For each test case, there will be one polynomial which it's length would be not larger than 1000.

    It is guaranteed that every input polynomial is valid, and every number would be a single digit.

    输入的首行是一个整数T,表示测试样例的数量。1 <= T <= 50。

    对于每个测试样例,都有一个长度不超过1000的多项式。

    保证输入字符串均有效,并且所有数字都是一位数。

    Output

    输出

    For each polynomial, output it's minimal form. If the polynomial's minimal form has n terms, output n space-separated integers.

    You only have to output each term's corresponding constant (from highest to lowest). In case the constant gets too big, output the remainder of dividing the answer by 1000000007 (1e9 + 7).

    输出每个多项式的最小形式。如果最小多项式有n项,则输出n个用空格分隔的整数。

    你只要输出每项对应的系数(从高到低)。为防止输出过大,输出的结果模1000000007(1e9 + 7)。

    Sample Input - 输入样例

    Sample Output - 输出样例

    4

    1*(1+1*(1+1))

    (1+x)*(1+x)

    x*((1+x)*(1+x*x+x+5)+1*x*x)

    (x*x*x*0+x*2)*x

    3

    1 2 1

    1 3 7 6 0

    2 0 0

    【题解】

    类似表达式求值的做法,表达式求值分为数字栈和符号栈,这里的区别就是把数字栈换成多项式栈。当然,由于储存方式的不同,写法也不唯一。

    需要注意的是运算时候数据是否溢出。

    【代码 C++】

    下面贴出代码版本比较原始,不过个人认为可读性比较好,算法简单。当然留了优化的空间,有兴趣(强迫症)可以试试……

    注意,因为下面代码中使用的gets()由于不安全,C11标准中删除了gets(),使用一个新的更安全的函数gets_s()替代。

     1 #include<cstdio>
     2 #include<cstring>
     3 __int64 polynomial[505][505], mi, pi;
     4 char data[1005], mark[505], *di;
     5 bool j_mark(){
     6     switch (*di){
     7     case 0: return 0;
     8     case '(': return 1;
     9     case ')': return 0;
    10     case '+':
    11         if (mark[mi] == '*' || mark[mi] == '+') return 0;
    12         else return 1;
    13     case '*':
    14         if (mark[mi] == '*') return 0;
    15         return 1;
    16     default: return 0;
    17     }
    18 }
    19 bool j_count(){
    20     switch (*di){
    21     case 0: return mark[mi] ? 1 : 0;
    22     case ')':
    23         if (mark[mi] != '(') return 1;
    24         --mi;
    25         return 0;
    26     case '+':
    27         if (mark[mi] == '*' || mark[mi] == '+') return 1;
    28         mark[++mi] = '+';
    29         return 0;
    30     case '*':
    31         if (mark[mi] == '*') return 1;
    32         mark[++mi] = '*';
    33         return 0;
    34     default: return 0;
    35     }
    36 }
    37 void count(){
    38     __int64 temp[505];
    39     memset(temp, 0, sizeof(temp));
    40     if (mark[mi] == '+'){
    41         for (int i = 0; i <= 500; ++i)
    42             temp[i] = (polynomial[pi][i] + polynomial[pi - 1][i]) % 1000000007;
    43     }
    44     else{
    45         int i, j;
    46         for (i = 0; i <= 500; ++i){
    47             if (!polynomial[pi][i]) continue;
    48             for (j = 0; j <= 500; ++j){
    49                 if (!polynomial[pi - 1][j]) continue;
    50                 temp[i + j] += (polynomial[pi][i] * polynomial[pi - 1][j]) % 1000000007;
    51                 temp[i + j] %= 1000000007;
    52             }
    53         }
    54     }
    55     --pi; --mi;
    56     memcpy(polynomial[pi], temp, sizeof(temp));
    57     return;
    58 }
    59 void opt(){
    60     int st = 500;
    61     while (st){
    62         if (!polynomial[0][st]) --st;
    63         else break;
    64     }
    65     printf("%d", polynomial[0][st]);
    66     for (--st; ~st; --st) printf(" %d", polynomial[0][st]);
    67     puts("");
    68     return;
    69 }
    70 int main(){
    71     int T;
    72     scanf("%d", &T); getchar();
    73     while (T--){
    74         pi = -1; mark[0] = mi = 0;
    75         for (gets(data), di = data; true; ++di){
    76             if (*di < '0'){//符号
    77                 if (j_mark()) mark[++mi] = *di;
    78                 else{
    79                     while (j_count()) count();
    80                 }
    81             }
    82             else{
    83                 ++pi;
    84                 memset(polynomial[pi], 0, sizeof(polynomial[pi]));
    85                 if (*di > '9') polynomial[pi][1] = 1;
    86                 else polynomial[pi][0] = *di - '0';
    87             }
    88             if (!*di) break;
    89         }
    90         opt();
    91     }
    92     return 0;
    93 }
    FZU 2215

    FZU 2215
     

  • 相关阅读:
    黑鲨2无限重启 把竞技按钮调到最上
    绿联 电池
    阿里云
    Centos 8 搭建时钟服务器
    CentOS8系统时间同步解决方法
    解决问题的人干活快的人
    【海通国际】Joe Lowry(Mr. Lithium)谈全球电池原材料供应危机
    Linux 实验楼
    用 set follow-fork-mode child即可。这是一个 gdb 命令,其目的是告诉 gdb 在目标应用调用fork之后接着调试子进程而不是父进程,因为在 Linux 中fork系统调用成功会返回两次,一次在父进程,一次在子进程
    【随笔】阿里云修改DNS
  • 原文地址:https://www.cnblogs.com/Simon-X/p/5134291.html
Copyright © 2011-2022 走看看