首页 > 其他分享 >最大乘积

最大乘积

时间:2023-08-18 17:57:19浏览次数:22  
标签:乘积 len2 int ++ len1 ans 最大 string

最大乘积

题目描述

一个正整数一般可以分为几个互不相同的自然数的和,如 \(3=1+2\),\(4=1+3\),\(5=1+4=2+3\),\(6=1+5=2+4\)。

现在你的任务是将指定的正整数 \(n\) 分解成若干个互不相同的自然数的和,且使这些自然数的乘积最大。

输入格式

只一个正整数 \(n\),(\(3 \leq n \leq 10000\))。

输出格式

第一行是分解方案,相邻的数之间用一个空格分开,并且按由小到大的顺序。

第二行是最大的乘积。

样例 #1

样例输入 #1

10

样例输出 #1

2 3 5
30

题解

思路

按照贪心的思路来说,尽量不要出现1才使得乘积最大,然后总和是n,就从2开始遍历,一直到分解不动的情况,会出现余数不等于0的情况。

把余数分到大的数上比分到小的数上得到的乘积更大

处理余数有两种情况

  1. 余数是加1到所有分解方案刚好或者足够
  2. 余数是加1到所有分解方案还有剩余,这样的情况直接所有剩余的加到分解方案最后的一个值上

最后就涉及到一个大数相乘的方法,把所有的分解结果依次相乘即可

code

#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define ppb pop_back
#define SZ(v) ((int)v.size())
#define pii pair<int, int>
typedef long long ll;
typedef unsigned int u32;
typedef unsigned long long u64;
typedef double db;
using namespace std;
const int N = 1e6+10;
int _;
int n;
int ans[N];
string s[N];
string res;
int len;

string f(string a) {
    for(int i = 0; i < SZ(a) / 2; i++) {
        swap(a[i], a[SZ(a)-i-1]);
    }
    return a;
}

string add(string a, string b) {
    int len1 = SZ(a), len2 = SZ(b);
    vector<int> c(max(len1, len2), 0), d(max(len1, len2), 0);
    for(int i = 0; i < len1; i++) c[i] = a[i] - '0';
    for(int i = 0; i < len2; i++) d[i] = b[i] - '0';
    int k = 0;
    string ans = "";
    for(int i = 0; i < max(len1, len2); i++) {
        int x = c[i] + d[i] + k;
        k = x / 10;
        ans += to_string(x%10);
    }
    if(k) ans += to_string(k);
    return ans;
}

string mul(string a, string b) {
    int len1 = SZ(a), len2 = SZ(b);
    vector<int> c(max(len1, len2), 0), d(max(len1, len2), 0);
    for(int i = 0; i < len1; i++) c[i] = a[i] - '0';
    for(int i = 0; i < len2; i++) d[i] = b[i] - '0';
    string ans = "";
    for(int i = 0; i < len1; i++) {
        string tmp = "";
        for(int j = 0; j < i; j++) tmp += "0";
        int k = 0;
        for(int j = 0; j < len2; j++) {
            int x = c[i] * d[j] + k;
            k = x / 10;
            tmp += to_string(x % 10);
        }
        if(k) tmp += to_string(k);
        ans = add(ans, tmp);
    }
    return ans;
}

void solve() {
    cin >> n;
    for(int i = 2; i <= n; i++) {
        if(i <= n) {
            ans[len] = i;
            s[len] = f(to_string(i));
            len++; 
            n -= i;
        }
    }
    for(int i = len - 1; i >= 0; i--) {
        if(n > 0) {
            ans[i] += 1;
            s[i] = f(to_string(ans[i]));
            n--;
        }
    }
    if(n > 0) {
        ans[len-1] += n;
        s[len-1] = f(to_string(ans[len-1]));
    }
    for(int i = 0; i < len; i++) {
        cout << ans[i] << " ";
    }
    res = s[0];
    for(int i = 1; i < len; i++) {
        res = mul(res, s[i]);
    }
    cout << "\n";
    for(int i = SZ(res) - 1; i >= 0; i--) {
        cout << res[i];
    }
    cout << "\n";
}   

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr); 
    _ = 1;
    // freopen('')
    // cin >> _;
    while(_--) {
        solve();
    }
    return 0;
}

