zhangjinxuan 发表于 2023-1-24 14:07:40

【C++板块提升计划】梦想护卫舰 第12期 破译密码

本帖最后由 zhangjinxuan 于 2023-1-25 20:14 编辑


上一关:数楼梯
梦想护卫舰 第12期 破译密码

你们走过了楼梯,来到了神庙大门,这门需要密码……

密码门上只有两串数字,而地上有一串文字:

这两串数字位数是相同的,一个是 A, 一个是 B, 有 n 位,1 <= n <= 200000,也是一个合法的十进制数字
现在你可以执行多次这个操作(或者不操作):
选择一个数字 i ,1 <= i <= n,将 A 从左往右数的第 i 位 与 B 从左往右数的第 i 位交换
A * B 得到的最小值就是密码
但这个数可能很大,所以你还要对 998244353 取余
注意:我们要找的是 A * B 的最小值,请不要最小化余数

输入格式
三行,第一行一个整数 n,第二行是 A,第三行是 B

输出格式
一个整数,表示最小值

输入样例1
2
13
22


输出样例1
276

样例解释1
交换个位(i = 1),A = 12, B = 23, 12 * 23 = 276,这是最小值了,不可能找到更小的

输入样例2
8
20220122
21002300


输出样例2
54558365

样例解释2
交换个位(i = 1),十位 (i = 2),万位 (i = 5),十万位(i = 6),A = 20000100, B = 21222322,A * B 998244353 = 54558365

注意:该题非原创,来自 ARC154,链接在这里

static/image/hrline/1.gif

答案与解析
**** Hidden Message *****

最佳战士
名字:ba21
奖励:最佳答案+5鱼币5荣誉
其他说明:使用语言为python

static/image/hrline/1.gif

**** Hidden Message *****

下一关: 细胞分裂

ba21 发表于 2023-1-24 17:28:21

本帖最后由 ba21 于 2023-1-24 17:32 编辑

弄了个python,结果又是C了。我以为你只搞python呢。算了,不搞了
原理就是把2个数中每一位的最小数挑出来交换。得到的乘积最小。

zhangjinxuan 发表于 2023-1-24 18:00:59

ba21 发表于 2023-1-24 17:28
弄了个python,结果又是C了。我以为你只搞python呢。算了,不搞了
原理就是把2个数中每一位的最小数挑出来 ...

python也行

ba21 发表于 2023-1-24 18:05:37

zhangjinxuan 发表于 2023-1-24 18:00
python也行

python 支持大数相乘,这题用python没意义了。

zhangjinxuan 发表于 2023-1-24 20:21:00

ba21 发表于 2023-1-24 18:05
python 支持大数相乘,这题用python没意义了。

重点是思路,毕竟,python 的大数相乘也比较慢{:10_284:}

ba21 发表于 2023-1-24 21:11:01

本帖最后由 ba21 于 2023-1-24 21:12 编辑

zhangjinxuan 发表于 2023-1-24 20:21
重点是思路,毕竟,python 的大数相乘也比较慢

python 的大数相乘使用的是(算法)所以还真不慢。

闲着用弄弄,重在参与:
C代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void getNewNumber(char *a, char *b);
char *MultipyBigNumber(char *a, char *b);
long long mod(char *divisor, long long number);
void swap(char *a, char *b, int i);

int main()
{
    char a[] = "51562165415643212316";
    char b[] = "52213412312166548821";
    int number = 998244353;

    getNewNumber(a, b);

    printf("%lld\n", mod(MultipyBigNumber(a,b), number));


    return 0;
}

// 获取最小乘积所需要的被乘数和乘数
void getNewNumber(char *a, char *b)
{
    int i;
    for (i = 0; i < strlen(a); i++)
    {
      if (a > b)
      {
            swap(a, b, i);
      }
    }
}

// 大数相乘
char *MultipyBigNumber(char *a, char *b)
{
        int i, j, x, bitLeft, bitRight;
        int lenA = strlen(a);
        int lenB = strlen(b);
        int len = lenA + lenB;
        char *arr;
        arr = (char*)malloc(sizeof(char)*(len+1));
        arr = '\0';
        arr = &arr;

        lenA--;
        lenB--;
        i = x = 0;
        while(i < len - 1 || x != 0)
        {
                for(j = 0; j <= i; j++)
                {
                        bitLeft = lenA - i + j;
                        bitRight = lenB - j;
                        if(bitLeft >= 0 && bitRight >= 0)
            {
                x += (a - '0') * (b - '0');
                        }

                }
                *(--arr) = x % 10 + '0';
                x /= 10;
                i++;
        }

        if(*arr++ == '0')
    {
      *arr = '\0';
    }

        return --arr;
}

// 求余数
long long mod(char *divisor, long long number)
{
    long long m=0;
    for(int i=0; i<strlen(divisor); i++){
      m = (m*10+(divisor-'0'))%number;
    }

    return m;
}

