1. 程式人生 > >Magic Multiplication ZOJ

Magic Multiplication ZOJ

  • 題意:題目定義一個運算子對於數A和數B的運演算法則為從A的第1位開始,每一位數去乘B的每一位數
  • 乘完之後進行A的下一位再去乘B的所有位上的數都是按照順序來的,然後所得結果按照操作順序構成字串C
  • 現在給出最終的結果串C,以及A的長度n和B的長度m,要你求出原來的A序列和B序列。
  • 思路:舉幾個例項發現C中的一個數如果能夠整除1-9之間的數那麼它不會去與下面一個數湊成兩位數作為結果
  • 一定是它自己就是一個乘積結果,瞭解這個規律之後進行列舉A的第一個位置的數,注意分一下情況看看是
  • 兩位數作為結果還是一位數作為結果,然後求出B串,再用B串不斷求出A的下一位在這個過程中
  • 不斷驗證A[i]與B的乘積是否是當前遍歷的序列。如果找到直接返回true 一定是字典序最小的。
  • #include<bits/stdc++.h>
    using namespace std;
    #define maxn 211985
    int a[maxn],b[maxn];
    char str[maxn];
    int n,t,pos,len,m;
    bool getb()
    {
        for(int i=0; i<m; i++)
        {
            int now=str[pos++]-'0';
            if(now%a[0]!=0)now=now*10+str[pos++]-'0';
            if(now%a[0]==0&&now/a[0]<10)
                b[i]=now/a[0];
            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&&now/b[0]<10)
                a[i]=now/b[0];
            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 0;
    }
    int main()
    {
        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]);
                printf("\n");
            }
            else printf("Impossible\n");
        }
        return 0;
    }