蓝桥杯-----七段码

题目描述:
在这里插入图片描述
解题心路:在读完这道题,我的思路基本上定格在了图,dfs,并查集上,实际解法也大致相同,但是就是这种思路下实在想不出如何去解决问题,可能是因为我太菜,参考了几个博客之后,我又深思熟虑之后终于有所领悟到其中的精髓,结合图分析:(具体实现直接上代码)
代码部分:

#include"iostream"
using namespace std;
int ans,fa[10];//fa[]父亲节点
int lamp[10],cn[10][10];//lamp[]表示灯1~7开关
void inti(){//a==1,b==2,c==3,d==4,e==5,f==6,g==7
	cn[1][2]=cn[1][6]=1;
	cn[2][1]=cn[2][3]=cn[2][7]=1;
	cn[3][2]=cn[3][4]=cn[3][7]=1;
	cn[4][3]=cn[4][5]=1;
	cn[5][4]=cn[5][7]=cn[5][6]=1;
	cn[6][5]=cn[6][1]=cn[6][7]=1;
	//7可以不用存了之前在1~6都对7进行了相应的存储,达到了效果(无向图特性) 
}//存图(邻接表) 
int find_fa(int i){//并查集 
	if(fa[i]==i)
	return fa[i];
	else 
	fa[i]=find_fa(fa[i]);//路径压缩 
	return fa[i];
}
int dfs(int t){
	if(t>7){
		for(int i=1;i<=7;i++)//初始化
		fa[i]=i;
		for(int i=1;i<=7;i++)
		for(int j=1;j<=7;j++){
			if(lamp[i]&&lamp[j]&&cn[i][j]){
				int fa_a=find_fa(i);
				int fa_b=find_fa(j);
				if(fa_a!=fa_b) fa[fa_a]=fa_b;
			}
		}
		int cnt=0;//标记开了的灯所在集合个数(其实就是记录多少个不连通的灯管) 
		for(int i=1;i<=7;i++)
		if(lamp[i]&&fa[i]==i)//表示所有开了的灯都在一个集合里(好好理解) 
		cnt++;
		if(cnt==1)//所开的灯都连通则说明灯有效
		ans++;
		return 0;
	}
	//这四句话非常重要: 
	lamp[t]=1;//表示为开灯 
	dfs(t+1);
	lamp[t]=0;//表示为关灯 
	dfs(t+1);
	//典型的二叉树搜索,其实也是图搜索
	//我对于t>7的理解是搜索到根部再递归(重在理解) 
}
int main(){
	inti();//初始化图 
	dfs(1);
	cout<<ans;
	return 0;
} 

最近刚刚对算法有一定的认知,突发奇想,想写写博客,写得不是很好,有什么不好的地方希望大佬加以指正,谢谢😄😊!!
对并查集不是很熟练的同学可以点击这个链接(没错也是我这个小白写的,写的不是很好,多多指教)
https://blog.csdn.net/weixin_51341430/article/details/115585190?spm=1001.2014.3001.5501
这个博主的图特别有意思建议收藏:(直接图解题,俗称肉眼观察法hh😂)
点击跳转链接

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值