// 交换
void swap(char *a, char *b, int i)
{
    a = a^b;
    b = a^b;
    a = a^b;
}



python代码
import random

def getNum(n):
    s = ''
    for i in range(n):
      s+=str(random.randint(0, 9))
    return s

n = 200000
a = getNum(n)
b = getNum(n)


lstA = list(a)
lstB = list(b)
for i in range(n):   
    if lstA > lstB:
      lstA, lstB = lstB, lstA

newA = int(''.join(lstA))
newB = int(''.join(lstB))

print(newA * newB % 998244353)

zhangjinxuan 发表于 2023-1-24 21:14:45

ba21 发表于 2023-1-24 21:11
python 的大数相乘使用的是(算法)所以还真不慢。

闲着用弄弄,重在参与:


C的代码效率有待优化{:10_282:}

Python的代码过了,恭喜{:10_256:}

zhangjinxuan 发表于 2023-1-24 21:17:31

ba21 发表于 2023-1-24 21:11
python 的大数相乘使用的是(算法)所以还真不慢。

闲着用弄弄,重在参与:


我看了看你的代码,其实上,根本就不需要大数相乘,你可以看看题解{:10_282:}

ba21 发表于 2023-1-24 22:04:17

zhangjinxuan 发表于 2023-1-24 21:17
我看了看你的代码,其实上,根本就不需要大数相乘,你可以看看题解

你的代码不全。
使用你的代码代入数字,结果并不正确。

zhangjinxuan 发表于 2023-1-24 22:18:20

ba21 发表于 2023-1-24 22:04
你的代码不全。
使用你的代码代入数字,结果并不正确。

嗯?要输入三个数字哦?第一行的数是位数,第二行是 A,第三行是 B

这是在做题

ba21 发表于 2023-1-24 22:21:38

zhangjinxuan 发表于 2023-1-24 22:18
嗯?要输入三个数字哦?第一行的数是位数,第二行是 A,第三行是 B

这是在做题

是的,不正确。
麻烦你介绍下你代码的思路。

人造人 发表于 2023-1-24 23:19:52

zhangjinxuan 发表于 2023-1-24 20:21
重点是思路,毕竟,python 的大数相乘也比较慢

我C语言也可以使用mpfr这个库实现大数运算,^_^
https://fishc.com.cn/forum.php?mod=redirect&goto=findpost&ptid=204663&pid=5618893

#include <stdio.h>
#include <mpfr.h>

int main(void) {
    mpfr_t a, b, c;
    mpfr_inits2(10000000, a, b, c, NULL);
    mpfr_set_str(a, "10", 10, MPFR_RNDD);
    mpfr_set_str(b, "1000000", 10, MPFR_RNDD);
    mpfr_pow(c, a, b, MPFR_RNDD);
    mpfr_printf("%.0Rf\n", c);
    mpfr_clears(a, b, c, NULL);
    mpfr_free_cache();
    return 0;
}

zhangjinxuan 发表于 2023-1-25 09:21:49

人造人 发表于 2023-1-24 23:19
我C语言也可以使用mpfr这个库实现大数运算,^_^
https://fishc.com.cn/forum.php?mod=redirect&goto=fin ...

哈哈{:10_256:}

zhangjinxuan 发表于 2023-1-25 09:22:50

ba21 发表于 2023-1-24 22:21
是的,不正确。
麻烦你介绍下你代码的思路。

就是要不全,防止有些人直接抄答案

zhangjinxuan 发表于 2023-1-25 09:23:23

ba21 发表于 2023-1-24 22:21
是的,不正确。
麻烦你介绍下你代码的思路。

这个是对的吧:
#include <bits/stdc++.h>
using namespace std;

char a, b;
int n;
long long ans = 0, p = 998244353;

long long eval_ans() {
        long long x = 1, avalue = 0, bvalue = 0;
        for (int i = n; i >= 1; --i) {
                long long ap = (long long)(a - '0') * x;
                long long bp = (long long)(b - '0') * x;
                ap %= p;
                bp %= p;
                avalue += ap;
                bvalue += bp;
                avalue %= p;
                bvalue %= p;
                x *= 10;
                x %= p;
        }
        return avalue * bvalue % p;
}

int main() {
        scanf("%d%s%s", &n, a + 1, b + 1);
        for (int i = 1; i <= n; ++i) {
                if (a > b) {
                        swap(a, b);
                }
        }
        printf("%lld", eval_ans());
        return 0;
}

ba21 发表于 2023-1-25 17:12:55

zhangjinxuan 发表于 2023-1-25 09:23
这个是对的吧:

对的,结果是你代码中数组的利用过了0

zhangjinxuan 发表于 2023-1-25 19:37:15

ba21 发表于 2023-1-25 17:12
对的,结果是你代码中数组的利用过了0

我是 1 ~ base {:10_284:}

元豪 发表于 2023-2-3 14:07:57

{:10_254:}
页: [1]
查看完整版本: 【C++板块提升计划】梦想护卫舰 第12期 破译密码