紫书第二章 顺序循环

2-1 7744问题

问题描述:
输出所有形如aabb的4位完全平方数。
思路一:

#include <iostream>
#include <cmath>
using namespace std;
int main()
{
	for(int i=1;i<10;i++)
	{
		for(int j=1;j<10;j++)
		{
			int x=i*1100+j*11;
			int y=floor(sqrt(x)+0.5);
			if(y*y==x)	cout<<x<<endl;
		}
	}
	return 0;
}

sqrt(x)求x的平方根。
floor(x)返回不超过x的最大整数。
由于浮点运算一般有误差,为减小误差影响,一般改为四舍五入,即floor(x+0.5)(仍旧有误差)。
思路二:
避开开方操作,枚举平方数。

#include <iostream>
using namespace std;
int main()
{
	for(int i=1;;i++)
	{
		int x=i*i;
		if(x<1000)	continue;
		if(x>9999)	break;
		int front = x/100;
		int back = x%100;
		if(front/10==front%10&&back/10==back%10)	cout<<x<<endl;
	}
	return 0;
}

2-2 3n+1问题

问题描述:
对于任何大于1的自然数,若n为奇数,将n变为3n+1,若n为偶数,将n变为n/2。最后n一定变为1。
输入n,输出变换的次数。

#include <iostream>
using namespace std;
int main()
{
	long long n; //注意此处如果用int,当数据足够大时会产生溢出现象
	cin>>n;
	int count=0;
	while(n!=1)
	{
		if(n%2==0)	n/=2;
		else	n=3*n+1;
		count++;
	}
	cout<<count<<endl;
	return 0;
}

2-3 近似计算

题目描述:
计算pi/4 = 1 - 1/3 + 1/5 - 1/7 +·····,直到最后一项小于10e-6。
思路一:

#include <iostream>
using namespace std;
const double N=1e-6;
int main()
{
	double sum=0;
	int k=1;
	for(int i=1;;i+=2)
	{
		double x=1.0/i;
		sum+=(x*k);
		k*=(-1);
		if(x<N)	break;
	}
	cout<<3.14/4<<' '<<sum<<endl;
	return 0;
}

思路二:

#include <iostream>
using namespace std;
const double N=1e-6;
int main()
{
	double sum=0;
	for(int i=0;;i++)
	{
		double x=1.0/(2*i+1);
		if(i%2==0)	sum+=x;
		else	sum-=x;	
		if(x<N)	break;
	}
	cout<<3.14/4<<' '<<sum<<endl;
	return 0;
}

2-4 阶乘之和

问题描述:
输入n,计算1到n的阶乘之和的后6位,不包含前导零。
代码:

#include <iostream>
using namespace std;
int main()
{
	int n;
	cin>>n;
	long long s=0,fac=1;
	for(int i=1;i<=n;i++)
	{
		fac*=i;
		s+=fac;
	}
	s%=1000000;
	cout<<s<<endl;
	return 0;
}

优化代码:(解决算数运算溢出)
要计算只包含加减乘的整数表达式除以正整数n的余数,可以在每步计算后对n取余,结果不变。

#include <iostream>
using namespace std;
const int mod=1000000;
int main()
{
	int n;
	cin>>n;
	long long s=0,fac=1;
	for(int i=1;i<=n;i++)
	{
		fac=(fac*i)%mod;
		s=(s+fac)%mod;
	}
	cout<<s<<endl;
	return 0;
}

2-5数据统计

题目描述:
输入一些整数,求出它们的最小值、最大值和平均值(保留三位小数)。
代码一(标准输入输出):

#include <iostream>
using namespace std;
const int INF=1e9;
int main()
{
	int x,n=0,min=INF,max=-INF,s=0;
	while(scanf("%d",&x)==1)//scanf返回的是成功输入的变量个数。
	{
		s+=x;
		if(x<min)	min=x;
		if(x>max)	max=x;
		n++;
	}
	printf("max=%d,min=%d,average=%.3f\n",max,min,(double)s/n);
	return 0;
}

输入完毕后先按Enter键,再按Ctrl+Z,再按Enter键即可结束输入。
以下是文件输入输出:
代码二(重定向版):
可在本机测试时使用,只需提交前删除#define LOCALL即可。

//数据统计,重定向版 
#define LOCAL
#include <iostream>
#define INF 1e9;
int main()
{
#ifdef LOCAL
	freopen("data.in","r",stdin);
	freopen("data.out","w",stdout);
#endif
//重定向的部分被写进#ifdef和#endif中。
//只有定义了符号LOCAL,才编译两条freopen语句。 
	int x,n=0,min=INF,max=-INF,s=0;
	while(cin>>x)
	{
		s+=x;
		if(x<min)	min=x;
		if(x>max)	max=x;
		n++;
	}
	cout<<min<<' '<<max<<' '<<(double)s/n<<endl;
	return 0;
}

代码三(fopen版):

#include <iostream>
#define INF 1e9;
using namespace std;
int main()
{
	FILE *fin,*fout;
	fin = fropen("data.in","rb");
	fout = fopen("data.out","wb");
	int x,n=0,s=0;
	int min=INF,max=-INF;
	while(fscangf(fin,"%d",&x)==1)
	{
		s+=x;
		if(x<min)	min=x;
		if(x>max)	max=x;
		n++;
	}
	fprintf(fout,"%d %d %.3f\n",min,max,(double)s/n);
	fclose(fin);
	fclose(fout);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值