思路:枚举+dfs判断图是否连通
题目描述:
小蓝要用七段码数码管来表示一种特殊的文字。
上图给出了七段码数码管的一个图示,数码管中一共有 7 段可以发光的二
极管,分别标记为 a, b, c, d, e, f, g。
小蓝要选择一部分二极管(至少要有一个)发光来表达字符。在设计字符
的表达时,要求所有发光的二极管是连成一片的。
例如:b 发光,其他二极管不发光可以用来表达一种字符。
例如:c 发光,其他二极管不发光可以用来表达一种字符。这种方案与上
一行的方案可以用来表示不同的字符,尽管看上去比较相似。
例如:a, b, c, d, e 发光,f, g 不发光可以用来表达一种字符。
例如:b, f 发光,其他二极管不发光则不能用来表达一种字符,因为发光
的二极管没有连成一片。
请问,小蓝可以用七段码数码管表达多少种不同的字符?
答案:80
#include<iostream>
#include<cstring>
using namespace std;
int cnt = 0, ans = 0;
int a, b, c, d, e, f, g;
int maps[6][4], vis[6][4];
int dir[4][2] = { {-1,-1},{1,-1},{1,1},{-1,1} };//斜着走的四个方向
void init() {
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 4; j++) {
vis[i][j] = 1;
}
}
}
void creatMap() {
maps[1][2] = a, maps[2][3] = b, maps[4][3] = c;
maps[5][2] = d, maps[4][1] = e, maps[2][1] = f;
maps[3][2] = g;//建图
/*
-1 a -1
f -1 b
-1 g -1
e -1 c
-1 d -1
*/
}
void dfs(int x,int y) {
cnt--;//每访问一个相当于灭一盏灯
vis[x][y] = 0;
for (int i = 0; i < 4; i++) {
int xx = x + dir[i][0];
int yy = y + dir[i][1];
if (maps[xx][yy] == 1 && vis[xx][yy] == 1)
dfs(xx, yy);
}
}
int main() {
init();
for (a = 0; a <= 1; a++)
for (b = 0; b <= 1; b++)
for (c = 0; c <= 1; c++)
for (d = 0; d <= 1; d++)
for (e = 0; e <= 1; e++)
for (f = 0; f <= 1; f++)
for (g = 0; g <= 1; g++) {
//先枚举出每一种亮灯情况
memset(maps, -1, sizeof(maps));
creatMap();
cnt = a + b + c + d + e + f + g;//总共亮灯的数目
for (int i = 1; i < 6; i++)
for (int j = 1; j < 4; j++) {
if (maps[i][j] == 1) {
init();
dfs(i, j);//dfs判断是否连通
if (maps[2][3] == 1 && maps[4][3] == 1 && cnt > 0)
dfs(4, 3);
if (maps[2][1] == 1 && maps[4][1] == 1 && cnt > 0)
dfs(4, 1);
if (cnt == 0) ans++;
i = 6;
break;//
}
}
}
cout << ans;
return 0;
}
可能网上的更简洁吧!但我实在不甘心啊,所以废了好大功夫才把这敲了半截的代码完善好,毕竟这是我自己的思路,含着泪也要敲完。