• 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("
    ");
    85         } else puts("Impossible");
    86     }
    87     return 0;
    88 }
  • 相关阅读:
    Leetcode 694. 不同岛屿的数量 中等 回溯 岛屿问题
    集成电路设计流程
    Leetcode 44. 通配符匹配 困难 动态规划 精选 TOP 面试题
    Leetcode 13. 罗马数字转整数 简单 字符串
    Leetcode 36. 有效的数独 中等 数组遍历 精选 TOP 面试题
    windows 不是真正的多用户OS,linux才是
    java AWT弹球游戏
    java AWT 图片查看器
    java AWT 简易绘图
    java Swing 进度条
  • 原文地址:https://www.cnblogs.com/scaulok/p/9940440.html
Copyright © 2020-2023  润新知