/* |
2013腾讯马拉松初赛第3场 |
1002 威威猫系列故事——因式分解 |
|
Time Limit: 0.2 Seconds Memory Limit: 65536K |
|
“春天来了,万物复苏,大地一片生机盎然,又到了动物们求偶的季节...” |
周末的威威猫虽然眼睛盯着电视屏幕,但是思绪却停留在自己喜欢的数学问题上。 |
有人说孤独是可耻的,但是单身一人的威威猫并不孤独,随着对数学的深入学习,威威猫甚至很庆幸自己没有陷入儿女情长,因为他有喜爱的数学相伴,最近,他就在潜心研究因式分解问题。 |
在我们学习数学的过程中,经常需要把一个多项式进行因式分解,也就是把它写成乘积的形式,比如多项式x^2+3x+2分解因式的结果就是(x+1)(x+2)。这个因式一眼就能看出来,但是当x的指数更高时,就不太容易分解了。 |
现在,威威猫就是在研究如何编写程序来实现对多项式的因式分解。 |
Input |
输入第一行是一个整数T(T<=50),表示测试数据的组数; |
接下来是T行字符串表示T个测试用例,每行1个数学多项式,多项式长度不会超过100个字符,每个多项式表示形式如下: A[1]x^P[1]+A[2]x^P[2]+...+A[m]x^P[m] |
其中0<=P[i]<=5,A[i]表示x^P[i]的系数,A[i]=0时直接简写为0,A[i]=1和-1时分别简写为x^P[i]与-x^P[i],P[i]=0和1时分别简写为A[i]与A[i]x,且同一指数r的对应项系数之和的绝对值不超过1000, 每行中没有多余空格,具体格式可参考Sample Input。 |
Output |
对于每组测试数据,首先输出Case #X: ,X代表多项式编号,从1开始计数,然后输出因式分解的结果,分解结果的表示形式规定如下: |
(x+B[1])(x+B[2])...(x+B[m]) |
其中,B[1]<=B[2]<=...<=B[m],若B[i]=0则不加括号直接简写为x,如果无法表现成上述格式,则输出"-1"。 |
具体可参考Sample Output。 |
Sample Input |
4 |
x |
x+1 |
-2x^2+x^2+x^3 |
2x+2 |
Sample Output |
Case #1: x |
Case #2: (x+1) |
Case #3: (x-1)xx |
Case #4: -1 |
|
*/ |
/* |
解题报告: |
这题的话初看很难,一些头续也没有。 |
仔细研究会发现,p[i]比较小,最多是5,也就是说,分解出来的因式最多5个。 |
每一个因子是形如(x+b[i])也就是说确定b[i]就可以了。 |
题目中说了每一项系数绝对值不超过1000,我们考虑最后一项常数项 |
常数项是由b[1]*b[2]*b[3]*b[4]*...*b[5] |
也就是说这些b[i]是常数项的因子,而且乘起来要等于常数项。 |
常数项不大,我们可以枚举常数项的因子。 |
然后去验证。 |
之儿有一个小问题就是,如果常数项为0怎么办,这种情况下的话,也就是说大家可以提出一个x来,如果还是0,就再提x。 |
对最后常数项不为0的进行分解就行了。 |
*/ |
#include<stdio.h> |
#include<string.h> |
#include<algorithm> |
using namespace std ; |
const int MAX = 110; |
const int INF = 100000000; |
char s[MAX]; |
int c[6]; |
struct BigNum { |
int dig[6]; |
int len; |
void clr() { |
len = 1; |
memset (dig, 0, sizeof (dig)); |
} |
}; |
bool dig( char x) { |
return x >= '0' && x <= '9' ; |
} |
BigNum f; |
BigNum Div(BigNum a, int b) { |
int i; |
int t; |
BigNum ret; |
ret.clr(); |
for (i = a.len - 1; i >= 1; i--) { |
t = a.dig[i]; |
ret.dig[i - 1] += t; |
a.dig[i] = 0; |
a.dig[i - 1] -= b * t; |
} |
ret.len = -1; |
if (a.dig[0] != 0) return ret; |
for (i = 5; i >= 0 && ret.dig[i] == 0; i--); |
ret.len = i + 1; |
return ret; |
} |
int calc() { |
int i; |
if (f.dig[0] == 0) { |
for (i = 0; i + 1 < f.len; i++) { |
f.dig[i] = f.dig[i + 1]; |
} |
f.len--; |
return 0; |
} |
for (i = -1000; i <= 1000; i++) { |
if (i == 0 && f.dig[0] != 0) continue ; |
else if (i != 0 && f.dig[0] % i != 0) continue ; |
BigNum tmp = Div(f, i); |
if (tmp.len == -1) continue ; |
f = tmp; |
return i; |
} |
return INF; |
} |
int main () { |
int T, CS = 1; |
int len; |
int tmp, p; |
int i; |
scanf ( "%d" , &T); |
while (T--) { |
scanf ( "%s" , s); |
memset (c, 0, sizeof (c)); |
len = strlen (s); |
int left, right; |
for (i = 0; i < len; i++) { |
if (s[i] == 'x' ) { |
//计算有边 |
if (s[i + 1] == '^' ) { |
right = i + 2; |
p = s[right] - '0' ; //最多是5,取1为就行了 |
} else { |
right = i; |
p = 1; |
} |
int ten = 1; |
left = i - 1; |
tmp = 0; |
while (left >= 0 && dig(s[left])) { |
tmp += (s[left] - '0' ) * ten; |
ten *= 10; |
left--; |
} |
if (tmp == 0)tmp++; |
if (left >= 0 && s[left] == '-' ) { |
tmp = -tmp; |
left--; |
} |
c[p] += tmp; |
for (left++; left <= right; left++) { |
s[left] = 1; |
} |
} |
} |
//puts("zz"); |
for (i = 0; i < len; i++) { //求剩下的常数 |
if (s[i] == '-' || dig(s[i])) { |
int sign = 1; |
tmp = 0; |
if (s[i] == '-' ) { |
sign = -1; |
i++; |
} |
while (i < len && dig(s[i])) { |
tmp = tmp * 10 + s[i] - '0' ; |
i++; |
} |
i--; |
c[0] += tmp * sign; |
} |
} |
int maxc = 5; |
while (maxc >= 0 && c[maxc] == 0) { |
maxc--; |
} |
printf ( "Case #%d: " , CS++); |
if (maxc <= 0) { |
puts ( "-1" ); |
continue ; |
} else if (c[maxc] != 1) { |
puts ( "-1" ); |
continue ; |
} |
//puts("");for(i=0;i<=maxc;i++)printf("x[%d]=%d\n",i,c[i]); |
int ans[6]; |
f.clr(); |
memcpy (f.dig, c, sizeof (c)); |
f.len = maxc + 1; |
for (i = 0; i < maxc; i++) { |
ans[i] = calc(); |
if (ans[i] == INF) break ; |
} |
if (i < maxc) { |
puts ( "-1" ); |
} else { |
sort(ans, ans + maxc); |
for (i = 0; i < maxc; i++) { |
if (ans[i] == 0) putchar ( 'x' ); |
else if (ans[i] < 0) printf ( "(x%d)" , ans[i]); |
else printf ( "(x+%d)" , ans[i]); |
} |
puts ( "" ); |
} |
} |
return 0 ; |
} |
初级程序员
by: 我的程序员之路 发表于:2013-05-19 20:46:03 顶(0) | 踩(0) 回复
厉害!
回复评论