剪邮票 dfs

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

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


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

题目答案:

116

题目思路:

枚举五种数的所有组合然后判断这五个数是否连通即可。判断连通性可以用DFS来判断,上下左右四个方向可以将题目中的1,2,3,4,5,6,7,8,9,10数字进行转换,4和5是无法连通的,可以将其变为1,2,3,4,6,7,8,9,11,12,13,14如图,这样我就可以实现左右分别+1和-1,上下分别+5和-5来实现。

 

#include<stdio.h>
#include<string>
using namespace std;
int temp2[5];
int temp1[12]={1,2,3,4,6,7,8,9,11,12,13,14};
int dict[4]={1,-1,5,-5};
int vis[5];
int ans=0;

void dfs(int n){
    for(int i=0;i<4;i++){
        int j = temp2[n]+dict[i];
        if(j>=1&&j<=14){
            for(int k=0;k<5;k++)
            {
                if(temp2[k]==j&&!vis[k])
                {
                    vis[k]=1;
                    dfs(k);
                }
            }
        }
    }
    
}

int main(){
    int a,b,c,d,e;
    for(a=0;a<12;a++){
        for(b=a+1;b<12;b++){
            for(c=b+1;c<12;c++){
                for(d=c+1;d<12;d++){
                    for(e=d+1;e<12;e++){
                        temp2[0]=temp1[a];
                        temp2[1]=temp1[b];
                        temp2[2]=temp1[c];
                        temp2[3]=temp1[d];
                        temp2[4]=temp1[e];
                        memset(vis,0,sizeof(vis));
                        vis[0]=1;
                        dfs(0);
                        int flag = 1;
                        for(int i =0;i<5;i++)
                        {
                            if(vis[i]==0){
                                flag=0;
                            }
                        }
                        if(flag)ans++;
                    }
                }
            }
        }
    }
    printf("%d\n",ans);
} 
View Code

链接:http://blog.csdn.net/qq_34594236/article/details/61209276

 

posted @ 2017-03-22 19:53  vxee  阅读(134)  评论(0编辑  收藏  举报