poj1032~沉寂后回归的第一道水题
原创
©著作权归作者所有:来自51CTO博客作者breakDawn的原创作品,请联系作者获取转载授权,否则将追究法律责任
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">放弃了ACM,不再思考这个决定的正确与否,自己可能确实不适合竞赛,但是适合学习。</span>
所以继续坚持poj刷题的快感,而不是面对竞赛题目的无助。
题意:输入一个整数,把这个整数拆成多个不相等整数相加,使得这些整数的乘积最大,求这一串整数。
唉,还是很失落,不论是水题还是难题,都不能靠自己推出结论和思路,都要看别人的题解,实在很受挫。
结合别人的题解和自己事后思考,大致思路是这样的:
比如输入一个8,8明显拆成4和4乘积最大,
输入一个9,明显拆成4和5最大。5又能拆成2和3,变的更大
说明拆成的数字越多,而且他们贴近地越紧密,乘积越大。
例如26,程序对他的实现过程是这样的:
从2开始加,2+3+……一直变成2+3+4+5+6=20,26-20=6,说明接下来只能插入6,但是6不能重复,说明26最多只能拆成5个数字。
接下来就要解决剩下的那个6了。把6拆成6和1,从大到小依次加到那6个数字上,直到6个1用完。
用了5个1时,变成了3+4+5+6+7,还剩1个1,就加到7上面,于是变成了3+4+5+6+8,而这个就是答案。
#include<iostream>
#include<string>
#include<cmath>
#include<algorithm>
#define M 1005
using namespace std;
int a[M];
int main()
{
int i,n,sum,m,j;
cin>>n;
a[1]=sum=2;
m=1;
while(a[m]<n-sum) //当不能再插入数字时退出循环
{
m++;
a[m]=a[m-1]+1;
sum+=a[m];
}
j=m;
for(i=0;i<n-sum;i++) //从大到小依次加上n-sum个1
{
a[j]++;
j--;
if(j==0) j=m;
}
for(i=1;i<=m;i++)
{
cout<<a[i];
if(i!=m)
cout<<" ";
else cout<<endl;
}
return 0;
}
2016/2/22
重做水题
#include<stdio.h>
void main()
{
int n,m,sum,i,j,a[1001];
scanf("%d",&n);
sum=m=0;
i=2;
while(n-sum>=i)
{
sum+=i;
a[m]=i;
i++;
m++;
}
sum=n-sum;
while(sum!=0)
{
for(j=m-1;j>=0&&sum!=0;j--)
{
a[j]++;
sum--;
}
}
for(i=0;i<m;i++)
{
printf("%d",a[i]);
if(i!=m-1)
printf(" ");
}
printf("\n");
}