Leetcode 5281. 使结果不超过阈值的最小除数

又一次参赛,除了第一道Easy题和第二道Medium外,剩下的两道在有限时间内,要么没思路,要么思路不对,超时,要么有思路调试出错,还需多加练习!

(这次的第三题,在循环从1开始,直到找到满足地为止,早就预料到会超时,提交之后果然Time out,切换思路,二分查找,但是有限时间内,没有调试正确!这里做一下笔记,以便学习和提高!)

实际代码记录:

  1 #include <iostream>
  2 #include <vector>
  3 #include <map>
  4 #include <algorithm>
  5 #include <math.h>
  6 
  7 using namespace std;
  8 void init(vector<vector<int> > &vc,int m,int n)
  9 {
 10     vector<int> level;
 11     level.resize(n);
 12     vc.resize(m,level);
 13     for (int i = 0; i < m; i++) {
 14         for (int j = 0; j < n; j++) {
 15             cin >> vc[i][j];
 16         }
 17     }
 18 }
 19 
 20 void printvc(const vector<vector<int> > vc) {
 21     for (int i = 0; i < vc.size(); i++)
 22     {
 23         for (int j = 0; j < vc[0].size(); j++)
 24         {
 25             cout << vc[i][j] << " ";
 26         }
 27         cout << endl;
 28     }
 29 }
 30 
 31 int subtractProductAndSum(int n) {
 32     if (n < 10) return 0;
 33     int he = 0, ji = 1;
 34     int temp;
 35     temp = n % 10;
 36     while (n) {
 37         he += temp;
 38         ji *= temp;
 39         n = n / 10;
 40         temp = n % 10;
 41     }
 42     cout << "he is " << he << endl;
 43     cout << "ji is " << ji << endl;
 44     return ji - he;
 45 }
 46 
 47 vector<vector<int>> groupThePeople(vector<int>& groupSizes) {
 48     vector<vector<int>> res;
 49     vector<int> level;
 50     vector<int> a;
 51     a.resize(groupSizes.size(),0);
 52     int count = 0;
 53     while(count<groupSizes.size()){
 54         for (int i = 0; i < groupSizes.size(); i++)
 55         {
 56             if (a[i] == 0) //可用
 57             {
 58                 level.push_back(i);
 59                 a[i] = 1;
 60                 count++;
 61                 if (level.size() != groupSizes[i])
 62                 {
 63                     for (int j = i + 1; j < groupSizes.size(); j++)
 64                     {
 65                         if (groupSizes[j] == groupSizes[i] && a[j] == 0) {
 66                             level.push_back(j);
 67                             a[j] = 1;
 68                             count++;
 69                             if (level.size() == groupSizes[i])
 70                                 break;
 71                         }
 72                     }
 73                 }
 74                 
 75                 res.push_back(level);
 76                 level.clear();
 77                 break;
 78             }
 79         }
 80     }
 81     
 82     return res;
 83 }
 84 
 85 bool isornot(vector<int> nums, int number, int threshold);
 86 int smallestDivisor(vector<int>& nums, int threshold) {
 87     //先排序
 88     sort(nums.begin(), nums.end());
 89     //然后二分查找一个满足的值
 90     int low = 1;
 91     int high = nums[nums.size() - 1];
 92     int res=nums[0];
 93     int mid;
 94     while (low <= high) {
 95         mid = (low + high) / 2;
 96         if (!isornot(nums, mid, threshold))  //如果mid不符合,说明,答案在右半个区间,更新low
 97             low = mid + 1;
 98         else  //否则,在左半个区间,更新high
 99         {
100             high = mid - 1;
101             res = mid;
102         }
103     }
104     return res;
105 }
106 
107 bool isornot(vector<int> nums,int number, int threshold) {
108     int sum = 0;
109     for (int i = 0; i < nums.size(); i++)
110     {
111         sum += ceil(nums[i] / (number*1.0));
112         //cout<< number<<" sum is "<<sum<<endl;
113         if (sum > threshold)
114             return false;
115     }
116     return true;
117 }
118 int main()
119 {
120 //    vector<vector<int> > vc;
121     //init(vc,3,4);
122     //printvc(vc);
123 
124     /* 第一题
125     int n;
126     cin >> n;
127     cout << subtractProductAndSum(n) << endl;
128     return 0;
129     */
130 
131     /* 第二题
132     vector<int> a;
133     int n;
134     cin >> n;
135     a.resize(n);
136     for (int i = 0; i < n; i++)
137     {
138         cin >> a[i];
139     }
140     vector<vector<int>> res;
141     res = groupThePeople(a);
142     for (int j = 0; j < res.size(); j++)
143     {
144         for (int k = 0; k < res[j].size(); k++)
145         {
146             cout << res[j][k] << " ";
147         }
148         cout << endl;
149     }
150     return 0;
151     */
152 
153     /*
154     vector<int> a;
155     int n;
156     cin >> n;
157     int threshold;
158     cin >> threshold;
159     a.resize(n);
160     for (int i = 0; i < n; i++)
161     {
162         cin >> a[i];
163     }
164     int res = smallestDivisor(a,threshold);
165     cout << res << endl;
166 
167     return 0;
168     */
169 
170     return 0;
171 }
View Code

