关于这个练习8,首先第一印象就是题量很大,有30道题,但好在大部分的题目难度中等,遇到的瓶颈就是如何在题目所要求输出的图案中找出一定的规律从而编写出代码实现题目。例如第6题(X形图案):
1006(X形图案)
题目描述:KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的X形图案。
输入描述:一个整数(2~20),表示输出的行数,也表示组成“X”的反斜线和正斜线的长度。
输出描述:输出用“*”组成的X形图案。

再看看示例:
示例1

输入

5

输出

*   *
 * * 
  *  
 * * 
*   *
第一眼看去,一点想法都没有,不知所措。但只要你仔细观察这个图案,就不难发现规律:
将X形图案看作正斜线“/”和反斜线“\”的组合,关于正斜线上的'*',其横坐标等于其纵坐标,而关于反斜线上的'*',其横纵坐标加在一起等于输入的整数n减1,从而找到了图案中'*'的排列规律,进而顺利解决该题。
0 1 2 3 4     
0 *          *
1   *     *
2       *
3    *     *  
4 *           *
AC代码:
#include <iostream>
using namespace std;
int main()
{
int n,i,j;
cin>>n;
for(i=0;i<n;i++)
{
for (j=0;j<n;j++)
{
if(i==j)
{
printf("*");
}else if (i+j==n-1)
{
cout<<"*";
}else
{
cout<<" ";
}
}
cout<<endl;
}
return 0;
}
第7题(乎乎的X形矩阵)也是这个规律。
接下来的8~19题,都是遵从一定的规律外加关于强制转换的知识,只要找到规律,就很容易解决问题。
20~23题,主要就是简单的循环应用,以及统计素数,难度不大。
从24题(零钱兑换)开始,难度剧增,可以说闻所未闻,不知所措。但我先说一下更为经典的1026(百钱买百鸡1)和1027(百钱买百鸡2):
先看一下两道题的题目:
1026(百钱买百鸡1)                                                                                                                                                                                                   
题目描述 :百钱买百鸡问题:公鸡五文钱一只,母鸡三文钱一只,小鸡三只一文钱,用 100 文钱买 100只鸡,公鸡、母鸡、小鸡各买多少只?         
本程序要求解的问题是:给定一个正整数 n,用 n 文钱买 n 只鸡,问公鸡、母鸡、小鸡各买多少只? 
输入描述: 输入一个正整数 n(1≤n≤200)。 、
输出描述: 如果有解,依次输出公鸡、母鸡、小鸡的个数(用正整数表示)。 如果无解,输出"No Answer."。

1027(百钱买百鸡2)
题目描述: 百钱买百鸡问题:公鸡五文钱一只,母鸡三文钱一只,小鸡三只一文钱,用 100 文钱买 100 只鸡,公鸡、母鸡、小鸡各买多少只? 
本程序要求解的问题是:给定一个正整数 n,用 n 文钱买 n 只鸡,问公鸡、母鸡、小鸡各买多少只? 
输入描述: 输入一个正整数 n(1≤n≤20000)。 
输出描述: 如果有解,依次输出公鸡、母鸡、小鸡的个数(用正整数表示)。 如果无解,输出"No Answer."。

可以看到,这两道题无非就是买鸡的数量的取值范围发生了变化,其余的文字一模一样。
对于1026,可以采用如下的代码:
#include<iostream>
using namespace std;
int main()
{
	int i,j,k,n,flag=0;
	cin>>n;
	for(i=0;i<=40;i++)
	{
		for(j=0;j<=67;j++)
		{
			for(k=0;k<=600;k++)
			{
				if((5*i+3*j+k/3.0==n)&&(i+j+k==n)){
				cout<<i<<" "<<j<<" "<<k<<endl;
				flag=1;
				}
			}
		}
	}
if(flag==0) cout<<"No Answer.\n";
return 0;
}
乍一看似乎很吓人,竟然有3重循环。但只要一想,其实也合情合理,无非就是用3个循环变量i,j,k来限定公鸡、母鸡、小鸡的最多数目(例如200文钱如果全部买5文钱一只的公鸡,最多只能买40只),之后按照题目要求编程即可。
但如果用20000文钱买20000只鸡,如果还用上述程序,循环判断所用时间就会超出限制,导致运行超时。有没有更好的代码呢?当然是有的:
#include<iostream>
using namespace std;
int main()
{
	int i,j,k,n,flag=0;
	cin>>n;
	for(i=0;i<=4000;i++)
	{
	for(j=0;j<=n-5*i;j++)
	 {
	k=n-i-j;
	 if((5*i+3*j+k/3.0)==n) 
	 {
	 cout<<i<<" "<<j<<" "<<k<<endl;
	 flag=1;
}
	}
	}
	if(flag==0) cout<<"No Answer."<<endl;
	return 0;
}
这样的话,就能减少一重循环,降低了代码的时间复杂度,使得代码可以在规定的时间内运行完毕,这样就不会运行超时。
1024(零钱兑换)、1025(鸡兔同笼)、1028(三元一次方程)也运用了类似的方法。
最后的两道题1029(分成整数)、1030(质因数分解),一道难如登天,另一道极为简单。
1029(分成整数)
题目描述 :给定一个正整数N,然后将N分解成3个正整数之和,计算出共有多少种符合要求的分解方法.
要求: 1) 分解的3个正整数各不相同;
 2) 分解的三个正整数中都不含数字3和7. 如:N为8, 可分解为(1,1,6), (1,2,5), (1,3,4), (2,2,4), (2,3,3), 其中满足要求的分解方法有1种,为(1,2,5) . 
输入描述: 输入一个正整数N(5<N<501), 表示要分解的正整数 
输出描述: 输出一个整数,表示共有多少种符合要求的分解方法.
这道题本身并不难,难就难在对题干中的两个要求的实现,要想将所有要求完美地表达出来,可谓非常繁琐。
#include<iostream>
using namespace std;
int f(int x)
{
	int a,b,c;
	a=x%10;
	b=x/100;
	c=x/10%10;
	if(a!=3&&a!=7&&b!=3&&b!=7&&c!=3&&c!=7) return 1;
	else return 0;
}
int main()
{
	int i,j,k,N,m=0;
	cin>>N;
	for(i=1;i<501;i++)
	{
	if(!f(i)) continue;
	for(j=i+1;j<501;j++)
	{
	if(!f(j)) continue;
	k=N-i-j;
	if(f(k)&&(k>i)&&(k>j))
	{
	m++;
	}
	}
	}
cout<<m<<endl;
return 0;
}
就说,如果考试考了这道题,除非有更高级的算法,否则我觉得,在有限的时间内且精神高度紧张的状态下,很难保证不出错。
总结一下,就是循环的应用范围很广泛,如能用好循环,尽量减少循环的嵌套,其实是能很高效地解决诸多困难的问题的。