相信大家在高中数学课上都做过类似于涂色的排列组合问题,那么这个问题如何用程序语言——C语言解决呢?
一、总体思路(如果你只是需要代码,请直接看代码部分)
你应该重视思路,用C语言将之前数学课上的思路重现一下就好了!这些问题都可以归类到递归问题,因为每次涂色的时候考虑的情况大致类似,下面提供一种思考方式:为方便起见,假设我已获得了求解这道问题的函数solve(),只要输入n是多少就能得到结果。
我们先不管第一格到第三格怎么涂色,我们先考虑倒数第2格,也就是第n-1格怎么涂色?
根据题意,
A、如果这个方格的颜色和第一个方格的颜色不同,那么第n个方格就只有1种选择(因为首尾两格也不同色),所以之前n-1个方格的涂色方法为solve(n-1),此时n个方格的涂色方法总数为solve(n-1)*1;(将第n个方格和之前的方格分成两部分)
B、如果这个方格的颜色和第一个方格的颜色相同,那么第n个方格就有2种选择,所以之前n-1个方格的涂色方法为solve(n-2)(为什么是n-2呢?是因为前提是?——“n-1的方格颜色已与第1个方格的颜色一致,第1个是什么颜色,第n-1方格就是什么颜色”,所以n-1方格的颜色不需要考虑,所以函数里传的参数是n-2)。所以,在本情况下,n个方格的涂色方法总数为2*solve(n-2)。
上述的A、B是思考方式上的分类,说白了就是初中数学(中考最后一题)中要掌握的分类讨论思想---“要想解对题,此题的所有情况都要列出”,而不是我们C语言中,不是if就是else的互斥情况。
综上,解决涂色问题的表达式是:方法总数=solve(n-1)*1+2*solve(n-2);说到这,你也许就觉得懂了,但是你忘了,我们的这个函数是假设出来的,还没有实现呢!别着急,请看第二部分,实现过程。
二、实现过程(“如果你不思考的Copy,你将永远是layman!”)
我们可以发现,当n<=3时,上述的思路行不通,所以可以先用递推式来模拟一下简单的涂色,n=1、n=2、n=3的情况。
发现:A:n=1时,涂色方法总数=3;//根据高中数学的排列组合得来的,下同
B:n=2时,涂色方法总数=6(3*2)
n=3时,涂色方法总数=6(3*2*1)
C:n>=4时,涂色方法总数=solve(n-1)*1+2*solve(n-2)
根据上述A、B、C三种情况,我们写下如下的代码:这里用long是为了范围更大,因为要大数输出!
#include <iostream>
#include <cmath>
using namespace std;
long long solve(int n) //用long long定义,整形范围更大。
{long long a[3]= {0};a[0]=3;//根据之前高中数学所学内容得出当n=1时,方法数为3;a[1]=6;//与上同理a[2]=6;//与上同理if(n==1)return 3;else if(n==2||n==3)return 6;elsereturn solve(n-1)*1+2*solve(n-2);
}
int main()
{int n;cout << "请输入方格的个数:" << endl;while (cin >> n){//输入方格数if (n == 0){cout << "输入有误!请重新输入方个个数:" << endl;continue;}cout << "对应的涂色方法为:" << endl;cout << solve(n) << endl;cout << "涂色已完成" << endl;cout << "请输入下一方格的个数:(无其它输入请用EOF结束程序)" << endl;}return 0;
}