首页 > 其他分享 >洛谷题单指南-模拟和高精度-P1249 最大乘积

洛谷题单指南-模拟和高精度-P1249 最大乘积

时间:2024-01-24 18:01:24浏览次数:30  
标签:乘积 idx nums int 洛谷题 因子 拆分 P1249

原题链接:https://www.luogu.com.cn/problem/P1249

题意解读:

题目分两步,第一步是将整数拆分成不同自然数的和,第二步通过高精度计算这些因数的乘积,要使乘积最大,需要某种贪心思想。

解题思路:

如何保证整数拆分后因子的乘积最大呢,有几个原则:

1、最好不要包括因子1,但3、4除外,需要进行特殊处理

2、从2开始,连续拆分整数,依次拆分出2、3、4......直到和大于给定整数n

3、这时之前已经拆分出的数为a1、a2......ax,a1+a2+...+ax <= n

4、这时还剩余 r = n - (a1+a2+...+ax) 未分配

5、可以证明,将r平均的分配给a1、a2......ax,会使得乘积最大,因此依次给各个数加1,r减1,直到r为0

6、由于a1、a2......ax是递增的,不能从头开始分,可能会导致重复,因此从后开始分,可以使结果最大

举例:

n = 8,依次拆分2、3,

到4时2+3+4>8,4不能分,

剩余8 -(2+3)= 3,

给3加1得4,给2加1得3,现在拆分得到3、4,

还剩1,分给4,得到3、5。

如何存储拆分出来的因子,还能保证顺序呢?借助于桶数组可以很容易解决。

因子拆分出来之后,再进行高精度*低精度计算乘积即可。

分析完毕。

100分代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 10005;

int n;
int nums[N]; // nums[i] = 1表示i是n的一个因子
int idx; //最大的因子

vector<int> mul(vector<int> &a, int b)
{
    vector<int> result;
    int t = 0;
    for(int i = 0; i < a.size(); i++)
    {
        t += a[i] * b;
        result.push_back(t % 10);
        t /= 10;
    }
    while(t)
    {
        result.push_back(t % 10);
        t /= 10;
    }

    return result;
}

int main()
{
    cin >> n;

    if(n == 3 || n == 4)
    {
        cout << 1 << " " << n - 1 << endl;
        cout << 1 * (n - 1);
        return 0;
    }

    int sum = 0;
    for(int i = 2; i < n; i++)
    {
        if(sum + i > n) //如果sum + i超过n
        {
            int r = n - sum; //计算超出的部分,可以分给其他的因子
            while(r) //分配原则是由大到小,每个因子分1,重复进行,直到分完,可以保证乘积最大
            {
                for(int j = idx; j >= 2; j--) 
                {
                    if(nums[j] && r) 
                    {
                        nums[j] = 0, nums[j + 1] = 1; //给i加1的操作
                        if(j == idx) idx++;
                        r--;
                    }
                    else break;
                }
            }
            break;
        }
        sum += i;
        nums[i] = 1;
        idx = i;
    }

    vector<int> res;
    res.push_back(idx);

    for(int i = 2; i < idx; i++)
    {
        if(nums[i]) res = mul(res, i);
    }

    for(int i = 0; i <= idx; i++) 
        if(nums[i]) cout << i << " ";
    cout << endl;
    for(int i = res.size() - 1; i >= 0; i--) 
        cout << res[i];

    return 0;
}

 

标签:乘积,idx,nums,int,洛谷题,因子,拆分,P1249
From: https://www.cnblogs.com/jcwy/p/17985414

