小米秋招笔试-算法(2019届)

小米秋招笔试-算法(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;
      }
    

猜你喜欢

转载自blog.csdn.net/u012526003/article/details/82794263