第2章 循环结构程序设计

原创 2015年11月19日 18:36:04

2.1 for循环

例题2.1 aabb(输出所有的形如aabb的4位完全平方数)
算法一:对1000到9999分别进行aabb以及完全平方的判断,但很明显效率较低。
#include <stdio.h>
#include <math.h>
int main()
{
	double square;
	for(int i = 1000; i <= 9999; i++){ //尽量缩短变量的定义范围,在for循环的初始化部分定义循环变量
		square = floor(sqrt(double(i)) + 0.5);
		if(i%10 == i%100/10 && i/100%10 == i/1000 && square*square == i)
			printf("%d ",i);
	}
	printf("\n");
	return 0;
}
算法二:进行双层循环,分别对a进行1到9和对b进行0到9的遍历,再对得到的形如aabb的四位数做完全平方的判断。注意四舍五入floor(sqrt(double(n)) + 0.5),如floor(x + 0.5)等于1的区间为[0.5, 1.5)。
#include <stdio.h>
#include <math.h>
int main()
{
	for(int a = 1; a < 10; a++){  //a从1开始,因为是四位数
		for(int b = 0; b < 10; b++){
			int n = a * 1100 + b *11;
			int m = floor(sqrt(double(n)) + 0.5);
			if(m*m == n) printf("%d ", n);
		}
	}
	printf("\n");
	return 0;
}
算法三:枚举平方根,从而避免开平方操作,square从1开始,当其平方数小于1000时开始下层循环,大于9999时跳出循环,循环体内进行aabb的判断。
#include <stdio.h>
#include <math.h>
int main()
{
	for(int square = 1; ; square++){
		int n = square*square;
		if(n < 1000) continue;
		if(n > 9999) break;
		if(n%10 == n%100/10 && n/100%10 == n/1000)
			printf("%d ", n);
	}
	printf("\n");
	return 0;
}

2.2 while循环和do-while循环

例题2.2 3n + 1问题(任何大于1的数n,若为奇数,变为3n + 1,若为偶数变为n/2,经过若干这样的变换后,最终变为1,求变换次数,其中n <= 10^9)
算法分析:若用int n来存放输入的数,当输入的n = 987654321时,对于n = 3n + 1;将导致n溢出int型范围值(-2147483648~2147483647),使得n值为负值,不满足n >1,故需要用long long型(-2^63~2^63-1)存放已输入的n值。
由于不知道循环次数,本题需要用到while循环,当while(n > 1)不满足时跳出循环。
#include <stdio.h>
int main()
{
	int n;
	scanf("%d", &n);
	long long n1 = n;
	int count = 0;
	while(n1 > 1)
	{
		if(n1 % 2 == 0) n1 = n1/2;
		else n1 = 3*n1 + 1;
		count++;
	}
	printf("%d\n", count);
	return 0;
}
例题2.3 近似计算(计算π/4 = 1 - 1/3 + 1/5 - 1/7 +......,直到最后一项小于10^-6)
算法分析:由于最后一项需要计算在内,故用do-while循环。
#include <stdio.h>
int main()
{
	double pi = 0.0, temp, t = 1.0;
	int i = 1;
	do{
		temp = 1.0/i;   //注意分子为1.0,此时才能进行浮点数运算,若写成1,temp的值将为1或者0,得不到正确结果
		pi += temp*t;  
		t = -t;
		i += 2;
	}while(temp >= 1e-6);   //注意10^-6的写法
	printf("%.6f\n", pi);
	return 0;
}

2.3 循环的代价

