**算法入门经典 第二版 循环的应用和注意点**
1.今天学习了循环章节在第二版;
循环无非就是3种情况;
a.for 用来一定次数的循环;
b.do while用来提前先做一个,再不知道要循环几次的循环;
c.while 用来没有固定循环;
2.朴素的循环:
水仙花数;
每次循环直接判断就好没什么技巧;
#include <iostream>
using namespace std;
bool f(int n)
{
int a,b,c;
a=n/100;
b=n%100/10;
c=n%10;
if(n==a*a*a+b*b*b+c*c*c) return true;
else return false;
}
int main()
{
for(int i=100;i<=999;++i)
{
if(f(i)) cout<<i<<endl;
}
}
技巧总结:
取最后x个数;对100取余,保留最后2位(100有2个0);
对10取余,保留最后1位(一个0)保留最后x位,对10000…(x个0);
取x位:除以100(x个0)
韩信点兵:
直接循环符合条件然后输出:
#include <iostream>
using namespace std;
int main()
{
int a,b,c,flag;
while(cin>>a>>b>>c)
{
flag=0;//一开始先假设没有这样的一个数;
for(int i=10;i<=100;++i)
{
if(i%3==a&&i%5==b&&i%7==c)//如果符合条件就输出,把标记flag设置为1表示找到了这样的数;
{
cout<<i<<endl;
flag=1;
break;
}
}
if(flag==0)//如果没有这样的一个数就输出“no answer”
{
cout<<"No answer";
}
}
}
技巧:
1.利用flag表示是否符合题意,flag到后面有许多技巧
记得关注;
记得关注;
记得关注;
3.关于一堆数组的连续加和,如何减少一层循环
阶乘之和;
普通写法:
#include <iostream>
using namespace std;
int main()
{
int n,t=1,sum=0,j;
cin>>n;
for(int i=1;i<=n;++i)
{
int t=1;
for(j=1;j<=i;++j)
{
t*=j;
}
sum+=t;
}
cout<<sum%1000000;
}
这里是2层循环所以复杂度是n*n;我们发现每次加上的数都是前一个乘上一个加一的数字,所以我们可以用一个变量来记录减少一个循环
#include <iostream>
using namespace std;
int main()
{
int n,t=1,sum=0;
cin>>n;
for(int i=1;i<=n;++i)
{
t*=i;//利用这个变量这是上一次的t乘以一个i,i自动++,所以自动乘上去;
sum+=t;
}
cout<<sum%1000000;
}
当然这个地方有bug,我们要注意大数的乘的时候会乘法溢出
循环时候出现乘法要注意,大数相乘是否会溢出
循环时候出现乘法要注意,大数相乘是否会溢出
循环时候出现乘法要注意,大数相乘是否会溢出
子序列的和;
输入两个正整数n<m;
输入1/(nn)加到1/(mm);
#include <iostream>
using namespace std;
int main()
{
int n,m;
double sum=0;
while(cin>>n>>m)
{
sum=0;
for(int i=n;i<=m;++i)
{
sum=sum+(1.0/i)/i;
}cout<<sum<<endl;
}
}
这里有个写法1/i/i;想想为什么不写成( i i);
因为大数的时候(ii)会溢出这就是技巧
这里给我一个提示,大数乘法是要注意是否会溢出
**每当我们遇到大数乘法的时候就要注意是否会溢出尽可能换个方向来看
4.模拟的循环小数
输入a,b,c输出a/b 保留c位小数;
直接用循环模拟小学我们学的取余数,乘以十,除除数就好了,一定要最后一次多判断一下下一位,如果下一位大于5就要进位;
#include <iostream>
using namespace std;
int main()
{
int a,b,c;
while(cin>>a>>b>>c)
{
int k=0;
if(a==0&&b==0&&c==0) break;
cout<<a/b<<".";//
while(k<c-1)
{
a%=b;
a*=10;
cout<<a/b;
k++;
}
a%=b;
a*=10;
if(a/b>5) cout<<a/b+1;
else cout<<a/b;
}
}