D - Magic Multiplication(The 2018 ACM-ICPC Asia Qingdao Regional Contest)(找規律+構造)

D - Magic Multiplication(The 2018 ACM-ICPC Asia Qingdao Regional Contest)(找規律+構造)

Time limit:1000 ms
Memory limit:65536 kB
judge:
ZOJ 4061
vjudge

Description

BaoBao is now learning a new binary operation between two positive integers, represented by \otimes, in his magic book. The book tells him that the result of such operation is calculated by concatenating all multiple results of each digit in the two integers.

Formally speaking, let the first integer be A=a1a2anA = a_1a_2 \dots a_n, where aia_i indicates the ii-th digit in AA, and the second integer be B=b1b2bmB = b_1b_2 \dots b_m, where bib_i indicates the ii-th digit in BB. We have AB=i=1nj=1maibj=a1b1+a1b2++a1bm+a2b1++anbmA \otimes B = \sum\limits_{i=1}^n\sum\limits_{j=1}^m a_ib_j = a_1b_1 + a_1b_2 + \dots + a_1b_m + a_2b_1 + \dots + a_nb_m Note that the result of aibja_ib_j is considered to be a \textbf{string} (without leading zeros if aibj>0a_ib_j > 0, or contains exactly one `0’ if aibj=0a_ib_j = 0), NOT a normal integer. Also, the sum here means \textbf{string concatenation}, NOT the normal addition operation.

For example, 23 \otimes 45 = 8101215. Because 8=2×48=2 \times 4, 10=2×510=2 \times 5, 12=3×412=3 \times 4 and 15=3×515=3 \times 5.

BaoBao is very smart and soon knows how to do the inverse operation of \otimes. Now he gives you the result of a \otimes operation and the numbers of digits in the two original integers. Please help him to restore the two original integers AA and BB.

Input

There are multiple test cases. The first line of the input contains an integer TT, indicating the number of test cases. For each test case:

The first line contains two positive integers nn and mm (1n,m2×1051 \le n, m \le 2 \times 10^5), where nn indicates the length of AA and mm indicates the length of BB. Here length of an integer means the length of the string when writing the number in decimal notation without leading zeros.

The second line contains only one positive integer CC without leading zeros, indicating the result of ABA \otimes B. The length of CC is no more than 2×1052 \times 10^5.

It’s guaranteed that the sum of lengths of CC over all test cases will not exceed 2×1062 \times 10^6.

Output

For each test case output one line.

If there exist such AA and BB that AB=CA \otimes B = C, output one line containing two integers AA and BB separated by one space. Note that AA and BB should be positive integers without leading zeros, the length of AA should be exactly nn, and the length of BB should be exactly mm.

If there are multiple valid answers, output the answer with the smallest AA; If there are still more than one answer, output one of them with the smallest BB.

If such AA and BB do not exist, print “Impossible” (without quotes) on a single line.

Sample Input

4
2 2
8101215
3 4
100000001000
2 2
80101215
3 4
1000000010000

Sample Output

23 45
101 1000
Impossible
Impossible

題意

這裏又三個數字:A,B,CA, B, C。給你 AABB 的長度和 CC ,問你是否能還原出 AABB ,如果能就輸出 AABB

有如下運算:AB=i=1nj=1maibj=a1b1+a1b2++a1bm+a2b1++anbmA \otimes B = \sum\limits_{i=1}^n\sum\limits_{j=1}^m a_ib_j = a_1b_1 + a_1b_2 + \dots + a_1b_m + a_2b_1 + \dots + a_nb_m

例:23 \otimes 45 = 8101215. Because 8=2×48=2 \times 4, 10=2×510=2 \times 5, 12=3×412=3 \times 4 and 15=3×515=3 \times 5

題解

難點在於我們在枚舉 CC 時無法確定該取一位數字還是兩位數字。

但我們知道,兩個長度爲 11 的數字相乘,其最小值是 00 ,最大值是 8181 ,即乘積的長度不超過 22 。其次,若乘積的長度是 22 ,則乘積的十位數字小於兩個數字的任意一個;如果乘積的長度是 11 ,則乘積大於兩個數字的任意一個。

所以我們在枚舉數字時,只需要判斷一下 CC 的數字和我們枚舉的數字的大小就可知道該取 11 位還是該取兩位:如果 CC 的數字小於枚舉數字,就取兩位,然後判斷是否能整除;如果 CC 的數字小於枚舉數字,就取 11 位,然後判斷是否能整除。

因爲 AABB 的長度是已知的,所以我們可以先枚舉 A[0]A[0] ,然後利用 CC 的前半部分和 A[0]A[0] 枚舉 BB (一個 A[0]A[0] 對應 11 個或 00BB ),然後再利用枚舉的 BB 去推導剩餘的 AA 。如果推導成功就得出了答案,而且因爲推導的過程是由大到小的,所以第一個滿足要求的答案就是最小的答案。

代碼

#include <bits/stdc++.h>
#define maxn 200005
#define _for(i, a) for(int i = 0; i < (a); ++i)
#define _rep(i, a, b) for(int i = (a); i <= (b); ++i)
#define scl(x) scanf("%lld", &x)
#define sc(x) scanf("%d", &x)
using namespace std;

int T, n, m;
int a[maxn], b[maxn];
char c[maxn];

bool getb() {
	int len = strlen(c), pos = 0;
	_for(i, m) {
		if (pos == len) return 0;					//C不夠用了
		int x = c[pos++] - '0';
		if (pos < len && x && x < a[0]) x = x * 10 + c[pos++] - '0';
		if (x % a[0] || x / a[0] > 9) return 0;		//除不盡或者商是兩位數
		b[i] = x / a[0];
	}
	_rep(i, 1, n - 1) {
		_for(j, m) {
			if (pos == len) return 0;				//C不夠用了
			int x = c[pos++] - '0';
			if (pos < len && x && x < b[j]) x = x * 10 + c[pos++] - '0';
			if (x && (b[j] == 0 || j && a[i] == 0)) return 0;	//a和b都爲0但c不爲0
			if (x == 0) {
				if (j && a[i] && b[j]) return 0;	//c爲0但a和b都不爲0;j不爲0代表a已經被賦值
				if (!j) a[i] = 0;
			}
			else {
				if (x % b[j] || j && x / b[j] != a[i] || x / b[j] > 9) return 0;	//除不盡或者商是兩位數
				a[i] = x / b[j];
			}
		}
	}
	return pos == len;
}

bool sol() {
	sc(n), sc(m);
	scanf("%s", c);
	int x = c[0] - '0';
	_rep(i, 1, 9) {		//利用a[0]找出b
		if (x % i == 0) {
			a[0] = i;
			if (getb()) return 1;
		}
	}
	x = x * 10 + c[1] - '0';
	_rep(i, 1, 9) {		//利用b找出a
		if (x % i == 0) {
			a[0] = i;
			if (getb()) return 1;
		}
	}
	return 0;
}

int main() {
	while (cin >> T) {
		_for(i, T) {
			if (sol()) {
				_for(j, n) printf("%d", a[j]);
				printf(" ");
				_for(j, m) printf("%d", b[j]);
				printf("\n");
			}
			else printf("Impossible\n");
		}
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章