例题2.4 阶乘之和的末6位(计算s = 1! + 2! + 3! + ......n!,其中n<=10^6)
算法分析:当计算第n项n!时,若n比较大,会超过int的范围。需要用到一点数学知识:要计算只包含加法,减法和乘法的整数表达式除以正整数n的余数,可以在每步计算之后对n取余,结果不变。
#include <stdio.h>
#include <time.h>
int main()
{
	const int MOD = 1000000;
	int n;
	scanf("%d", &n);
	double t1 = (double)clock() / CLOCKS_PER_SEC;  //循环体开始执行前时间,防止将键盘输入时间计算在内
	int S = 0;
	for(int i = 1; i <= n; i++){
		int factorial = 1;
		for(int j = 1; j <= i; j++){
			factorial = factorial * j % MOD;  
		}
		S = (S + factorial) % MOD;            //没进行一次乘法或者加法,都要对MOD取余,使结果尽可能小
	}
	printf("%d\n", S);
	printf("Time used = %.6f\n", (double)clock() / CLOCKS_PER_SEC - t1); //使用clock()和CLOCKS_PER_SEC来计算时间差(秒)
	return 0;
}
可以将n设置160,1600,6400……来进行多组测试,可知程序的运行时间大致与n的平方成正比。从40开始,答案始终不变,这是因为25!的末尾后面有6个0,故可修改原程序,在输入n后,加一条语句if(n > 25) n = 25;

2.4 算法竞赛的输入输出框架

例题2.5 数据统计(输入一些整数,求出它们的最小值,最大值和平均值)
算法一:设置一个INF和-INF,每输入一个x,就对其进行比较,然后累加。
#include <stdio.h>
#include <cstdlib>
int main()
{
	int x, count = 0;
	double s = 0;
	int min = INT_MAX, max = INT_MIN;  //也可以先输入一个x,然后令max = min = x;
	while(scanf("%d", &x) != EOF){  //scanf("%d", &x) == EOF
		if(x > max) max = x;
		if(x < min) min = x;
		s += x;
		count++;
	}
	printf("%d %d %f\n", min, max, s/count);
	return 0;
}
scanf遇到回车键时将数据从缓冲区送到程序,例如输入5, 8, 9, 14, 16,按回车键,再按crtl + z键结束输入后,程序运行最终结果
算法二:一种好的方法是用文件——把输入数据保存在文件中,输出数据也保存在文件中。

例题2.6 数据统计ii(与上例相同,但告诉了n值,以及要求测试多组数据,输入n = 0时结束输入)
算法分析:若此处用自己设置的max和min,要注意上组数据对下组数组的影响,故应当将max和min在循环体内重新赋初值。
#include <stdio.h>
#define INF 100000000
int main()
{
	int x, n, kase = 0, min, max;
	while(scanf("%d", &n) == 1 && n)  //如果程序鲁棒性强,有时能在数据有瑕疵的情况下仍然给出正确的结果
	{
		max = -INF;
		min = INF;
		int s = 0;
		for(int i = 0; i < n; i++){
			scanf("%d", &x);
			s += x;
			if(x < min) min = x;
			if(x > max) max = x;
		}
		printf("Case %d: %d %d %.3f\n", ++kase, min, max, (double)s/n);
	}
	return 0;
}

2.5 注解和习题

