ZOJ - 4061 Magic Multiplication (构造)(2018ICPC青岛D)

版权声明:Why is everything so heavy? https://blog.csdn.net/lzc504603913/article/details/83826306

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;
}

猜你喜欢

转载自blog.csdn.net/lzc504603913/article/details/83826306