zoukankan      html  css  js  c++  java
  • 【ZOJ】4061-Magic Multiplication 思维+模拟

    题目链接

    题意

    定义(A otimes B = sumlimits_{i=1}^nsumlimits_{j=1}^m a_ib_j = a_1b_1 + a_1b_2 + dots + a_1b_m + a_2b_1 + dots + a_nb_m)

    现在给出 (A)(B) 的位数以及 (A otimes B),输出 (A) 的值以及 (B) 的值,如果有多个答案,优先输出 (A) 的最小值。

    思路

    比赛的时候自己被自己迷惑住了。
    队友说枚举 (A_1) ,就可以求出唯一一个 (A_1) 对应的 (B),我一直不信,因为主观认为对于 (A_1) 无法从给出的 (A otimes B) 看出对应的 (A_1 imes B_i) 是一位还是两位,所以可能对于一个 (A_1) 可能求出很多个 (B)

    但是后来仔细一想,对于一个 (A_1) 只可能有一个 (B)

    当时时间不是很多了,中间浪费了一段时间,没有写完。

    赛后补了。

    首先枚举 (A_1) 的值 [1,9],然后我们遍历 (A otimes B) ,先用 1 位除 (A_1),如果一位不行,就用两位,如果两位都不行,那么这个(A_1)就不合适。

    直到得到 (m) 个数字,即 (B)

    这时再用剩下的 (A otimes B) "除" (B),和上面步骤类似,验证得到的 (A) 是否合法,如果合法,存起来这对 (A,B),排个序,输出最小的。

    代码

    /*
     * @Autor: valk
     * @Date: 2020-08-21 11:06:28
     * @LastEditTime: 2020-10-12 10:15:27
     * @Description: 如果邪恶  是华丽残酷的乐章 它的终场 我会亲手写上 晨曦的光 风干最后一行忧伤 黑色的墨 染上安详
     */
    #include <bits/stdc++.h>
    #define emplace_back push_back
    #define pb push_back
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int mod = 1e9 + 7;
    const int seed = 12289;
    const double eps = 1e-6;
    const int inf = 0x3f3f3f3f;
    const int N = 2e5 + 10;
    
    int n, m;
    char str[N];
    vector<int> a, b;
    struct node {
        char a[N], b[N];
    } ans[100];
    int tot;
    bool cmp(node x, node y)
    {
        if (strlen(x.a) == strlen(y.a))
            return strcmp(x.a, y.a) < 0;
        return strlen(x.a) < strlen(y.a);
    }
    
    void getb(int pos)
    {
        if(b[0]==0)
            return;
        int len = strlen(str + 1);
        for (int i = 1; i < n; i++) {
            vector<int> temp;
            for (int j = 0; j < m; j++) {
                if (pos > len) {
                    return;
                }
                int now = str[pos] - '0';
                if (b[j] == 0) {
                    if (now)
                        return;
                    ++pos;
                } else {
                    if (now % b[j] == 0 && now / b[j] < 10) {
                        temp.pb(now / b[j]);
                        ++pos;
                    } else {
                        if (pos == len)
                            return;
                        now = now * 10 + str[pos + 1] - '0';
                        if (now % b[j] == 0 && now / b[j] < 10) {
                            temp.pb(now / b[j]);
                            pos += 2;
                        } else
                            return;
                    }
                }
            }
            sort(temp.begin(), temp.end());
            temp.erase(unique(temp.begin(), temp.end()), temp.end());
            if (temp.size() == 0)
                temp.pb(0);
            if (temp.size() == 1) {
                a.pb(temp[0]);
            } else {
                return;
            }
        }
        if (pos != len + 1||a.size()!=n)
            return;
        tot++;
        for(int i=0;i<n;i++){
            ans[tot].a[i] = a[i] + '0';
        }
        ans[tot].a[n] = '';
        for (int i = 0; i < m;i++){
            ans[tot].b[i] = b[i] + '0';
        }
        ans[tot].b[m] = '';
    }
    
    void enumer()
    {
        for (int i = 1; i < 10; i++) {
            a.clear(), b.clear();
            a.pb(i);
            int pos = 1;
            for (int j = 1; j <= m; j++) {
                int now = str[pos] - '0';
                if (now % i == 0 && now / i < 10) {
                    b.pb(now / i);
                    pos += 1;
                } else {
                    now = now * 10 + str[pos + 1] - '0';
                    if (now % i == 0 && now / i < 10) {
                        b.pb(now / i);
                        pos += 2;
                    } else {
                        break;
                    }
                }
            }
            if (b.size() == m) {
                getb(pos);
            }
        }
    }
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while (T--) {
            tot = 0;
            scanf("%d%d%s", &n, &m, str + 1);
            enumer();
            if(tot==0){
                printf("Impossible
    ");
            }else{
                sort(ans + 1, ans + 1 + tot, cmp);
                printf("%s %s
    ", ans[1].a, ans[1].b);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    MySQL动态游标
    扩展JS Date对象时间格式化功能
    Spring+ibatis动态管理数据源
    Spring在web应用中获得Bean的方法
    访问iis时需要输入服务器用户名密码
    sql08 语句修改标识列数据
    在浏览器选项卡上面追加网站Logo图
    'WebForm_PostBackOptions' 未定义 webForm_PostBackOptions is undefined
    pylot是一款开源的web性能测试工具
    在RedHat上安装gcc,java 和 eclipse-rcp
  • 原文地址:https://www.cnblogs.com/valk3/p/13803565.html
Copyright © 2011-2022 走看看