【问题描述】
小蓝要用七段码数码管来表示一种特殊的文字。
在这里插入图片描述
上图给出了七段码数码管的一个图示,数码管中一共有 7 段可以发光的二 极管,分别标记为 a, b, c, d, e, f, g。
小蓝要选择一部分二极管(至少要有一个)发光来表达字符。在设计字符 的表达时,要求所有发光的二极管是连成一片的。
例如: b 发光,其他二极管不发光可以用来表达一种字符。
例如: c 发光,其他二极管不发光可以用来表达一种字符。这种 方案与上 一行的方案可以用来表示不同的字符,尽管看上去比较相似。
例如: a, b, c, d, e 发光, f, g 不发光可以用来表达一种字符。
例如: b, f 发光,其他二极管不发光则不能用来表达一种字符,因为发光 的二极管没有连成一片。
请问,小蓝可以用七段码数码管表达多少种不同的字符?
【答案提交】 这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
思路:
因为是道填空题,所以不用考虑算法的时间效率什么的,只要能得出答案就行,这里只是其中的一种解法。
这道题可以是典型的n个数中选m个和DFS的应用的问题。这里可以试着把所有的选法(7选1,7选2…7选7)枚举出来,接着对所有的情况依次都判断一遍此时的情况是不是一个合法解,是的话总数就加一。
如何判断此时的序列是否是一个合法解,就是判断这个序列的第一个位置能否跑到此序列的其他所有点,简化成一个无向图的问题,判断下连通性。
这里用数字(1-7)代替了原本的字符(a-g),方便标记判断。例如某次n选m生成了一个序列(2,1,7,5),那就分别dfs(2,1),dfs(2,7),dfs(2,5),若都能走通就代表这是个合法情况,总次数加一。至于dfs的实现,就是纯基础走图了,不太懂的可以看下这篇文章和这篇文章,嘿嘿。
代码如下:
#include <iostream>
#include <string.h>
using namespace std;
int map[10][10],book[105],s=0,flag=0;
int judge2(int a[],int x,int sum)
{
int i;
for(i=1;i<=sum;i++)
{
if(a[i]==x)
return 1;
}
return 0;
}
void dfs(int x,int y,int b[],int sum)
{
int i;
if(x==y)
{
flag=1;
return;
}
for(i=1;i<=7;i++)
{
if(book[i]==0)
{
if(map[x][i]==1&&judge2(b,i,sum))
{
book[i]=1;
dfs(i,y,b,sum);
book[i]=0;
}
}
}
return;
}
int judge(char a[],int sum)
{
int i;
if(sum==1)
return 1;
int b[10066];
for(i=1;i<=sum;i++)
{
b[i]=a[i]-'a'+1;
}
book[b[1]]=0;
for(i=2;i<=sum;i++)
{
flag=0;
memset(book,0,sizeof(book));
dfs(b[1],b[i],b,sum);
if(flag==0)
return 0;
}
return 1;
}
void combine(int n,int m,char a[],int b[],int M)
{
int i,j;
for(i=n;i>=m;i--)
{
b[m-1]=i-1;
if(m>1)
{
combine(i-1,m-1,a,b,M);
}
else {
char ch[10005],ans=0;
for(j=M-1;j>=0;j--)
{
ch[++ans]=a[b[j]];
}
if(judge(ch,ans))
s++;
}
}
return;
}
int main()
{
char a[10005]={'a','b','c','d','e','f','g'};
int b[10005],i,n,m;
map[1][2]=1;
map[2][1]=1;
map[2][3]=1;
map[3][2]=1;
map[3][4]=1;
map[4][3]=1;
map[4][5]=1;
map[5][4]=1;
map[5][6]=1;
map[6][5]=1;
map[6][1]=1;
map[1][6]=1;
map[2][7]=1;
map[7][2]=1;
map[3][7]=1;
map[7][3]=1;
map[5][7]=1;
map[7][5]=1;
map[6][7]=1;
map[7][6]=1;
//cin>>n>>m;
n=7;
//for(i=0;i<n;i++)
//{
// cin>>a[i];
//}
for(i=1;i<=n;i++)
{
m=i;
combine(n,m,a,b,m);
}
cout<<s<<endl;
return 0;
}