题目:七段码(蓝桥OJ 595)

问题描述:

解题思路:
        枚举每一种可能组合(可以使用二进制数表示,每一个二进制就是一种组合),在判断是否符合题目要求的每一个发光灯管相邻(使用并查集方法确定,当每一个发光管属于同一领导则符合题目要求)。

题解:

#include <bits/stdc++.h>
using namespace std ;

#define n 7
//abcdefg
//0123456
vector <int > edge[n] =//每一个灯管的相邻编号
{
    {1, 5}, //0的相邻编号
    {0, 2, 6},  //1
    {1, 3, 6},  //2
    {2, 4}, //3
    {3, 5, 6},  //4
    {0, 4, 6},  //5
    {1, 2, 4, 5},   //6
};

int f[n] ;
int Find (int x )//找到最高领导
{
    if(f[x] == x) return x;
    f[x] = Find(f[x]) ;//压缩路径,提高效率
    return f[x];
}

int check (int x)//检查该组合x是否符合,即每一个灯管都有同一个最高领导
{

    for (int i = 0 ; i  < n ; ++ i)//n为7,7个灯管
    {
        f[i] = i ;//初始老板为自己
    }

    for (int i = 0 ; i < n ; ++ i)//枚举所有编号灯管
    {
        if ((x >> i) & 1)//括号表示该组合x第i位上灯亮(即i编号灯管亮)
        {

            for(int j : edge[i])//枚举i灯管的相邻灯管
            {
                if((1 << j) &x)//括号表示该组合x的i灯管存在相邻的j灯管亮
                {
                    //使i编号与j编号的最高领导为同一个
                    int ti = Find (i), tj = Find (j) ;
                    f[ti] = tj ;
                }
            }
        }
    }

//自此完成该组合最高领导合并。即相邻的灯泡都有同一领导,如果所有灯泡都相邻,那将有相同领导
    int t = -1 ;
    for (int i = 0 ; i < n ; ++ i)
    {
        if ((1 << i) &x )//i灯管亮时
        {

            if (t == -1)
            {
                t = Find (i) ;//将i灯管的最高领导赋给t
            }
            else
            {
                if (t != Find (i)) return 0 ;//存在不同最高领导的灯管。即说明灯管不相邻,停止循环并返回0,表明该组合存在不相邻灯管
            }
        }
    }
    return 1 ;
}
int main ()
{
    int ans = 0 ;
    for (int i = 1 ; i < (1 << n) ; ++ i)//枚举所有可能的二进制数(1 << n表示2^n)
    {
        if (check (i) == 1)
        {
             ++ans ;
        }
    }

    printf ("%d", ans) ;

    return 0 ;
}

知识点:枚举子集,并查集

附:并查集模板:

        

#include<bits/stdc++.h>
using namespace std;

const int N = 1e7 + 10;
int f[N];//f[i]表示i的最高领导 
int Find(int x)
{
    if(f[x] == x) return x ;//当老板为自己时即是最高领导 
    f[x] = Find(f[x]);//压缩路径。记录当时的最高领导,不需要每次都重复到执行相同次数** 
	return f[x]; 
}

void And(int x, int y)//合并xy,使其拥有共同领导 
{
	x = Find(x);//找到x的最高领导 
	y = Find(y);//找到y的最高领导 
	f[x] = y;//让原x的最高领导有一个领导,这样原xy就有一个共同最高领导 **
//	printf("%d%d%d",x ,f[x]); 
	
}

int main()
{
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); 
 
	int n, m;cin >> n >> m;
	
	for(int i = 1; i <= n; i++)
	{
		f[i] = i;//让一开始领导都是自己本身 
	}	
	while(m--)
	{
		int q, x, y;cin >> q >> x >> y;
			 
		if(q == 1){
			//输入一表示将xy合并
			And(x, y); 
	 
		}
		else{
			x = Find(x);
			y = Find(y);
	 
			if(x == y){				 
			 	puts("YES"); //使用cout会存在缓存,不会立即输出,程序结束时才会输出 
			}
			else{
				puts("NO"); 
			}
		}
	}
	return 0;
} 

 

        说明:从1到100的数组,最多执行10此操作。输入1表示合并(x,y同一最高领导),输入1以外表示查询是否同一最高领导 。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值