ZOJ - 4061 Magic Multiplication (構造)(2018ICPC青島D)
Magic Multiplication
Time Limit: 1 Second Memory Limit: 65536 KB
BaoBao is now learning a new binary operation between two positive integers, represented by , 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 , where indicates the -th digit in , and the second integer be , where indicates the -th digit in . We have
Note that the result of is considered to be a \textbf{string} (without leading zeros if , or contains exactly one `0' if ), NOT a normal integer. Also, the sum here means \textbf{string concatenation}, NOT the normal addition operation.
For example, 23 45 = 8101215. Because , , and .
BaoBao is very smart and soon knows how to do the inverse operation of . Now he gives you the result of a operation and the numbers of digits in the two original integers. Please help him to restore the two original integers and .
Input
There are multiple test cases. The first line of the input contains an integer , indicating the number of test cases. For each test case:
The first line contains two positive integers and (), where indicates the length of and indicates the length of . 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 without leading zeros, indicating the result of . The length of is no more than .
It's guaranteed that the sum of lengths of over all test cases will not exceed .
Output
For each test case output one line.
If there exist such and that , output one line containing two integers and separated by one space. Note that and should be positive integers without leading zeros, the length of should be exactly , and the length of should be exactly .
If there are multiple valid answers, output the answer with the smallest ; If there are still more than one answer, output one of them with the smallest .
If such and 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
解題思路:構造題,思考後發現,其實情況數很少,所以完全可以暴力剪枝。現場暴力搜尋,爆棧了。後來借鑑了別人的做法,實際上不用深搜,直接for迴圈就好了。這裡只要知道一個性質就很好做,
假設兩個數字
64
8
你要用8乘某個數變成6是不可能的,所以這裡必然取64,而不是取6.
所以只需判斷數字是否大於第一位數,大於的話只能取兩位,小於的話只能取一位,即
8>6所以取兩位為64
假設是
81
4
因為4<8,必然取一位為8.
知道這個性質之後,就可以暴力了,因為要求字典序最小,所以列舉A的第一位,然後構造出正確的B,然後通過這個B,構造出A的第二位,然後用A的第二位乘B看看能不能構造出原串即可。第一個找到的就是答案。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 200005;
int N,M,len;
char str[MAXN];
int A[MAXN];
int B[MAXN];
int pos;
bool getB(){
for(int i=0;i<M;i++){
int now=str[pos++]-'0';
if(A[0]>now&&now!=0)//妙啊
now=now*10+str[pos++]-'0';
if(now%A[0]==0){
B[i]=now/A[0];
if(B[i]>=10)
return false;
}
else
return false;
}
return true;
}
bool getA(){
for(int i=1;i<N;i++){
int now=str[pos++]-'0';
if(B[0]>now&&now!=0)//妙啊
now=now*10+str[pos++]-'0';
if(now%B[0]==0){
A[i]=now/B[0];
if(A[i]>=10)
return false;
}
else
return false;
for(int j=1;j<M;j++){
int now=str[pos++]-'0';
if(A[i]>now&&now!=0)
now=now*10+str[pos++]-'0';
if(A[i]*B[j]!=now)
return false;
}
}
return true;
}
bool solve(){
int one=str[0]-'0';
int two=one*10+str[1]-'0';
for(int i=1;i<=9;i++)//列舉
{
pos=0;
if(one%i==0){
A[0]=i;
if(getB()&&getA()&&pos==len)
return true;
}
}
for(int i=1;i<=9;i++)//兩位的情況,一位能找到,字典序必然比兩位小
{
pos=0;
if(two%i==0&&two/i<10){
A[0]=i;
if(getB()&&getA()&&pos==len)
return true;
}
}
return false;
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&N,&M);
scanf("%s",str);
len=strlen(str);
if(solve()){
for(int i=0;i<N;i++)
printf("%d",A[i]);
printf(" ");
for(int i=0;i<M;i++)
printf("%d",B[i]);
puts("");
}
else
printf("Impossible\n");
}
return 0;
}