题目:排列硬币
内容描述:总共有n枚硬币,将它们摆成一个阶梯形状,第k行就必须正好有k枚硬币。
给定一个数字n,找出可形成完整阶梯行的总行数。n是一个非负整数,并且在32位有符号整型的范围内。
算法:
1.暴力算法
2.二分算法
3.牛顿迭代求平方根算法
算法思想:
1.暴力算法:(传入硬币数 n )
1.来个循环从 1 开始 到 n 结束
2.循环里面我们就 减去那个数,n=n-i ;
3.直到 n==0; 返回i 或者 n<0 ,返回 i -1 (结束循环)
2.二分算法 (传入硬币数 n )
1 +2 +3 +4 +5 +6 等差数列 求和 ---》 公式 : S =n * a1 + n*(n-1 )/2 = n*( 1 + n)/2;
所以构建第 n 个台阶所需要的硬币数量为 n * (1+ n)/2;
1.首先命令两个变量,一个低的 low =0 , 一个高的 high = n , 代表台阶数
2.我们要建造一个while 循环 循环的条件为 low<=high
3.我们的里面定义一个变量,首先是mid 是一个中间值,中间的台阶是啥 ,
4. mid= low + (low+high)/2 ,mid的位置
5. 当mid 位置所用的硬币数量 大于 n 的时候 (mid*(mid+1)/2 > n )-->high--
6. 当mid 位置所用的硬币数量 小于 n 的时候 (mid*(mid+1)/2 > n )-->low ++
7.当我们mid 所用的硬币数量正好等于 n 的时候,返回 mid.'
8.while 循环没有找到,mid 所用的硬币数量正好等于 n (mid*(mid+1)/2 == n) 结束循环,返回high,低的这个数,因为这时候,low>high .
3.牛顿迭代求平方根算法 (传入硬币数 n )
1.开始的时候我们说过这个计算公式: (阶梯数 k)
推导: k*(k-1)/2 =n ;
k*k -k =2n
k*k =2n-k;
k= sqrt(2n-k);//sqrt 开根号
2.所以我i们开始写算法 牛顿迭代的算法:
牛顿迭代的思想: 1. x*x =n
2. x=n/x; (递归,之前的求平方根 有这个算法)
3. (x+ n/x)/2==x 的时候 就证明 x 的值找到了。
4. 所以我们利用这个思想 来是求 上面的值 k.
5. (k + (2n-k)/k )/2= k 的时候,k 的值就出来了。
代码:
/*************************************************
作者:She001
时间:2022/8/27
题目:排列硬币
内容描述:总共有n枚硬币,将它们摆成一个阶梯形状,第k行就必须正好有k枚硬币。
给定一个数字n,找出可形成完整阶梯行的总行数。n是一个非负整数,并且在32位有符号整型的范围内。
***************************************************/
#include<iostream>
#include<map>
using namespace std;
/*
算法:
1.暴力算法
2.二分算法
3.牛顿迭代求平方根算法
*/
/*
算法思想:
1.暴力算法:(传入硬币数 n )
1.来个循环从 1 开始 到 n 结束
2.循环里面我们就 减去那个数,n=n-i ;
3.直到 n==0; 返回i 或者 n<0 ,返回 i -1 (结束循环)
*/
int fangfa_1(int n)
{
int m=n;
for(int i=1;i<n;i++)
{
//cout<<"m= "<<m<<endl;
m=m-i;
if(m==0)
{
return i;
}
else if(m<0)
{
return i-1;
}
}
}
/*
2.二分算法 (传入硬币数 n )
1 +2 +3 +4 +5 +6 等差数列 求和 ---》 公式 : S =n * a1 + n*(n-1 )/2 = n*( 1 + n)/2;
所以构建第 n 个台阶所需要的硬币数量为 n * (1+ n)/2;
1.首先命令两个变量,一个低的 low =0 , 一个高的 high = n , 代表台阶数
2.我们要建造一个while 循环 循环的条件为 low<=high
3.我们的里面定义一个变量,首先是mid 是一个中间值,中间的台阶是啥 ,
4. mid= low + (low+high)/2 ,mid的位置
5. 当mid 位置所用的硬币数量 大于 n 的时候 (mid*(mid+1)/2 > n )-->high--
6. 当mid 位置所用的硬币数量 小于 n 的时候 (mid*(mid+1)/2 > n )-->low ++
7.当我们mid 所用的硬币数量正好等于 n 的时候,返回 mid.'
8.while 循环没有找到,mid 所用的硬币数量正好等于 n (mid*(mid+1)/2 == n) 结束循环,返回high,低的这个数,因为这时候,low>high .
*/
int fangfa_2(int n)
{
int mid,sum;
int low=0;
int high=n;
while(low<=high)
{
mid=low +((high-low)/2);
sum =((mid*(mid+1)))/2;
//cout<<"sum= "<<sum<<endl;
//cout<<"low= "<<low<<endl;
//cout<<"high= "<<high<<endl;
if(sum==n)
{
return mid;
}
else if(sum>n)
{
high=mid-1;
}
else if(sum<n)
{
low=mid+1;
}
}
return high;//·µ»ØÐ¡µÄÄǸöÖµ
}
/*
3.牛顿迭代求平方根算法 (传入硬币数 n )
1.开始的时候我们说过这个计算公式: (阶梯数 k)
推导: k*(k-1)/2 =n ;
k*k -k =2n
k*k =2n-k;
k= sqrt(2n-k);//sqrt 开根号
2.所以我i们开始写算法 牛顿迭代的算法:
牛顿迭代的思想: 1. x*x =n
2. x=n/x; (递归,之前的求平方根 有这个算法)
3. (x+ n/x)/2==x 的时候 就证明 x 的值找到了。
4. 所以我们利用这个思想 来是求 上面的值 k.
5. (k + (2n-k)/k )/2= k 的时候,k 的值就出来了。
*/
double fangfa_3_1(double k,int n)
{
double res = (k+(2*n-k)/k)/2;
if(res==k)
{
return res;
}
if(res!=k)
{
fangfa_3_1(res ,n);
}
}
int fangfa_3(int n)
{
double a=fangfa_3_1(n,n);
return (int )a;
}
int main()
{
int a= fangfa_1(11);
int b= fangfa_2(11);
int c= fangfa_3(11);
cout<<a<<endl;
cout<<b<<endl;
cout<<c<<endl;
return 0;
}
本文详细介绍了三种不同的算法——暴力算法、二分算法及牛顿迭代求平方根算法,用于解决给定数量硬币时如何形成完整的阶梯形状问题。通过对比不同算法的特点,帮助读者理解并掌握每种算法的应用场景。

1358

被折叠的 条评论
为什么被折叠?



