1.粘木棍
问题描述
有N根木棍,需要将其粘贴成M个长木棍,使得最长的和最短的的差距最小。
输入格式
第一行两个整数N,M。
一行N个整数,表示木棍的长度。输出格式
一行一个整数,表示最小的差距
样例输入
3 2
10 20 40
解题思路:深搜,m个类别,每个木棍可以有m种选择,放或者不放,搜索所有情况,判断条件为每一种类别都有木棍,再求其max和min值,求差值与ans比较,反正这样写很简单,优化还没有考虑,就挑最省事的写。
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int N = 1e2+10;
const int INF = 0x3f3f3f3f;
int n,m,a[N],ans=1e4;
vector<int> DP[N];
void dfs(int index) //index为当前选择到第几个木棍
{
if(index>=n)
{
int minV=INF,maxV=-INF;
for(int i=0;i<m;i++) //判断每个类别都有木棍
{
if(DP[i].size()==0)
return;
}
vector<int> res;
for(int i=0;i<m;i++)
{
int sum=0;
for(int j=0;j<DP[i].size();j++) //每个类别求和即长度
sum+=DP[i][j];
res.push_back(sum);
}
for(int i=0;i<res.size();i++)
{
if(res[i]>maxV)
maxV=res[i];
if(res[i]<minV)
minV=res[i];
}
if(maxV-minV<ans) //更新最值
ans=maxV-minV;
return;
}
for(int i=0;i<m;i++) //每个木棍可以有m种选择
{
DP[i].push_back(a[index]);
dfs(index+1);
DP[i].pop_back();
}
}
int main() {
cin>>n>>m;
for(int i=0;i<n;i++)
cin>>a[i];
dfs(0);
cout<<ans;
return 0;
}
2.连续因子
题目链接:题目详情 - L1-006 连续因子 (20 分) (pintia.cn)
一个正整数 N 的因子中可能存在若干连续的数字。例如 630 可以分解为 3×5×6×7,其中 5、6、7 就是 3 个连续的数字。给定任一正整数 N,要求编写程序求出最长连续因子的个数,并输出最小的连续因子序列。
输入格式:
输入在一行中给出一个正整数 N(1<N<231)。
输出格式:
首先在第 1 行输出最长连续因子的个数;然后在第 2 行中按
因子1*因子2*……*因子k
的格式输出最小的连续因子序列,其中因子按递增顺序输出,1 不算在内。输入样例:
630
输出样例:
3 5*6*7
解题思路:暴力搜索,考场能暴力出结果咱就别动脑了。首先判断该数是不是质数,是的话可以结束了;否则,搜索其所有可能的因子,并对每一个因子连续求累积直到不满足break,记录连续的因子个数并比较更新。
#include<bits/stdc++.h>
using namespace std;
const int MAX = 1e2;
vector<int> a;
bool prime(int n) //返回false说明不是素数 true说明是素数
{
bool flag = false;
for(int i=2;i<=sqrt(n);i++)
{
if(n%i==0)
return false;
}
return true;
}
int main()
{
int n;
cin>>n;
if(prime(n))
{
cout<<1<<endl;
cout<<n;
return 0;
}
int x=n,ans=1,start;
for(int i=2;i<=x/i;i++) //遍历 该数所有可能的因子
{
int j=i;
int sum=1;
for(j;j<=n;j++) //以j开头的所有连续因子
{
sum*=j; //累乘
if(n%sum==0&&sum<=n) continue; //如果累乘得到的积还能被sum整除 则继续 反之截断
else break;
}
if(j-i>ans) //求i到j的连续因子个数
{
ans=j-i;
start=i;
}
}
cout<<ans<<endl;
x=ans;
while(x) //输出结果
{
if(x==ans)
cout<<start;
else
cout<<"*"<<start;
start++;
x--;
}
}