ACM-ICPC 2018 青岛赛区现场赛 D. Magic Multiplication && ZOJ 4061 (思维+构造)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4061

题意:定义一个长度为 n 的序列 a1,a2,..,an 和长度为 m 的序列 b1,b2,..,bm 所构成的新序列 c 为 a1b1,a1b2,....,anbm,给出最终的序列和两个初始序列的长度,构造出字典序最小的初始序列。

题解:首先我们知道两个个位数相乘最多可以得到两位数,易知最终序列的第一个数字 c1 的构造一定有 a1 的参与,当 a1 <= c1 时或者 c1 == 0时,a1 * b1 必须为个位数;否则 a1 * b1 必须为两位数,容易证明其正确性。有了这个性质以后,可以通过枚举 a1 得到完整的 b 序列,然后通过 b 序列再得出 a 序列。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define ull unsigned long long
 5 #define mst(a,b) memset((a),(b),sizeof(a))
 6 #define mp(a,b) make_pair(a,b)
 7 #define pi acos(-1)
 8 #define pii pair<int,int>
 9 #define pb push_back
10 const int INF = 0x3f3f3f3f;
11 const double eps = 1e-6;
12 const int MAXN = 2e5 + 10;
13 const int MAXM = 1e8 + 10;
14 const ll mod = 1e9 + 7;
15 
16 int n,m,len;
17 char s[MAXN];
18 int a[MAXN],b[MAXN],now[MAXN],pos;
19 bool flag;
20 
21 bool geta() {
22     for(int i = 2; i <= n; i++) {
23         int num = s[++pos];
24         if(b[1] > num && num != 0) num = num * 10 + s[++pos];
25         if(num % b[1] || num / b[1] >= 10) return false;
26         a[i] = num / b[1];
27         for(int j = 2; j <= m; j++) {
28             num = s[++pos];
29             if(a[i] > num && num != 0) num = num * 10 + s[++pos];
30             if(a[i] * b[j] != num) return false;
31         }
32     }
33     if(pos != len) return false;
34     return true;
35 }
36 
37 bool getb() {
38     pos = 0;
39     for(int i = 1; i <= m; i++) {
40         int num = s[++pos];
41         if(a[1] > num && num != 0) num = num * 10 + s[++pos];
42         if(num % a[1] || num / a[1] >= 10) return false;
43         b[i] = num / a[1];
44     }
45     return true;
46 }
47 
48 int main() {
49 #ifdef local
50     freopen("data.txt", "r", stdin);
51 //    freopen("data.txt", "w", stdout);
52 #endif
53     int t;
54     scanf("%d",&t);
55     while(t--) {
56         scanf("%d%d%s",&n,&m,s + 1);
57         len = strlen(s + 1);
58         for(int i = 1; i <= len; i++) s[i] = s[i] - '0';
59         flag = false;
60         for(int i = 1; i <= 9; i++) {
61             if(s[1] % i == 0) {
62                 a[1] = i;
63                 if(getb() && geta()) {
64                     flag = true;
65                     break;
66                 }
67             }
68         }
69         if(!flag) {
70             for(int i = 1; i <= 9; i++) {
71                 if((s[1] * 10 + s[2]) % i == 0) {
72                     a[1] = i;
73                     if(getb() && geta()) {
74                         flag = true;
75                         break;
76                     }
77                 }
78             }
79         }
80         if(flag) {
81             for(int i = 1; i <= n; i++) printf("%d",a[i]);
82             printf(" ");
83             for(int i = 1; i <= m; i++) printf("%d",b[i]);
84             printf("\n");
85         } else puts("Impossible");
86     }
87     return 0;
88 }

猜你喜欢

转载自www.cnblogs.com/scaulok/p/9940440.html