20省2-5- 七段码 深搜检测连通域 板子题,细心等于判断是==

20省2-5- 七段码


link.
【dfs】连通域
七段码-二进制,深搜检测连通域
if括号里面的判断一定要用==

#include<bits/stdc++.h>
using namespace std;
int N[7][7]={0};//不相连
int vis[7];
int sel[7];
void dfs(int pos){
    for(int i=0;i<7;i++){
        if(N[pos][i]&&sel[i]&&vis[i]==0){
                vis[i]=1;
                dfs(i);
        }
    }
}
int check(){
     int sum=0;//0个连通域
     memset(vis,0,sizeof(vis));//一开始都没有访问过
     for(int i=0;i<7;i++){//从0到6去看
       if(sel[i]==1&&vis[i]==0) {//曹,这个地方等于判断是==
        sum++;
        vis[i]=1;
        dfs(i);
       }
     }
     if(sum==1)    return 1;//sum等于1表示有一个连通域
     else  return 0;
}
void change2(int x){
     memset(sel,0,sizeof(sel));
     int la=0;
     while(x){
     sel[la++]=x%2;
     x/=2;
     }
}
int main(){
    int num=0;
    N[0][1]=N[1][0]=1;
    N[1][2]=N[2][1]=1;
    N[1][6]=N[6][1]=1;
    N[2][6]=N[6][2]=1;
    N[2][3]=N[3][2]=1;
    N[3][4]=N[4][3]=1;
    N[4][5]=N[5][4]=1;
    N[6][4]=N[4][6]=1;
    N[5][6]=N[6][5]=1;
    N[5][0]=N[0][5]=1;
       for(int i=1;i<=127;i++){//7个1是127,7个0是1 sel可以从6个0一个0,变到7个1
       change2(i);
       if(check()){
        num++;
       }
   }
   cout<<num;

return 0;}

板子:

#include <stdio.h>
#include <string.h>

int N[13][13]={0};		//邻接矩阵
int flag[13];			//深搜访问标记
int sel[13];			//块是否被选择的标记

void dfs(int pos)
{
	int i;
	for (i=1;i<13;i++)
		if ( N[pos][i] && sel[i] && flag[i]==0 )	//如果与上一个的联通,且被选择,且未被标记过,则将其标记
		{
			flag[i]=1;
			dfs(i);
		}	
}

int check()							//检查集合自身的连通性
{
	int i,sum=0;
	memset(flag,0,sizeof(flag));
	for (i=1;i<13;i++)
		if (sel[i] && flag[i]==0)	//如果存在一块被选择,且该块未被之前的深搜访问标记过,则是新的一个独立块
		{
			sum++;					//每有一个新的独立块,sum就+1		
			flag[i]=1;
			dfs(i);
		}
		
	if (sum==1)					//如果sum等于1,就表示只有一个连通域
		return 1;
	else
		return 0;
}

int main()
{
	//邻接的赋值
	//
	///
	
	//选择组合

	printf("%d\n",count);

	return 0;
}

这是后面剪邮票代码:用板子解决

#include <stdio.h>
#include <string.h>

int N[13][13]={0};		//邻接矩阵
int flag[13];			//深搜访问标记
int sel[13];			//块是否被选择的标记

void dfs(int pos)
{
	int i;
	for (i=1;i<13;i++)
		if ( N[pos][i] && sel[i] && flag[i]==0 )	//如果与上一个的联通,且被选择,且未被标记过,则将其标记
		{
			flag[i]=1;
			dfs(i);
		}	
}

int check()							//检查集合自身的连通性
{
	int i,sum=0;
	memset(flag,0,sizeof(flag));
	for (i=1;i<13;i++)
		if (sel[i] && flag[i]==0)	//如果存在一块被选择,且该块未被之前的深搜访问标记过,则是新的一个独立块
		{
			sum++;					//每有一个新的独立块,sum就+1		
			flag[i]=1;
			dfs(i);
		}
		
	if (sum==1)					//如果sum等于1,就表示只有一个连通域
		return 1;
	else
		return 0;
}

int main()
{
	int i,j,k,p,q;
	int count=0;

	for (i=1;i<=11;i++)				//左右邻接
		if ( i!=4 && i!=8 )
			N[i][i+1]=N[i+1][i]=1;
	
	for (i=1;i<=8;i++)				//上下邻接
		N[i][i+4]=N[i+4][i]=1;	
	
	for (i=1;i<13-4;i++)
		for (j=i+1;j<13-3;j++)
			for (k=j+1;k<13-2;k++)
				for (p=k+1;p<13-1;p++)
					for (q=p+1;q<13;q++)
					{
						memset(sel,0,sizeof(sel));
						sel[i]=1, sel[j]=1,	sel[k]=1, sel[p]=1,	sel[q]=1;
					
						if (check())
							count++;
					}

	printf("%d\n",count);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值