两种方法表示亮暗状态:(1)普通遍历
(2)利用二进制表示
**在不用管遍历顺序的时候,不用恢复状态**
**在遍历状态和最后答案有关时,应恢复状态**
七段码上图给出了七段码数码管的一个图示,数码管中一共有7 段可以发光的二极管,分别标记为a, b, c, d, e, f, g。小蓝要选择一部分二极管(至少要有一个)发光来表达字符。在设计字符的表达时,要求所有发光的二极管是连成一片的。
例如:b 发光,其他二极管不发光可以用来表达一种字符。
例如:c 发光,其他二极管不发光可以用来表达一种字符。这种方案与上一行的方案可以用来表示不同的字符,尽管看上去比较相似。
例如:a, b, c, d, e 发光,f, g 不发光可以用来表达一种字符。
例如:b, f 发光,其他二极管不发光则不能用来表达一种字符,因为发光的二极管没有连成一片。
请问,小蓝可以用七段码数码管表达多少种不同的字符?
答:80种。
#include<bits/stdc++.h>
using namespace std;
int a[7],vis[10];
int res;
//相邻矩阵,用来记录谁和当前遍历到的某一段相连
int cs[7][7]={{0,1,0,0,0,1,0},//0
{1,0,1,0,0,0,1},//1
{0,1,0,1,0,0,1},//2
{0,0,1,0,1,0,0},//3
{0,0,0,1,0,1,1},//4
{1,0,0,0,1,0,1},//5
{0,1,1,0,1,1,0},//6
};
void dfs(int i)
{
for(int j=0;j<7;j++)
{
if(a[j]==1&&cs[i][j]==1&&vis[j]==0)
{
vis[j]=1;
dfs(j);
// vis[j]=0;
}
}
}
int main()
{
for(a[0]=0;a[0]<2;a[0]++)
for(a[1]=0;a[1]<2;a[1]++)
for(a[2]=0;a[2]<2;a[2]++)
for(a[3]=0;a[3]<2;a[3]++)
for(a[4]=0;a[4]<2;a[4]++)
for(a[5]=0;a[5]<2;a[5]++)
for(a[6]=0;a[6]<2;a[6]++)
{
int num=0;//记录从几个段点开始遍历的
memset(vis,0,sizeof(vis));
for(int i=0;i<7;i++)
{
if(a[i]==1&&vis[i]==0)
{
num++;
vis[i]=1;
dfs(i);
// vis[i]=0;可有可无
}
}
if(num==1)res++;//如果只从一个段点遍历就全部遍历完的话,说明连成一片
}
cout<<res;
return 0;
}
#include<bits/stdc++.h>
using namespace std;
int a[7],vis[10];
int num;
int res;
//相邻矩阵
int cs[7][7]={{0,1,0,0,0,1,0},//0
{1,0,1,0,0,0,1},//1
{0,1,0,1,0,0,1},//2
{0,0,1,0,1,0,0},//3
{0,0,0,1,0,1,1},//4
{1,0,0,0,1,0,1},//5
{0,1,1,0,1,1,0},//6
};
void dfs(int i)
{
for(int j=0;j<7;j++)
{
if(a[j]==1&&cs[i][j]==1&&vis[j]==0)
{
vis[j]=1;
dfs(j);
}
}
}
int main()
{
//利用二进制存储每一段的亮暗状态
for(int i=0;i<(1<<7);i++)
{
int tmp=i,cnt=0;
int num=0;
memset(vis,0,sizeof(vis));
for(int j=0;j<7;j++)
{
a[cnt++]=tmp>>j&1;
}
for(int j=0;j<7;j++)
{
if(a[j]==1&&vis[j]==0)
{
num++;
vis[j]=1;
dfs(j);
}
}
if(num==1) res++;
}
cout<<res;
return 0;
}