微软SWE暑期实习一面
题目
7个晶体管上的灯的亮暗可以组成0-9的任意一个数字。假设有n组晶体管,每组晶体管中至少有一个亮,可能存在坏了的晶体管。
假设有2组晶体管,第一组是数字2,因为有坏了的可能, 2->2,2->8;其可能为2/8;第2组是数字3,其可能为3/8/9
由此可以组成{23,28,29,83,88,89}
input:n个7位数,即有n组晶体管
output:组成的数字,例如本题的{23,28,29,83,88,89}
面试思路
- 得到残缺的数字中的暗的晶体管,若包含正常数字的所有暗的晶体管,则可以变成这个数字。用set
- 得到数字之后全排列就可以得到答案
- 但是没有写出来
提示
- 数字位运算(&)就可以得到是否包含
例如:2 (1011011) 只有2和5为暗,其他为亮
8 (1111111) 全亮
2 & 8 (每一位按位与)= 2 (则可以由2拓展到8)
- 每一组晶体管都有一系列可以拓展的值(dfs,回溯)
代码
//tag: dfs,回溯,位运算 #include<bits/stdc++.h> using namespace std; vector<int> v(10) ; void init() { v[0] = 0b0111111; // 可以用二进制表示0b101100等等 v[1] = 0b0000110; v[2] = 0b1011011; v[3] = 0b1001111; v[4] = 0b1100110; v[5] = 0b1101101; v[6] = 0b1111101; v[7] = 0b0000111; v[8] = 0b1111111; v[9] = 0b1101111; } vector<vector<int>> ha; string ans; vector<string> res; void dfs(int n) { if (n == ha.size()) { //终止条件 res.push_back(ans); return; } for (int i = 0; i < ha[n].size(); i++) { //扩展新结点 ans.push_back(char(ha[n][i] + '0')); dfs(n + 1); ans.pop_back(); // 回溯 } } void d(vector<int> in) { ha.resize(in.size()); for (int i = 0; i < in.size(); i++) { for (int j = 0; j < 10; j++) { if ((in[i] & v[j])== in[i]) { ha[i].push_back(j); } } } dfs(0); } int main() { init(); vector<int> in ({0b1011011, 0b1001111}); d(in); for (int i = 0; i < res.size(); i++) { cout << res[i] << endl; } return 0; }