算法学习之循环结构程序设计
for循环
打印1,2,3,...,n每个占一行。
#include <conio.h> #include<stdio.h> int main(){ int i,n; scanf("%d",&n); for(i=1;i<=n;i++){ printf("%d\n",i); } getch(); return 0; }
分支结合循环,威力很强大
输出所有形如aabb的四位完全平方数。
分析:先全部列出来,然后开根,看是否为整数。其中a可以从1到9,
b可以从0到9。如何组成aabb呢?
a*1100+b*11即可。
伪代码可以开拓思路。
下面来实现它
#include <conio.h> #include<stdio.h> #include<math.h> int main(){ int a,b,n; double m; for(a=1;a<=9;a++){ for(b=0;b<=9;b++){ n = a*1100+b*11; m = sqrt(n); if((int)m == m){//判断是否为整数 printf("%d\n",n); } } } getch(); return 0; }
另一个思路是枚举平方根x,从而避免开平方操作。
#include <conio.h> #include<stdio.h> #include<math.h> int main(){ int x,n,high,low; for(x = 1;;x++){ n = x*x; if(n<1100) continue;//跳过本次循环 if(n>9999) break;//结束本次循环,这一句很重要 high = n / 100;//获取高位,技巧 low = n % 100;//获取低位,技巧啊,余下的不满足100的就是低位的数字 if(high/10 == high%10&&low/10 == low%10){//前两位相同,后两位相同,则满足条件 printf("%d\n",n); } } getch(); return 0; }
这个效率貌似不如第一个高!执行的时间比较久,如果没有终止操作,不知道要执行多久呢!
这个大概就是算法的复杂度吧!一定要有意识提高代码的效率!
3n+1问题
猜想:对于任意大于1的自然数n,若n为奇数,则将n变为3n+1,否则变为n的一般。经过若干次这样的变换,
一定会使n变为1。例如3->10->5->16->8->4->2->1。
输入n,输出变换的次数。n<=10的9次方。
样例输入:3
样例输出:7
分析:程序完成工作依然是重复性劳动,循环的次数是不确定的,而且n不是递增的循环。可以考虑用
while条件式的循环来实现。
#include <conio.h> #include<stdio.h> int main(){ int n,count = 0;//定义变量n,count并为count赋初值 scanf("%d",&n); while(n>1){//只要n不等于1,这里n>0的整数,也就是只要n大于1,就执行操作 if(n%2 == 1){//奇数 n = 3*n+1; }else{ n = n/2; } count++; } printf("%d\n",count);//不要忘记测试,一个看上去正确的程序可能隐含错误。 //断点输出是很好的排错方式 //printf("%d\n",n); getch(); return 0; }
for与while的关系
"
for(初始化;条件;调整){
循环体
}
"
等价于
"
初始化
while(条件)
{
循环体;
调整;
}
"
阶乘之和
输入n,计算S = 1!+2!+3!+...+n!的末6位(不含前导0)。n<=10的6次方。
样例输入:10
样例输出:37913(其实总和为4037913)
分析:如何实现阶乘呢?用一次循环呗。
#include <conio.h> #include<stdio.h> int main(){ int n,i,j,S=0; scanf("%d",&n); for(i=1;i<=n;i++){ int factorial = 1;//定义阶乘,每次循环都被重新赋初值 for(j=1;j<=i;j++){ factorial *= j; } S += factorial; } S = S%1000000;//有几个0就会剩下几位 //S = int(S); printf("%d\n",S); getch(); return 0; }
每步取模,加一个“计时器”,可以计算出时间复杂度。
输入一些整数,求出它们的最小值、最大值和平均值(保留3位小数)。输入保证这些数都是不超过1000的整数。
样例输入:2 8 3 5 1 7 3 6
样例输出:1 8 4.375
#include <conio.h> #include<stdio.h> #define INF 1000000000 int main(){ int x,n = 0,min = INF,max = -INF,s=0; while(n!=8&&scanf("%d",&x) == 1){ s += x; if(x<min) min = x; if(x>max) max = x; n++; } printf("%d %d %.3lf\n",min,max,(double)s/n); getch(); return 0; }
下面将其改造成读文件,写文件的形式
#define LOCAL #include <conio.h> #include<stdio.h> #define INF 1000000000 int main(){ //读取文件 #ifdef LOCAL freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif int x,n = 0,min = INF,max = -INF,s=0; while(n!=8&&scanf("%d",&x) == 1){//如果前面不通过,就不执行后面的内容了 s += x; if(x<min) min = x; if(x>max) max = x; /* printf("x = %d,min = %d,max = %d\n",x,min,max); */ n++; } printf("%d %d %.3lf\n",min,max,(double)s/n); getch(); return 0; }
读取当前文件夹下的in.txt
并将结果输出到out.txt中
输出2,4,6,8...2n
方法1
#include <conio.h> #include<stdio.h> int main(){ int i,n; scanf("%d",&n); for(i=2;i<=2*n;i+=2) { printf("%d\n",i); } getch(); return 0; }
方法2
#include <conio.h> #include<stdio.h> int main(){ int i,n; scanf("%d",&n); for(i=1;i<=n;i++) { printf("%d\n",2*i); } getch(); return 0; }
浮点陷阱
#include <conio.h> #include<stdio.h> int main(){ double i; for(i=0;(int)i!=10;i+=0.1)//如果不加(int)就永远不会等于10,程序永远不停止! { printf("%.1lf\n",i); } getch(); return 0; }
C++中的输入输出
方式1
#include <conio.h> //C++中保留了C语言中常用的头文件,如果你愿意,可以继续使用stdio.h #include<cstdio>//功能和C中的stdio.h很接近 using namespace std; //C++特有的单行注释,可以和C中传统注释/**/混合使用 int main(){ int a,b; while(scanf("%d%d",&a,&b)==2){ printf("%d\n",a+b); } getch(); return 0; }
方式2(用iostream)
#include <conio.h> //C++中保留了C语言中常用的头文件,如果你愿意,可以继续使用stdio.h #include<iostream>//C++中的输入输出头文件 using namespace std; //C++特有的单行注释,可以和C中传统注释/**/混合使用 int main(){ int a,b; while(cin>>a>>b){//张嘴送给cin cout<<a+b<<"\n";//张嘴送给a+b } getch(); return 0; }
C++中读取文件
#include <conio.h> #include<fstream> using namespace std; ifstream fin("in.txt"); ofstream fout("out.txt"); int main(){ int a,b; while(fin>>a>>b){//张嘴送给cin fout<<a+b<<"\n";//张嘴送给a+b } getch(); return 0; }