一个长度13的尺子,如果在1位置刻点可以量出1和12,13三种刻度.那么至少刻几个点,可以直接量出1-13所有的长度,分别刻在哪几个位置?
注:必须是直接量。即在尺子上能找出一个1-13任意的整数长度。
写了个没什么技术含量的dfs暴力求解。一个可行解是 1, 2, 6, 10。
1 #include <iostream> 2 #include <vector> 3 #include <unordered_map> 4 using namespace std; 5 6 class Solution { 7 public: 8 vector<vector<int>> ruler(int n, vector<int> &minPath) { 9 dfs(0, n, minPath); 10 return result; 11 } 12 vector<vector<int>> result; 13 vector<int> path; 14 void dfs(int start, int n, vector<int> &minPath) { 15 if (start == n + 1) { 16 if (fullScale(path)) { 17 result.push_back(path); 18 if (path.size() < minLen) { 19 minLen = path.size(); 20 minPath = path; 21 } 22 } 23 return; 24 } 25 for (int i = start; i <= n; i++) { 26 path.push_back(i); 27 dfs(i + 1, n, minPath); 28 path.pop_back(); 29 } 30 } 31 bool fullScale(vector<int> path) { 32 if (path.size() < 4) { 33 return false; 34 } 35 unordered_map<int, int> umap; 36 umap[13]++; 37 umap[0]++; 38 for (int i = 0; i < path.size(); i++) { 39 for (int j = 0; j < i; j++) { 40 if (path[i] - path[j] < 13) { 41 umap[path[i] - path[j]]++; 42 umap[path[j]]++; 43 umap[path[i]]++; 44 umap[13 - path[i]]++; 45 umap[13 - path[j]]++; 46 } 47 if (umap.size() >= 14) { 48 return true; 49 } 50 } 51 } 52 return false; 53 } 54 private: 55 int minLen = 13; 56 }; 57 58 int main() { 59 int n = 13; 60 Solution solu; 61 vector<int> minPath; 62 vector<vector<int>> res = solu.ruler(n, minPath); 63 for (auto x : minPath) { 64 cout << x << ", "; 65 } 66 }
ref: https://en.wikipedia.org/wiki/Sparse_ruler