小米秋招笔试-算法(2019届)
第一题
-
题目是输入一个数组以及一个数,确定这个数是否能由这个数组中的某些数相加得到,输出1或者0,表示可行或不可行。
-
思路:先排序,再用bfs。
-
在牛客上有大神提示用背包去做,我试了一下,发现比之前的代码简单一些,不过思路比较有新意,在这里空间复杂度为O(N)。
-
排序+bfs+剪枝代码
#include <cstdlib> #include <string> #include <iostream> #include <fstream> #include <sstream> #include <unordered_map> #include <unordered_set> #include <map> #include <set> #include <stdio.h> #include <numeric> #include <algorithm> #include <functional> #include <stack> #include <queue> #include <cmath> #include <assert.h> #include <vector> #include <memory> #include <memory.h> using namespace std; typedef long long ll; const int MOD = 1e9 + 7; typedef unsigned char uchar; // #define G_DEBUG // 定义unordered_set<pair<int,int>, pairhash> sets时会用到 struct pairhash { public: template <typename T, typename U> std::size_t operator()(const std::pair<T, U> &x) const { return std::hash<T>()(x.first) ^ std::hash<U>()(x.second); } }; bool bfs( vector<int>& nums, int idx, int curr, int goal ) { if (curr == goal) return true; if (idx >= nums.size() || curr > goal) return false; if (nums[idx] + curr > goal) return false; bool ret = bfs( nums, idx+1, curr+nums[idx], goal ); if (!ret) ret = bfs(nums, idx + 1, curr, goal); return ret; } int main() { #ifdef G_DEBUG // 调试使用 int N = 0; ifstream file("data.txt"); file >> N; vector<int> nums( N, 0 ); for (int i = 0; i < N; i++) file >> nums[i]; int goal = 0; file >> goal; #else vector<string> strs(15); int N = 0; cin >> N; vector<int> nums( N, 0 ); for (int i = 0; i < N; i++) cin >> nums[i]; int goal = 0; cin >> goal; #endif std::sort( nums.begin(), nums.end() ); int ret = bfs( nums, 0, 0, goal ); cout << ret << endl; system("pause"); return 0; }
-
背包算法的代码
#include <cstdlib> #include <string> #include <iostream> #include <fstream> #include <sstream> #include <unordered_map> #include <unordered_set> #include <map> #include <set> #include <stdio.h> #include <numeric> #include <algorithm> #include <functional> #include <stack> #include <queue> #include <cmath> #include <assert.h> #include <vector> #include <memory> #include <memory.h> using namespace std; typedef long long ll; const int MOD = 1e9 + 7; typedef unsigned char uchar; #define G_DEBUG // 定义unordered_set<pair<int,int>, pairhash> sets时会用到 struct pairhash { public: template <typename T, typename U> std::size_t operator()(const std::pair<T, U> &x) const { return std::hash<T>()(x.first) ^ std::hash<U>()(x.second); } }; bool bag( vector<int>& nums, int goal ) { bool flag = false; vector<vector<int>> dp( 2, vector<int>(goal+1, 0) ); int len = nums.size(); for (int i = 0; i < len; i++) { flag = !flag; for (int j = nums[i]; j <= goal; j++) { dp[flag][j] = max( dp[!flag][j], dp[!flag][j-nums[i]]+nums[i] ); } } return dp[flag].back() == goal; } int main() { #ifdef G_DEBUG // 调试使用 int N = 0; ifstream file("data.txt"); file >> N; vector<int> nums(N, 0); for (int i = 0; i < N; i++) file >> nums[i]; int goal = 0; file >> goal; #else vector<string> strs(15); int N = 0; cin >> N; vector<int> nums(N, 0); for (int i = 0; i < N; i++) cin >> nums[i]; int goal = 0; cin >> goal; #endif int ret = bag( nums, goal ); cout << ret << endl; system("pause"); return 0; }
第二题
-
leetcode上有原题,当时也没想着搜索一下,没做出来。。
-
题目链接:https://blog.csdn.net/liuchonge/article/details/78346951
-
思路:使用二分法求解。
-
代码
#include <cstdlib> #include <string> #include <iostream> #include <fstream> #include <sstream> #include <unordered_map> #include <unordered_set> #include <map> #include <set> #include <stdio.h> #include <numeric> #include <algorithm> #include <functional> #include <stack> #include <queue> #include <cmath> #include <assert.h> #include <vector> #include <memory> #include <memory.h> using namespace std; typedef long long ll; const int MOD = 1e9 + 7; typedef unsigned char uchar; #define G_DEBUG // 定义unordered_set<pair<int,int>, pairhash> sets时会用到 struct pairhash { public: template <typename T, typename U> std::size_t operator()(const std::pair<T, U> &x) const { return std::hash<T>()(x.first) ^ std::hash<U>()(x.second); } }; bool canSplit( vector<int> &nums, int goal, int m ) { int count = 1; ll total = 0; for (int i = 0; i < nums.size(); i++) { total += nums[i]; if (total > goal) { total = nums[i]; count++; if (count > m) return false; } } return true; } int main() { #ifdef G_DEBUG // 调试使用 ifstream file("data.txt"); int N = 0, M = 0; file >> N >> M; vector<int> nums(N, 0); for (int i = 0; i < N; i++) file >> nums[i]; #else int N = 0, M = 0; cin >> N >> M; vector<int> nums( N, 0 ); for (int i = 0; i < N; i++) cin >> nums[i]; #endif int left = 0, right = 0; for (int i = 0; i < nums.size(); i++) { left = max(left, nums[i]); right += nums[i]; } int mid = 0; while (left < right) { mid = (left + right) / 2; if (canSplit(nums, mid, M)) right = mid; else left = mid + 1; } cout << left << endl; system("pause"); return 0; }