-
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; }
D - Magic Multiplication ZOJ - 4061-数学构造
猜你喜欢
转载自blog.csdn.net/BePosit/article/details/83960920
今日推荐
周排行