第166周赛题目列表: 

分析:

  第一题很简单,直接提出数字n的每一位,进行求和和求积,然后返回差即可!

  第二题是说,每个人站在一个确定人数的分组里,那么,加入这个人在3个人的组group里,group.size()就等于每个人身上的号码。

  第三题,就是一开始遍历所有值,但是超时,然后采用二分搜索的方式进行求解:

题目三:

  给你一个整数数组 nums 和一个正整数 threshold  ,你需要选择一个正整数作为除数,然后将数组里每个数都除以它,并对除法结果求和。

  请你找出能够使上述结果小于等于阈值 threshold 的除数中 最小 的那个。

  每个数除以除数后都向上取整,比方说 7/3 = 3 , 10/2 = 5 。

  题目保证一定有解。

示例 1:

  输入:nums = [1,2,5,9], threshold = 6
  输出:5
  解释:如果除数为 1 ,我们可以得到和为 17 (1+2+5+9)。
  如果除数为 4 ,我们可以得到和为 7 (1+1+2+3) 。如果除数为 5 ,和为 5 (1+1+1+2)。

首先写一个函数,判断一个数是否满足数组nums和阈值threshold,

 1 bool isornot(vector<int> nums,int number, int threshold) {
 2     int sum = 0;
 3     for (int i = 0; i < nums.size(); i++)
 4     {
 5         sum += ceil(nums[i] / (number*1.0));
 6         //cout<< number<<" sum is "<<sum<<endl;
 7         if (sum > threshold)
 8             return false;
 9     }
10     return true;
11 }

然后,数组确定,二分查找这样的最小值即可;

 1 int smallestDivisor(vector<int>& nums, int threshold) {
 2     //先排序
 3     sort(nums.begin(), nums.end());
 4     //然后二分查找一个满足的值
 5     int low = 1;
 6     int high = nums[nums.size() - 1];
 7     int res=nums[0];
 8     int mid;
 9     while (low <= high) {
10         mid = (low + high) / 2;
11         if (!isornot(nums, mid, threshold))  //如果mid不符合,说明,答案在右半个区间,更新low
12             low = mid + 1;
13         else  //否则,在左半个区间,更新high
14         {
15             high = mid - 1;
16             res = mid;
17         }
18     }
19     return res;
20 }

题目给定的值,一定满足有解,所以不用考虑无解的情况,因此,low=1,high=max(nums),即当所有的商为1时,最终和最小,一定小于等于阈值;

(很遗憾,当时思路对,但是没有调试出来!)

题目四:

  后续补充~~~

原文地址:https://www.cnblogs.com/cnyulei/p/12005631.html