2016年第七届蓝桥杯C/C++B组省赛题目7:剪邮票

题目描述:

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

现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】
【图3.jpg
中,粉红色所示部分就是合格的剪取。

请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

题目答案:

116

题目思路:
i1、i2、i3、i4和i5为枚举要剪下的5个数,对这五个数构成的连通性进行dfs判断,
如果dfs后测得从i1出发从上下左右四个方向上深度优先搜索遍历为i2~i5之间的所有点,
cnt标记i5能够走到的是i1~i5这些点的个数,如果cnt == 5就说明是连在一起的,
注意从4和8向右行走走不到5和9,并且从5和9出发向左行走走不到4和8~
所以遇到index == 4或者index == 8并且是向右走的时候continue~(index == 5和9并向左走同理~)
将result加一~累加得到的result就是结果116~

代码:

#include <iostream>
using namespace std;
int dis[4] = {1, -1, 4, -4};//移动方向
int visit[13];//标记所经历的点
int i1, i2, i3, i4, i5, cnt, result = 0;
void dfs(int index) {
    visit[index] = 1;//标记所经历的点
    if (cnt >= 5) return;
    for (int i = 0; i < 4; i++) {
        if ((dis[i] == 1 && (index == 4 || index == 8)) || (dis[i] == -1 && (index == 5 || index == 9)))
            continue;
        int t = index + dis[i];//移动到下一个点
        if (t >= 1 && t <= 12 && visit[t] == 0 && (t == i2 || t == i3 || t == i4 || t == i5))
        {
            cnt++;
            dfs(t);
        }
    }
}
int main() {
    for (i1 = 1; i1 <= 12 - 4; i1++) {
        for (i2 = i1 + 1; i2 <= 12 - 3; i2++) {
            for (i3 = i2 + 1; i3 <= 12 - 2; i3++) {
                for (i4 = i3 + 1; i4 <= 12 - 1; i4++) {
                    for (i5 = i4 + 1; i5 <= 12; i5++) {
                        memset(visit, 0, sizeof(visit));
                        cnt = 1;
                        dfs(i1);
                        if (cnt == 5) result++;
                    }
                }
            }
        }
    }
    cout << result;
    return 0;
}

转自链接:https://blog.csdn.net/liuchuo/article/details/69569281

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值