【ZOJ4061】Magic Multiplication(构造)

题意:定义一个新运算为两个数A,B上每一位相乘,然后顺次接在一起,现在给定结果C和原来两个数字的长度,要求恢复成原来的数字A,B

若有多解输出A字典序最小的,A相同输出B字典序最小的,无解输出Impossible

n,m<=2e5,sigma lenc<=2e6

思路:实际上只需要枚举A的第一位就行了,因为给定一个1-9的数字和接下去的1-2位结果,构造方案一定是唯一的

因为题目要求A和B都没有前导0,根据枚举的A[1]推出B,再根据B[1]推出剩余的A,暴力检验是否与C相等

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<string>
  4 #include<cmath>
  5 #include<iostream>
  6 #include<algorithm>
  7 #include<map>
  8 #include<set>
  9 #include<queue>
 10 #include<vector>
 11 using namespace std;
 12 typedef long long ll;
 13 typedef unsigned int uint;
 14 typedef unsigned long long ull;
 15 typedef pair<int,int> PII;
 16 typedef vector<int> VI;
 17 #define fi first
 18 #define se second 
 19 #define MP make_pair
 20 #define N      210000
 21 #define M      51
 22 #define MOD 1000000007
 23 #define eps 1e-8 
 24 #define pi     acos(-1)
 25 #define oo     1010000000
 26 
 27 char c[N];
 28 int a[N],b[N],n,m,now,len;
 29 
 30 int calcB()
 31 {
 32     for(int i=1;i<=m;i++)
 33     {
 34         int t=c[now++]-'0';
 35         if(a[1]>t&&t!=0) t=t*10+c[now++]-'0';
 36         if(t%a[1]==0&&(t/a[1])<10) b[i]=t/a[1];
 37          else return 0;
 38     }
 39     return 1;
 40 }
 41 
 42 int calcA()
 43 {
 44     for(int i=2;i<=n;i++)
 45     {
 46         int t=c[now++]-'0';
 47         if(b[1]>t&&t!=0) t=t*10+c[now++]-'0';
 48         if(t%b[1]==0&&(t/b[1])<10) a[i]=t/b[1];
 49          else return 0;
 50         for(int j=2;j<=m;j++)
 51         {
 52             int t=c[now++]-'0';
 53             if(a[i]>t&&t!=0) t=t*10+c[now++]-'0';
 54             if(a[i]*b[j]!=t) return 0;
 55         }
 56     }
 57     return 1;
 58 }
 59 
 60 int solve()
 61 {
 62     int one=c[1]-'0';
 63     int two=one*10+c[2]-'0';
 64     for(int i=1;i<=9;i++)
 65      if(one%i==0)
 66      {
 67          now=1;
 68          a[1]=i;
 69          if(calcB()&&calcA()&&now==len+1) return 1;
 70      }
 71      
 72     for(int i=1;i<=9;i++)
 73      if(two%i==0&&two/i<10)
 74      {
 75          now=1;
 76         a[1]=i; 
 77         if(calcB()&&calcA()&&now==len+1) return 1;
 78      }
 79      return 0;
 80 }
 81 
 82 int main()
 83 { 
 84      int cas;
 85      scanf("%d",&cas);
 86      for(int v=1;v<=cas;v++) 
 87      {
 88         scanf("%d%d",&n,&m);
 89         scanf("%s",c+1);
 90         len=strlen(c+1);
 91         if(solve())
 92         {
 93             for(int i=1;i<=n;i++) printf("%d",a[i]);
 94             printf(" ");
 95             for(int i=1;i<=m;i++) printf("%d",b[i]);
 96             printf("\n");
 97         }
 98          else printf("Impossible\n");
 99     }
100     return 0;
101 }
102     

猜你喜欢

转载自www.cnblogs.com/myx12345/p/10054687.html