蓝桥杯 剪邮票 DFS (不错的题目)

 

剪邮票

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

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

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
using namespace std;

const int maxn = 14;
int maze[3][4];
int num[6];
int have[13];          // 用了对从全排列中 选出来 5个数 ,进行 标志 (回溯: 标志为true后,需要换回false) 
bool used[3][4];       //这个是 从全排列中选出来5个数,进行DFS搜索是否连续用的标志数组 , 标志为true后,不需要换回false 
bool visit[13];        //进行全排列用的标志数组 
int ans;
int Count = 0;
int dir[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};  //方向 

void init();
void dfs_find(int r, int c);
bool judge(int r, int c);
void solve();

void init()
{
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 4; j++) {
            maze[i][j] = i*4 + j + 1;
        }
    } 
}

bool judge(int r, int c)
{
    return (r >= 0 && r < 3) && (c >= 0 && c < 4);
}

void dfs_find(int r, int c)
{
    for (int i = 0; i < 4; i++)
    {
        int nx = r + dir[i][0], ny = c + dir[i][1];
        //这个位置不是have标记位置(have里标记过的元素,是全排列找到的五个元素),或者已经访问过了 
        if (judge(nx, ny) && !used[nx][ny] && have[maze[nx][ny]]) {  
            used[nx][ny] = true;    //不需要换回 false, 除非出现另外一组5个数的时候 
            Count++;                //连续的数++ 
            dfs_find(nx, ny);       //对一个点进行DFS 
        }
    }
}

void solve()
{
    memset(have, 0, sizeof(have));
    memset(used, false, sizeof(used));
    for (int i = 1; i <= 5; i++) {
        have[ num[i] ] = 1;        //对5个数的位置进行标记 
    }
    
    for (int i = 0; i < 12; i++)
    {
        int r = i / 4;    //对应行
        int c = i % 4;    //对应列 
        if ( have[maze[r][c]] )     // 对找到的 5个数字(被标记1的),开始DFS搜索 
        {
            Count = 1;              //开始为1 
            used[r][c] = true;      //由标记的第一个数开始, 向其他标记的数 进行DFS, 找到则 Count++ 
            dfs_find(r, c);
            break;
        }
    }
    if (Count == 5) {               //全排列找到的5个数, 是相邻的, 则ans++ 
        ans++;
    }
}
//创建5个数的组合 
void Start_DFS(int cur)
{
    if (cur == 6)   //找到了5个数 
    {
        solve();    //对找到的5个数,进行排列组合 
        return;
    }
    
    //1到12 这 12个数 挨个遍历 -- 并进行DFS搜索 
    for (int i = num[cur - 1] + 1; i < 13; i++)    
    {
        if (!visit[i])          
        {
            visit[i] = true;
            num[cur] = i;       //存数,  对12个数进行全排列,从中选5个数,再进行排列组合 
            Start_DFS(cur + 1); //下一个数
            visit[i] = false;   
        }
    } 
}

int main()
{
    init();
    Start_DFS(1);
    printf("%d\n", ans);
}

 

算法思路:

1. 先全排列,从全排列1~12,从中选5个数,进行排列组合;

2. 对选中的5个数标志;

3. 循环找到第一个 第一个被标志的位置,并DFS递归寻找,他的dir方向的数字,是否是从全排列中选出来的其他数字.

详细看注释.

参考了这篇博客:http://blog.youkuaiyun.com/wuxiushu/article/details/51207533

转载于:https://www.cnblogs.com/douzujun/p/6670663.html

内容概要:该PPT详细介绍了企业架构设计的方法论,涵盖业务架构、数据架构、应用架构和技术架构四大核心模块。首先分析了企业架构现状,包括业务、数据、应用和技术四大架构的内容和关系,明确了企业架构设计的重要性。接着,阐述了新版企业架构总体框架(CSG-EAF 2.0)的形成过程,强调其融合了传统架构设计(TOGAF)和领域驱动设计(DDD)的优势,以适应数字化转型需求。业务架构部分通过梳理企业级和专业级价值流,细化业务能力、流程和对象,确保业务战略的有效落地。数据架构部分则遵循五大原则,确保数据的准确、一致和高效使用。应用架构方面,提出了分层解耦和服务化的设计原则,以提高灵活性和响应速度。最后,技术架构部分围绕技术框架、组件、平台和部署节点进行了详细设计,确保技术架构的稳定性和扩展性。 适合人群:适用于具有一定企业架构设计经验的IT架构师、项目经理和业务分析师,特别是那些希望深入了解如何将企业架构设计与数字化转型相结合的专业人士。 使用场景及目标:①帮助企业和组织梳理业务流程,优化业务能力,实现战略目标;②指导数据管理和应用开发,确保数据的一致性和应用的高效性;③为技术选型和系统部署提供科学依据,确保技术架构的稳定性和扩展性。 阅读建议:此资源内容详尽,涵盖企业架构设计的各个方面。建议读者在学习过程中,结合实际案例进行理解和实践,重点关注各架构模块之间的关联和协同,以便更好地应用于实际工作中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值