Magic Multiplication ZOJ
阿新 • • 發佈:2018-12-20
- 題意:題目定義一個運算子對於數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; }