# 我會因式分解
https://neoj.sprout.tw/problem/514/
### 題目敘述
因式分解國中都有教,但很多人還是不會,所以我們要讓電腦幫我們做。
現在給你 $N$ 個候選的 $D$ 次因式,接下來有 $Q$ 個 $2D$ 次多項式,請輸出它由哪兩個因式組成。
### 輸入
第一行有三個整數 $D,\ N,\ Q$ 分別代表因式的次數、因式的個數、多項式的個數。
接下來有 $N$ 行,每行有 $D+1$ 個整數 $c_0,\ c_1,\ ...\ c_i\ ...\ c_D$ ,代表因式的 $i$ 次係數(升冪排序)。
接下來有 $Q$ 行,每行有 $2D+1$ 個整數 $e_0,\ e_1,\ ...\ e_i\ ...\ e_{2D}$ ,代表多項式的 $i$ 次係數(升冪排序)。
### 輸出
請輸出 $Q$ 行,每行形如 $(c_0 + c_1x^1, ... c_Dx^D)(c'_0 + c_1x^1, ... c_Dx^D)$,且左項不比右項晚被輸入。
輸入限制
$1 \le D < 10$
$1 \le N < 30$
$1 \le Q < 10$
$|c| \le 10000$
保證 $Q$ 個多項式 $q$ 皆可在前 $N$ 個因式中找到 $n_1,\ n_2$,使得 $q(x) = n_1(x) * n_2(x)$。
### 範例輸入輸出
#### 範例輸入 I
```
1 2 2
1 1
2 1
1 2 1
2 3 1
```
#### 範例輸出 I
```
(1 + 1x^1)(1 + 1x^1)
(1 + 1x^1)(2 + 1x^1)
```
#### 範例輸入 II
```
3 3 1
9 8 2 3
1 0 0 -1
-1 0 0 1
-1 0 0 2 0 0 -1
```
#### 範例輸出 II
```
(1 + 0x^1 + 0x^2 + -1x^3)(-1 + 0x^1 + 0x^2 + 1x^3)
```
### Hint
你可以直接使用下面的程式碼,並填入有寫 TODO 的部份。
```cpp
#include <iostream>
#include <cstring>
#define MAXN 30
#define MAXD 10
// 多項式乘法,res = a*b,並回傳 res 陣列。
int *convolution(int a[], int b[], int res[], int D){
memset(res, 0, (2 * D + 1) * sizeof(int));
// TODO
return res;
}
// 讀一個 D 次多項式到陣列 p
void readPoly(int p[], int D){
// TODO
}
// 印出形如 (c_0 + c_1x^1 ... c_Dx^D) 的多項式 p
void printPoly(int p[], int D){
// TODO
}
int main(){
int D, N, Q;
int factor[MAXN][MAXD + 1];
int input[MAXD * 2 + 1];
int result[MAXD * 2 + 1];
std::cin >> D >> N >> Q;
for(int i = 0; i < N; i++)
readPoly(factor[i], D);
while(Q--){
readPoly(input, D * 2);
for(int i = 0; i < N; i++)
for(int j = i; j < N; j++)
if(memcmp(convolution(factor[i], factor[j], result, D), input, (2 * D + 1) * sizeof(int)) == 0)
{
printPoly(factor[i], D);
printPoly(factor[j], D);
std::cout << std::endl;
}
}
}
```
# Code
```cpp
#include <iostream>
#include <cstring>
#define MAXN 30
#define MAXD 10
using namespace std;
int *convolution(int a[], int b[], int res[], int D){
memset(res, 0, (2 * D + 1) * sizeof(int));
for (int i = 0 ; i <= D ; i++)
for (int j = 0 ; j <= D ; j++)
res[i + j] += a[i] * b[j];
return res;
}
void readPoly(int p[], int D){
for (int i = 0 ; i <= D ; i++)
cin >> p[i];
}
void printPoly(int p[], int D){
cout << "(";
for (int i = 0 ; i <= D ; i++){
cout << p[i];
if (i != 0)
cout << "x^" << i;
if (i != D)
cout << " + ";
}
cout << ")";
}
int main(){
int D, N, Q;
int factor[MAXN][MAXD + 1];
int input[MAXD * 2 + 1];
int result[MAXD * 2 + 1];
cin >> D >> N >> Q;
for (int i = 0; i < N; i++)
readPoly(factor[i], D);
while (Q--)
{
readPoly(input, D * 2);
for (int i = 0 ; i < N; i++)
for (int j = i; j < N; j++)
if (memcmp(convolution(factor[i], factor[j], result, D),
input, (2 * D + 1) * sizeof(int)) == 0)
{
printPoly(factor[i], D);
printPoly(factor[j], D);
cout << "\n";
}
}
}
```