习题2.4:子序列的和(输入两正整数n < m < 10^5,输出1/n^2 + 1/(n+1)^2 + ……+1/m^2,保留5位小数,输入包含多组数据,n=m=0时结束输入)
算法分析:需要注意的就是每一项都应该转换为浮点数,然后累加。用C++实现如下:
<span style="font-size:10px;">#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
	double n,m;
	int kase=0;
	while(cin>>n>>m)
	{
		if(n==0&&m==0) break;
		cout<<"Case "<<++kase<<": ";
		double sum=0;
		for(int i=n;i<=m;i++)
		{
			double temp=1.0/(i*i);
			sum+=temp;
		}
		cout<<setiosflags(ios::fixed)<<setprecision(5)<<sum<<endl;
	}
	return 0;
}</span>
习题2.5:分数化小数(输入正整数a,b,c,输出a/b的小数形式,精确到小数点后c位,a,b<=10^6, c<=100,输入包含多组数据,a=b=c=0时结束输入)
算法分析:
<span style="font-size:10px;">#include <iostream>
using namespace std;
int ans1[110],ans2[110];
int main()
{
	int a,b,c;
	int kase=0;
	while(cin>>a>>b>>c)
	{
		if(a==0&&b==0&&c==0) break;
		cout<<"Case "<<++kase<<": ";
		ans1[0]=a;
		ans2[0]=a/b;
		for(int i=1;i<=c+1;i++)
		{
			ans1[i]=ans1[i-1]%b*10;  //存放每次的除数
			ans2[i]=ans1[i]/b;       //存放每次的商
		}
		if(ans2[c+1]>=5)             //进位
		{
			ans2[c]=ans2[c]+1;
			int i=c;
			while(ans2[i]==10)
			{
				if(--i>0)
					ans2[i]=ans2[i]+1;
				else break;
				ans2[i]=0;
			}
			if(ans2[1]==10) {ans2[1]=0; ans2[0]++;}   //修改整数位
		}
		cout<<ans2[0]<<".";
		for(int i=1;i<=c;i++)
			cout<<ans2[i];
		cout<<"\n";
	}
	return 0;
}</span>
习题2.6:排列(用1~9,组成3个三位数abc,def和ghi,每个数字恰好使用一次,使abc:def:ghi = 1:2:3,按格式“abc def ghi”输出所有解,每行一个)
算法分析:
#include <stdio.h>  
int  main(void)  
{  
    int i, j, k;  
    int i1, i2, i3;  
    int j1, j2, j3;  
    int k1, k2, k3;  
    int c, count;  
    for (i = 123; i <= 329; i++) {  
        j = i*2;  
        k = i*3;  
        i1 = i/100, i2 = i/10%10; i3 = i%10;  
        j1 = j/100, j2 = j/10%10; j3 = j%10;  
        k1 = k/100, k2 = k/10%10; k3 = k%10;          
        for (c = 1; c != 10; c++) {  
            count = 0;  
            if (c == i1)  
                count++;  
            if (c == i2)  
                count++;  
            if (c == i3)  
                count++;  
            if (c == j1)  
                count++;  
            if (c == j2)  
                count++;  
            if (c == j3)  
                count++;  
            if (c == k1)  
                count++;  
            if (c == k2)  
                count++;  
            if (c == k3)  
                count++;  
            if (count > 1)  
                break;  
        }  
        if (c == 10 && i2 != 0 && i3 != 0 && j2 != 0 && j3 != 0 && k2 != 0 && k3 != 0)  
            printf("%d %d %d\n", i, j, k);  
    }         
    return 0;  
}  

































版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

第2章 循环结构程序设计

2.1 for循环 例题2.1 aabb(输出所有的形如aabb的4位完全平方数) 算法一:对1000到9999分别进行aabb以及完全平方的判断,但很明显效率较低。 #include #inclu...

第2章 循环结构程序设计 习题

习题 2-1 水仙花数(daffodil) 习题 2-2 韩信点兵(hanxin)

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

第二章循环结构程序设计习题

2-1、水仙花数(daffodil) 输出100~999中所有的水仙花数。若三位数ABC满足ABC=A^3+B^3+C^3,则称其为水仙花数。   2-2、韩信点兵(韩信) 相传韩信才智过人,...

第02章_循环结构程序设计

算法竞赛入门经典_学习笔记_各例题和训练源文件   第02章_循环结构程序设计 Example_0201_aabb完全平方数_先创形式再判值.cpp Example_0201_aabb完全平方...

第二章 循环结构程序设计

2.1 for循环 2.2 while循环和do-while循环 2.3循环的代价 2.4算法竞赛中的输入输出框架 2.1 for循环2-1 输出1,2,3·······n的值#...

循环结构程序设计

一、实验目的1、掌握用while语句,do-while语句和for语句实现循环的方法。 2、掌握在程序设计中用循环的方法实现一些常用算法(如穷举、迭代、递推等)。 3、调试程序的技巧。 二、实验内容1...

5.循环结构程序设计

1.while while(condition){...} 2.do  ... while 先执行循环体,然后再检查条件是否成立。 3.for(表达式1;表达式2;表达式3) ...

while循环结构的程序设计

循环结构的程序设计

循环结构程序设计

FOR 对于for循环,建议尽量缩短变量的定义范围,例如在初始化部分定义循环变量。 for(int i=0;i<10;i++)aabb(7744)输出所有形如aabb的4位完全平方数;#include...

C++专项 第七讲:循环结构程序设计

循环结构程序设计例子: 输出所有的水仙花数,穷举法练习:都要学C,鸡兔同笼问题,利用级数展开式求cos(x),在迭代中赋予变量term新的含义,菲波那契数列,输出一个指定区间内的所有素数,判断单个数m...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)