本文分享的必刷题目是从蓝桥云课、洛谷、AcWing等知名刷题平台精心挑选而来,并结合各平台提供的算法标签和难度等级进行了系统分类。题目涵盖了从基础到进阶的多种算法和数据结构,旨在为不同阶段的编程学习者提供一条清晰、平稳的学习提升路径。
欢迎大家订阅我的专栏:算法题解:C++与Python实现!
附上汇总贴:算法竞赛备考冲刺必刷题(C++) | 汇总
【题目来源】
学而思编程:乘积最大
【题目描述】
有一个正整数n nn,将n nn的每一位数码拆开,分成3 33组,将每组内的数重新排列成3 33个新的正整数。(可以不按原数的顺序排列)
这3 33个新的正整数的乘积最大可能是多少?
【输入】
1 11个正整数n nn。
【输出】
输出最大乘积。
【输入样例】
123456【输出样例】
136396【解题思路】
【算法标签】
#贪心
【代码详解】
#include<bits/stdc++.h>usingnamespacestd;inta[20],n;// 存储数字的每一位intcnt,b[20],zero=1;// zero: 记录末尾0的个数longlongnum;// 输入的数字vector<int>v[5];// 三个数字的每一位,v[1],v[2],v[3]存储三个数intmain(){cin>>num;// 输入数字// 将数字分解为每一位while(num){a[++n]=num%10;// 从低位到高位存储num/=10;}// 从大到小排序sort(a+1,a+1+n,greater<int>());// 将数字分配到三个数中(循环分配)for(inti=1;i<=n;i++){v[(i-1)%3+1].push_back(a[i]);// 循环分配到v[1],v[2],v[3]}// 处理长度不是3的倍数的情况if(n%3==2){// 长度除以3余2v[3].push_back(0);// 第三个数补0zero=10;// 记录有一个末尾0}if(n%3==1){// 长度除以3余1v[2].push_back(0);// 第二个数补0v[3].push_back(0);// 第三个数补0zero=100;// 记录有两个末尾0}boolf=0;// 标记是否需要调整boolf1=0;// 标记第一个数的最高位是否需要调整// 检查第一个数的最高位和第三个数的最高位是否相等if(v[1][0]==v[3][0])f1=0;// 相等,不需要调整elsef1=1;// 不相等,可能需要调整// 处理:让第一个最大的数尽可能小for(inti=1;i<v[3].size();i++){// 检查前一位是否已经不同if(v[1][i-1]!=v[2][i-1]){f=1;// 已经不同}// 如果当前位v[1]和v[3]相等,继续if(v[1][i]==v[3][i]){continue;}else{if(f1==0){// 如果最高位相等f1=1;// 标记已处理continue;}else{swap(v[1][i],v[3][i]);// 交换,让v[1]更小}}// 如果前一位相等且当前位不同,交换v[1]和v[2]if(v[1][i-1]==v[2][i-1]&&v[1][i]!=v[2][i]&&f==0){swap(v[1][i],v[2][i]);f=1;}}intt=-1;// 标记哪个数更大:2表示v[2]大,3表示v[3]大// 让后两个数的差值尽可能小for(inti=1;i<v[3].size();i++){if(t==-1){// 第一次确定大小关系if(v[2][i-1]<v[3][i-1]){t=3;// v[3]更大}elseif(v[2][i-1]>v[3][i-1]){t=2;// v[2]更大}}if(t!=-1){// 已经确定大小关系// 如果v[3]更大但当前位v[3]>v[2],交换让v[2]变大if(t==3&&v[3][i]>v[2][i])swap(v[3][i],v[2][i]);// 如果v[2]更大但当前位v[3]<v[2],交换让v[3]变大elseif(t==2&&v[3][i]<v[2][i])swap(v[3][i],v[2][i]);}}longlongx[5]={0},res=1;// 计算三个数for(inti=1;i<=3;i++){for(intj=0;j<v[i].size();j++){x[i]=x[i]*10+v[i][j];// 构造数字}res*=x[i];// 计算乘积}cout<<res/zero;// 除以补0的影响return0;}【运行结果】
123456 136396