相关文章

  • 洛谷题单指南-模拟和高精度-P1591 阶乘数码
    原题链接:https://www.luogu.com.cn/problem/P1591题意解读:此题核心就是通过高精度*低精度计算阶乘,然后统计数码个数即可,直接给出代码。100分代码:#include<bits/stdc++.h>usingnamespacestd;vector<int>mul(vector<int>&a,intb){vector<int>result;intt......
  • 洛谷题单指南-模拟和高精度-P1786 帮贡排序
    原题链接:https://www.luogu.com.cn/problem/P1786题意解读:此题比较简单,模拟+排序即可解决。需要注意的是,当帮贡或者等级相同时,都要保持原来的顺序,因此需要记录每个人的编号,便于排序。话不多说,直接上代码。100分代码:#include<bits/stdc++.h>usingnamespacestd;constint......
  • 238.除自身以外数组的乘积
    1.题目介绍给你一个整数数组nums,返回数组answer,其中answer[i]等于nums中除nums[i]之外其余各元素的乘积。题目数据保证数组nums之中任意元素的全部前缀元素和后缀的乘积都在32位整数范围内。请不要使用除法,且在O(n)时间复杂度内完成此题。示例1:输入:nu......
  • 洛谷题单指南-模拟和高精度-P1098 [NOIP2007 提高组] 字符串的展开
    原题链接:https://www.luogu.com.cn/problem/P1098题意解读:题目本身是一道模拟题,但是细节点较多,要拿100分,有以下注意点:1、-号两个需要同时为小写字母或者数字,才进行填充2、-号左边>=右边,直接输出-3、对待填充的内容的处理,可以先看是否填充*;小写字母和数字的填充都是前一位asci......
  • 洛谷题单指南-模拟和高精度-P1067 [NOIP2009 普及组] 多项式输出
    原题链接:https://www.luogu.com.cn/problem/P1067题意解读:模拟法依次输出多项式内容即可,但是需要考虑的周全,主要有以下关键点:1、系数为0时不输出多项式2、第一个符号,只有负号才输出3、次数不为0时,不输出为1的系数;次数为0时,输出所有系数4、次数为1时,不输出次数;次数为0时不输......
  • 洛谷题单指南-模拟和高精度-P1518 [USACO2.4] 两只塔姆沃斯牛 The Tamworth Two
    原题链接:https://www.luogu.com.cn/problem/solution/P1518题意解读:此题是一道模拟题,关键要解决几个问题:1、如何转换方向2、如何在地图中移动3、如何判断无法抓住牛。解题思路:定义chara[10][10]用于存储地图,cx,cy和fx,fy分别代表牛、Farmer所在的位置,cdir、fdir分别代表牛......
  • 洛谷题单指南-模拟和高精度-P1328 [NOIP2014 提高组] 生活大爆炸版石头剪刀布
    原题链接:https://www.luogu.com.cn/problem/P1328题意解读:非常简单的一道题,核心考点就是循环数组以及评分规则的构建。评分规则:甲vs乙,1表示甲赢,-1表示甲输,-0表示平转化为数组:intrule[5][5]={0,-1,1,1,-1,1,0,-1,1,-1,-1,1,0,-1,1,-1,......
  • 洛谷题单指南-模拟和高精度-P4924 [1007] 魔法少女小Scarlet
    原题链接:https://www.luogu.com.cn/problem/P4924题意解读:根据题意,通过模拟法,枚举每一个要旋转的矩阵,执行旋转操作即可,关键点在于如何进行矩阵旋转。设定矩阵inta[][],临时矩阵intt[][]用于保存旋转后的矩阵,矩阵长度为len。先考虑要旋转的区域左上角是a[0][0]的情况,区域内每......
  • 洛谷题单指南-模拟和高精度-P1601 A+B Problem
    原题链接:https://www.luogu.com.cn/problem/P1601题意解读:本题是高精度加法的模版题。知识点解析:  高精度加法:  如果一个数大到远超过整形变量的范围时,就不能使用int、long、longlong等变量来存储整数,也不能直接通过变量加法来求和。  因此,需要回到加法计算的本质,从个......
  • 洛谷题单指南-模拟和高精度-P1563 [NOIP2016 提高组] 玩具谜题
    原题链接:https://www.luogu.com.cn/problem/P1563题意解读:本题关键在于根据小人的朝向和寻找的方向来确定数组下标的变化。用数组存储小人,intd[]存朝向,inta[]存名称,朝向和寻找方向有4种组合:朝向(0:向内,1:向外)  寻找方向(0:左,1:右)  数组下标操作00顺时针寻找,下标递减......