Simple Polynomial Problem FZU - 2215 (字符串求值+多项式)

3人阅读 评论(0) 收藏 举报
分类:

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.

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.

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).

Sample Input
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
Sample Output
3
1 2 1
1 3 7 6 0
2 0 0

思路 : 在已经有了字符串求值的算法以后,就很容易理解这个题了我们可以将字符串里的每个非运算符的字符都当成一个多项式,那么这样的话,就能把这个问题转化为字符串求值问题。

例如  (1+x)*(1+x) 就变成了   (1+2)*(3+4) 其中每个数字代表一个多项式,也就是多项式数组的下标。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<cstring>
#include<string>
#include<vector>
#include<cmath>
#include<map>
#include<set>
#define mem(a,b) memset(a,b,sizeof(a))
#define mod 1000000007
using namespace std;
typedef long long ll;
const int maxn = 1e6+500;
const double esp = 1e-7;
const int ff = 0x3f3f3f3f;
map<int,int>::iterator it;

char s[1005];
int a[1005];
int iid[500];
struct mat{
	ll x[501];
};


mat operator + (mat a, mat b)    // 重载多项式加法
{
	for(int i = 500; i >= 0; i--)
	{
		a.x[i] = (b.x[i]+a.x[i])%mod;
	}
	return a;
}
	
mat operator * (mat a,mat b)   // 重载多项式乘
{
	mat ans;
	memset(ans.x,0,sizeof(ans.x));
	int al = 500;
	int bl = 500;
	while(a.x[al] == 0) al--;
	while(b.x[bl] == 0) bl--;
	for(int i = al; i >= 0; i--)
	for(int j = bl; j >= 0; j--)
	{
		ans.x[i+j] += a.x[i]*b.x[j];
		ans.x[i+j] %= mod;
	}
	return ans;
}

int pri[][6] = {      // 优先级允许数组
    0,0,0,0,0,0,
    0,0,0,0,0,0,
    0,0,0,0,0,0,
    0,0,1,0,0,0,
    0,1,1,1,1,0,
    0,1,1,1,1,0
}; 
void get()     // 运算符编号
{
	iid['('] = 1;
	iid['*'] = 2;
	iid['+'] = 3;
	iid[')'] = 4;	
	iid['#'] = 5;	
}
int j;
mat mt[1005];

mat solve(int n)   // 字符串求值
{
	stack <int> s1;
	stack <int> s2;
	for(int i = 0; i < n; i++)
	{	
		if(a[i] >= 0)    // 是数字 
		{
			s1.push(a[i]);
		}
		else    // 是符号 
		{
			while(s2.size() && pri[-a[i]][-(s2.top())])
			{
				int x = s2.top();
				s2.pop();
				if(-x == 1) break;
				if(-x == 2) 
				{
					int y = s1.top();
					s1.pop();
					int yy = s1.top();
					s1.pop();
					mt[j] = mt[y]*mt[yy];
					s1.push(j++);
				} 
				if(-x == 3)
				{
					int y = s1.top();
					s1.pop();
					int yy = s1.top();
					s1.pop();
					mt[j] = mt[y]+mt[yy];
					s1.push(j++);
				}
			}
			if(a[i] != -4) s2.push(a[i]); // 右括号不加 
		}
	}
	return mt[s1.top()]; 
}


int main()
{
    int t;
    scanf("%d",&t);
    get();
    while(t--)
    {
    	scanf("%s",s);
    	int n = strlen(s);
    	j = 1;
    	memset(mt,0,sizeof(mt));
    	for(int i = 0; s[i]; i++)
    	{
    		if(s[i] >= '0' && s[i] <= '9')
    		{
    			mt[j].x[0] =  s[i] - '0';
    			a[i] = j++;
    		}
    		else if(s[i] == 'x')
    		{
    			mt[j].x[1] = 1;
    			a[i] = j++;
    		}
    		else
    		a[i] = iid[s[i]]*(-1);
    	}
    	a[n] = -5;
    	int i = 500;
    	mat ans = solve(n+1);
    	while(i > 0 && ans.x[i] == 0) i--;   // 注意非零输出
    	for(;i>=0; i--)
    	{
    		printf(i == 0 ?"%I64d\n" : "%I64d ",ans.x[i]);
    	}
    }
	return 0;
}

查看评论

【FZU 2215】Simple Polynomial Problem

D - Simple Polynomial Problem Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d ...
  • Torrance_ZHANG
  • Torrance_ZHANG
  • 2016-04-04 22:58:20
  • 519

FZU 2215 Simple Polynomial Problem【模拟】【表达式计算】

题目链接http://acm.fzu.edu.cn/problem.php?pid=2215思路题意就是叫你把给你的多项式化到最简,输出各项系数。表达式计算用栈实现就行了,但这题需要改动下,数据栈内不...
  • wlx65003
  • wlx65003
  • 2016-04-14 19:02:01
  • 593

状压dp fzu2218 Simple String Problem

传送门:点击打开链接 题意:一个长为n(n 求两段子串A和B,A和B中间没有共用的字母类型,求len(A)*len(B)的最大值 思路:当时想到了3种方法,感觉各有优势,都来BB一下。 ...
  • qwb492859377
  • qwb492859377
  • 2015-12-28 12:48:03
  • 955

FZU 2215 Simple Polynomial Problem 多项式模拟 表达式树

Problem 2215 Simple Polynomial Problem Time Limit: 1000 mSec    Memory Limit : 32768 KB Problem D...
  • lmhacm
  • lmhacm
  • 2017-04-16 16:51:53
  • 231

FZU 2215 Simple Polynomial Problem (多项式乘法 栈)

FZU 2215 Simple Polynomial Problem (多项式乘法 栈)
  • Tc_To_Top
  • Tc_To_Top
  • 2016-08-20 19:14:23
  • 845

Polynomial Problem(hdu 1296 表达式求值)

We have learned how to obtain the value of a polynomial when we were a middle school student. If f(x...
  • qq_35806592
  • qq_35806592
  • 2017-04-02 15:22:16
  • 161

hdu 1296 Polynomial Problem(多项式模拟)

Problem Description We have learned how to obtain the value of a polynomial when we were a middle s...
  • xiaosshhaa
  • xiaosshhaa
  • 2017-03-29 21:38:45
  • 220

第六届福建省大学生程序设计竞赛——G Simple String Problem(状态压缩dp)

题目链接:http://acm.fzu.edu.cn/problem.php?pid=2218题目大意:解题思路:PS: 因为这道题目自己当时没有做出来,是下来以为巨巨给的题解,他真的有一万种方法AC...
  • Yick_Liao
  • Yick_Liao
  • 2015-12-29 09:27:43
  • 787

fzu2218 Simple String Problem

Accept: 2    Submit: 16 Time Limit: 2000 mSec    Memory Limit : 32768 KB  Problem Description ...
  • Kirito_Acmer
  • Kirito_Acmer
  • 2015-12-28 11:09:19
  • 565

FZU 2218 Simple String Problem(状态压缩DP)

FZU 2218 Simple String Problem(状态压缩DP) 组队赛时遇到的一道题,最后几分钟才做出来。说实话我做的时候也完全没有底,没想到竟然能一发AC...
  • lincifer
  • lincifer
  • 2016-03-20 23:35:55
  • 423
    个人资料
    持之以恒
    等级:
    访问量: 1万+
    积分: 1064
    排名: 4万+
    最新评论