C语言(CED)有排成一行的n个方格,用红(Red)、粉(Pink)、绿(Green)三色涂每个格子,每格涂一色,要求任何相邻的方格不能同色,且首尾两格也不同色.求全部的满足要求的涂法.

相信大家在高中数学课上都做过类似于涂色的排列组合问题,那么这个问题如何用程序语言——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;
    else
        return 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;
}

发布了62 篇原创文章 · 获赞 93 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/GenuineMonster/article/details/88289989