第二章 循环结构程序设计--算法竞赛入门经典

第二章 循环结构程序设计–算法竞赛入门经典

例题2-2:3n+1的溢出问题

int32位整数范围是-2147473648~2147483647,long long是64位的整形可以表示的范围是-2^63 ~ 2^63-1。

#include<stdio.h>
int main()
{
	int n2, count = 0;
	scanf("%d", &n2);
	long long n = n2;
	while (n > 1)
	{
		if (n % 2 == 1)
		{
			n = n * 3 + 1;
		}
		else
		{
			n /= 2;
		}
		count++;
	}
	printf("%d\n", count);
	return 0;
}

输入987654321
输出180

例题2-4:阶乘之和 P25

输入n,计算S=1!+2!+3!+…+n!的末6位(不含前导0),n<=10^6。

#include<stdio.h>
#include <stdio.h>
#include <time.h>
int main()
{
	const int MOD = 1000000;
	int n, s = 0;
	scanf("%d", &n);
	if (n>25)/*程序的运行时间大致和n的平方成正比。因为25!的末尾
	有6个零,所以n=25之和的输出都一样。加上n>25的判断,解决效率和溢出问题。*/
	{
		n = 25;
	}
	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;
	}
	printf("%d\n", s);
	printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC);
	/*使用time.h和clock()函数获得程序运行时间。常数CLOCKS_PER_SEC和操作系
	统相关,请不要直接使用clock()的返回值,而应总是除以CLOCKS_PER_SEC。*/
	/*为了避免输入数据的时间影响测试结果,可使用一种称为“管道”的小技巧:
	在Windows命令行下执行echo 20|abc,操作系统会自动把20输入,其中abc是程序名。*/
	return 0;
}
例题2-5:数据统计 P27

输入一些整数,求出它们的最小值、最大值和平均值(保留3位小数)。输入保证这些数都是不超过1000的整数。

数据统计(重定向版):

#include <stdio.h>
#define LOCAL
#define INF 1000000000
int main()
{
#ifdef LOCAL
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int a;
	int min = INF;
	int max = -INF;
	int n = 0;
	int s = 0;
	//在Windows下,输入完毕后,需要键入Ctrl+Z,之后再按Enter键,即可结束输入。
	while (scanf("%d", &a) == 1)//scanf返回成功输入的变量个数
	{
		if (a < min)
			min = a;
		if (a > max)
			max = a;
		s += a;
		n++;
	}
	double avg;
	avg = double(s) / n;
	printf("%d  %d  %.3lf\n", min, max, avg);
	return 0;
}

数据统计(fopen版):

#include <stdio.h>
#define INF 1000000000
int main()
{
	FILE *fin, *fout;
	fin = fopen("input.txt", "rb");
	fout = fopen("output.txt", "wb");
	int x, n = 0, min = INF, max = -INF, s = 0;
	while (fscanf(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;
}

数据统计(fopen+标准输入输出版):

#include <stdio.h>
#define INF 1000000000
int main()
{
	FILE *fin, *fout;
	//在文件操作下用标准输入输出的方法一
	//fin = fopen("con", "rb");
	//fout = fopen("con", "wb");
	//在文件操作下用标准输入输出的方法二
	fin = stdin;
	fout = stdout;
	int x, n = 0, min = INF, max = -INF, s = 0;
	while (fscanf(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
	//fclose(fin);
	//fclose(fout);
	return 0;
}
习题2-5:分数化小数(decimal)

输入正整数a,b,c,输出a/b的小数形式,精确到小数点后c位。a,b<=10^6,c<=100。输入包括多组数据,结束标记为a=b=c=0。

#include <stdio.h>
int main()
{
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	int a, b, c;
	int n = 0;
	while (scanf("%d", &a) == 1 && scanf("%d", &b) == 1 && scanf("%d", &c) == 1)
	{
		if (a == 0 && b == 0 && c == 0)
			break;
		int res1, res2;
		res1 = a / b;
		res2 = a % b * 10;
		if (c > 0)
		{
			printf("Case %d: %d.", ++n, res1);
			for (int i = 0;i < c;i++)
			{
				res1 = res2 / b;
				res2 = res2  % b * 10;
				printf("%d", res1);
			}
			printf("\n");
		}
		else
		{
			printf("Case %d: %d\n", ++n, res1);
		}


	}
	return 0;
}
习题2-6:排列(permutation)

用1,2,3,…,9组成3个三位数abc,def,ghi,每个数字恰好使用一次,要求abc:def:ghi=1:2:3。按照“abc def ghi”的格式输出所有解。

#include <stdio.h>
#include<string.h>
int main()
{
	int abc, def, ghi;
	int s[10] = { 0 };
	for (int abc = 123;abc <= 329;abc++)//abc的最大值为987/3=329
	{
		memset(s, 0, sizeof(s));
		int sum = 0;
		def = abc * 2;
		ghi = abc * 3;
		s[abc / 100] = s[abc % 100 / 10] = s[abc % 10] = 1;
		s[def / 100] = s[def % 100 / 10] = s[def % 10] = 1;
		s[ghi / 100] = s[ghi % 100 / 10] = s[ghi % 10] = 1;
		for (int i = 1;i < 10;i++)
		{
			sum += s[i];
		}
		if (sum == 9)
		{
			printf("%d %d %d\n", abc, def, ghi);
		}
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值