D - Magic Multiplication ZOJ - 4061-数学构造

  • D - Magic Multiplication

  •  ZOJ - 4061 
  • 题意:题目定义一个运算符对于数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;
    }
  •  

猜你喜欢

转载自blog.csdn.net/BePosit/article/details/83960920