蓝桥杯——剪邮票

如【图1.jpg】, 有12张连在一起的12生肖的邮票。

现在你要从中剪下5张来,要求必须是连着的。

(仅仅连接一个角不算相连) 比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。

请你计算,一共有多少种不同的剪取方法。

【最终结果】

116

思路

1.首先从12个数里面取出5个数来

2.把这五个数保存在mpt[3][4]当中,是这五个数的位置用1表示,不是的用0表示

3.判断这五个数是否相连

4.用深度遍历的方法判断。

#include <iostream>
#include <string>
using namespace std;

int sum = 0;

int a[12] = {1,2,3,4,5,6,7,8,9,10,11,12};
int mpt[3][4]; 
int mpt_cmd[3][4];
int b[5];//保存取出来的五个元素
int count = 0;
int mect[4][2] = {1,0,-1,0,0,1,0,-1};

void Print()
{
    for(int i=0;i<3;i++)
    {
        for(int j=0;j<4;j++)
        {
            cout<<mpt[i][j]<<" ";
        }
        cout<<endl;
    }
    
    cout<<endl;
    cout<<endl;
}

int Hand(int x,int y)//判断mpt[x][y],是否在mpt_cmd中,在里面返回0,不在返回1;
{
    if(mpt[x][y] == mpt_cmd[x][y])
    {
        return 0;
    }
    return 1;
    
}

void Lianjie(int x,int y)//判断五个数是否连接
{
    int x1,y1;
    for(int i=0;i<4;i++)//有四个方向
    {
        x1 = x+mect[i][0];
        y1 = y+mect[i][1];
        if(x1<0||x1>=3||y1<0||y1>=4)//超出界限了
            continue;
        if((mpt[x1][y1] == 0)|| (Hand(x1,y1) == 0))//该点不是所抽的五个数,或者该点已经遍历过
            continue;
        mpt_cmd[x1][y1] = 1;
        count++;
        Lianjie(x1,y1);            
    }
}

void Add()//抽取的五个数
{
    count = 0;
    memset(mpt,0,sizeof(mpt));//把数组初始化为0;
    memset(mpt_cmd,0,sizeof(mpt_cmd));
    int x,y;
    for(int i=0;i<5;i++)//将抽出来的五个数保存到数组mpt中,另该出为1,其它处为零
    {
         
        x = (b[i]-1)/4;
        y = (b[i]-1)%4;
        mpt[x][y] = 1;
    }

    
    count =1;
    Lianjie(x,y);//从保存的最后一个数当起点
    if(count==6)
    {
        //Print();输出每一种情况
        sum++;
    }
}



void fun(int m,int n)
{
    int i;
    for(i=m;i>=n;i--)
    {
        b[n-1] = a[i-1];
        if(n>1)
            fun(i-1,n-1);
        else
        {
            Add();
        }
    }
    
}

int main()
{
    fun(12,5);
    cout<<sum++<<endl;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/zkw123/p/10542038.html
今日推荐