《算法竞赛入门经典》第2章 循环结构程序设计(未完待续)


规范代码

1、留意“当前行”的跳转和变量的改变

2、尽量缩短变量的定义范围:

int main() {
    int i;
    int n = 5;
    for (i = 0; i < n; i++) {
        printf("%d\n", i);
    }
    // 在这里,即使循环已经结束,i 仍然可用
    return 0;
}

int main() {
    int n = 5;
    for (int i = 0; i < n; i++) {
        printf("%d\n", i);
    }
    // 在这里,i 的作用域结束了,外部无法访问 i
    return 0;
}

作用:减少内存资源的占用。

编程技巧与思维

1、伪代码:

例2-1 aabb:

输出所有形如aabb的4位完全平方数。

解题思路1:
1、循环找四位数
2、判断剔除(n*n=m)

for (int a = 1; a <= 9; a++)
	for (int b = 0; b <= 9; b++)
		if (aabb是完全平方数)printf(“% d”, aabb);
int main()
{
	for (int a = 1; a <= 9; a++)
		for (int b = 0; b <= 9; b++)
		{
			int n = 0;
			n = a * 1100 + b * 11;
			int m = floor(sqrt(n)+0.5);//为减小误差,四舍五入。
			if (m * m == n)printf("%d\n", n);//核心思路
		}
	return 0;
}

新知

解题思路2:
枚举平方根x

int main()
{
	for (int x = 1; x <= 100; x++)
	{
		int aabb = 0;
		aabb = x * x;
		if (aabb/1000==aabb/100%10&&aabb/10%10==aabb%10)printf("%d\n", aabb);
	}
	return 0;
}

重点:千位=百位,十位=个位。

例2-4 阶乘之和

输入n,计算s = 1!+2!+3!+…+n!

for (int i = 1; i <= n; i++)s += i!;

2、看似正确的代码其实有错(不要忘了测试)

溢出、
解决方法:输出中间变量。

习题

2-1 水仙花数(dafodil)

int main()
{
	for (int i = 100; i <= 999; i++)
	{
		if (i == pow(i / 100, 3) + pow(i % 10, 3) + pow(i % 100 / 10, 3))
			printf("%d\n", i);
	}
	return 0;
}

新知:
double pow(double x, double y);
pow数学函数,计算x的y次方;(具体使用方法模仿即可)

进阶请移步

2-2 韩信点兵 (hanxin)

int main()
{
	int i, a, b, c;//依次输入三人一排,五人,七人一排的排尾数
	while (scanf("%d%d%d", &a, &b, &c) != EOF)//循环输入到文件结束
	{
		for (i = 10; i <= 100; i++)
		{
			if (i % 3 == a && i % 5 == b && i % 7 == c)//认真理解题意
			{
				printf("Case 1:%d\n", i);
				break;
			}
		}
		if (i > 100)
			printf("Case 2: No answer\n");
	}
	return 0;
}

2-3 倒三角形 (triangle)

解题思路

1、首先确定需要多重循环打印(最外层循环输出次数最少)。
2、理清三要素:” “、”#“、”\n“
3、根据输出示例思考各要素之间的联系:
①换行只需要输出五次
②” “和”#“每行都要输出
所以:以输出换行为目的写最外层循环
4、根据输出示例看出每行” “与”#“之间的关系(我是一个个数的…)

int main()
{
	int n, i, j, k;
	scanf("%d", &n);
	for (i = n; i >= 1; i--)//循环打印,换行
	{
		for (j = 1; j <= n - i + 1; j++)//数出每行空格从2开始递增,想办法用编程实现。
		{
			printf("  ");
		}
		for (k = 1; k <= 2 * i - 1; k++)//”#“后加上” “
			printf("# ");
		printf("\n");
	}
	return 0;
}

2-4 子序列的和(subsequence)

int main()
{
	int n, m, i, count = 0;
		while (scanf("%d%d", &n, &m) != EOF)
		{
			double sum = 0;//注意要重置sum
			for (i = n; i <= m; i++)
			{
				sum += 1.0 / pow(i, 2);//注意小数除法
			}
			count++;//小细节
			printf("Case %d:%.5lf\n", count, sum);//又忘了,简单的累加
			if (n == 0 && m == 0)//条件要详细,不能连==
			{
				break;
			}
		}
		return 0;
}

2-5 分数化小数 (demical)

int main()
{
	int a, b, c, count = 0;
	while (scanf("%d%d%d", &a, &b, &c) != EOF)
	{
		if (a == 0 && b == 0 && c == 0)
			break;
		count++;
		printf("Case %d:%.*lf\n",count,c,a / (b * 1.0));//注意小数除法
	}
	
	return 0;
}

2-6 排列(permutation)

在这里插入代码片
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值