2016蓝桥杯C++A组第七题 剪邮票【DFS】

从1-12中从小到大选取5个数(DFS)

BFS判断找出来的5个数是否连通:以任意一个(我的程序取得是最小的)为起点,BFS搜索   是否可以搜索到5个 如果可以 说明是连通的

#include<iostream>
#include<stdio.h>
#include<cmath>
#include<queue>
using namespace std;
int a[13] = { 0 };//dfs
int l[5];//存储已经 找到的5个数 
int sum = 0;
typedef struct node{
    int x, y;
    struct node(){
        x = -1;
        y = -1;
    }
    struct node(int xx, int yy){
        x = xx;
        y = yy;
    }
}Node;
bool ok(){//bfs判断找到的5个数是否连通
    int arr[3][4];//存储剪切矩阵 
    int flag[3][4];
    for (int i = 0; i<3; i++){
        for (int j = 0; j<4; j++){
            arr[i][j] = 0;//bfs过程中标记是否可访问 
            flag[i][j] = 0;//bfs过程中标记是否已经访问 
        }
    }
    for (int i = 0; i<5; i++){
        arr[(l[i]-1)/4][(l[i]-1)%4]= 1;
    }
    /*cout << "arr:" << endl;
    for (int i = 0; i<3; i++){
        for (int j = 0; j<4; j++){
            cout << arr[i][j];
            cout << " ";
        }
        cout << endl;
    }*/
    int dir[4][2]{//上下左右方向控制 
        { -1, 0},
        { 1, 0 },
        { 0, -1 },
        { 0, 1 }
    };
    queue<Node> q;
    Node vs((l[0] - 1) / 4, (l[0] - 1) % 4);
    flag[vs.x][vs.y] = 1;
    q.push(vs);
    int ssum = 1;
    Node vn, vw;
    while (q.empty() == false){
        vn = q.front();
        q.pop();
        for (int i = 0; i<4; i++){
            vw.x = vn.x + dir[i][0];
            vw.y = vn.y + dir[i][1];
            //cout << vw.x << vw.y << endl;
            /*cout << "flag:" << endl;
            for (int i = 0; i<3; i++){
                for (int j = 0; j<4; j++){
                    cout << flag[i][j];
                    cout << " ";
                }
                cout << endl;
            }*/
            //getchar();
            if (vw.x >= 0 && vw.x <= 2 && vw.y >= 0 && vw.y <= 3){
                if (flag[vw.x][vw.y] == 0 && arr[vw.x][vw.y] == 1){//如果改点未访问过   且该点可访问
                    flag[vw.x][vw.y] = 1;//标记该节点已经访问过
                    q.push(vw);
                    ssum++;
                }
            }
        }
    }
    //cout << ssum << endl;
    if (ssum == 5) return true;
    return false;

}
void dfs(int x){
    if (x>1 && (l[x - 1]<l[x - 2])) return;//递减就不要 
    if (x == 5&&ok()){
        /*for (int i = 0; i<5; i++){
            printf(" %d", l[i]);
        }
        printf("\n");*/
        sum = sum + 1;
        //printf("打印%d\n",sum);
        return;
    }
    if (x == 5) return;
    for (int i = 1; i<13; i++){
        if (a[i] == 0){
            l[x] = i;
            a[i] = 1;
            dfs(x + 1);
            a[i] = 0;
        }
    }
}
int main(){
    dfs(0);
    cout << sum << endl;
}

 

转载于:https://www.cnblogs.com/Elaine-DWL/p/6658873.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值