标签:乘积,len2,int,++,len1,ans,最大,string
From: https://www.cnblogs.com/zhyyyyy115/p/17641187.html

相关文章

  • 「AWOI Round 2 A」最大和
    嘿嘿,来水题解了。题目链接。题目简化给你一个数,从它的个位到最高位进行操作,对于其每一位,你可以选择让他增加\(1\),减少\(1\)(如果当前位是\(0\),减\(1\)后会退位)或者不变。分析要使每一位的总和最大,我们可以对每一位进行判断。如果当前位不是\(0\)和\(9\),那么显然要......
  • 【学习笔记】简单数论-最大公约数
    一个整数\(N\)的约数上界为\(2\sqrt{N}\)。\(1\simN\)每个数的约数个数的总和大约为\(N\timeslogN\)。取模运算性质\((a+b)\bmodp=((a\bmodp)+(b\modp))\modp\),反之亦成立。\((a-b)\bmodp=((a\bmodp)-(b\modp))\modp\),反之亦成立。\((a\tim......
  • linux系统句柄限制调整,当使用netty/socket触发达到系统最大连接数时查看
    socket原理:客户端使用tcp端口连接至服务端,服务端会打开一个句柄文件和客户端保持连接,注意并不是一个连接就会占用一个服务器端口,所以socket连接数跟系统端口最大连接数无关,不然系统防火墙不就没啥用,默认系统每个进程打开的句柄是有限制的,另外整个系统还有一个句柄限制总数,所以soc......
  • 代码随想录算法训练营第十三天|单调数列:滑动窗口最大值(力扣239.)、优先级队列:前k个高
    单调数列:滑动窗口最大值(力扣239.)给定滑动窗口的范围,求每个滑动窗口范围内的最大值使用单调队列实现对于最大值数字前面的数字不存入数列,对于最大值数字后面的数字存入数列中单调队列中数字的大小呈递减顺序pop(value):如果窗口移除的元素等于单调队列的队口元素,则pop;否则什......
  • 单调栈(查找一个最大差值或查询某个位置左右两侧比他大(或小)的数的位置)
    leetcode121.买卖股票的最佳时机classSolution{public:intmaxProfit(vector<int>&prices){intans=0;vector<int>St;prices.emplace_back(-1);//为了结果的必然出现for(inti=0;i<prices.size();++i){......
  • 最大传输单元MTU和最大分段大小MSS
    参考:https://support.huawei.com/enterprise/zh/knowledge/EKB1000052671https://zhiliao.h3c.com/questions/dispcont/93066在PPPoE场景出现上网慢的情况时,首先检查设备当前的MTU以及TCP-MSS值。了解一些基本概念:1.MTU(MaxitumTransmissionUnit):最大传输单元。EthernetII帧的结......
  • LeetCode 7023操作使得分最大
    7023.操作使得分最大题目描述:一个数字的质数分数为其质因数个数;给定一个长度为\(n\)的正整数数组nums和正整数k,可以进行k次如下操作:选择一个之前没有选择过的非空子数组subnums从subnums中选择一个质数分数最大的元素x,如果多个元素质数分数相同且最大,选择下标最小的一个将得......
  • #yyds干货盘点# LeetCode程序员面试金典:数组中的第K个最大元素
    题目:给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例1:[3,2,1,5,6,4],示例 2:[3,2,3,1,2,4,5,5,6],代码实现:class......
  • 最大流模板
    需要注意的是要ll就全ll,不然要出事。structFlow{lltot=1,hd[N],ne[M],to[M],lim[M];voidAdd(intx,inty,llz){ne[++tot]=hd[x];hd[x]=tot;to[tot]=y;lim[tot]=z;ne[++tot]=hd[y];hd[y]=tot;to[tot]=x;lim[tot]=0;}llT,dis[......
  • 【专题】中国的技能转型:推动全球规模最大的劳动者队伍成为终身学习者报告PDF合集分享(
    学习能力是将知识资源转化为知识资本的能力。它包括对所学内容的兴趣和热情,有助于更深入理解和掌握知识,提高个人的认知和思维能力。阅读原文,获取专题报告合集全文,解锁文末158份学习教育行业相关报告。教育和娱乐支出越来越成为家庭消费的重要组成部分。这包括对18岁以下儿童的素质......