###### tags: `BiWeekly Contest`
# BiWeekly Contest 100 (03/18)
## [2591. Distribute Money to Maximum Children](https://leetcode.com/problems/distribute-money-to-maximum-children/description/)(<font color="00b8a3">Easy</font>)
### Solution
判斷題目給出的條件
1. 每個人都至少要有1元
2. 不能有人拿到4元
限制 :
>1 <= money <= 200
>2 <= children <= 30
#### 時間複雜度 : ***O(1)***
#### 空間複雜度 : ***O(1)***
程式碼<font color="ff0000">**(改良前)**</font> :
```c++=
class Solution {
public:
int distMoney(int money, int children) {
int ans = 0;
money -= children;
if(money < 0) return -1;
while(money >= 7){
++ans;
money -= 7;
if(ans == children && money) return (children - 1);
} // while迴圈應該可以改用數學的方法做一次就好
if(money == 3 && ans && children - ans == 1) --ans;
return ans;
}
};
```
程式碼<font color="ff0000">**(改良後)**</font> :
```c++=
class Solution {
public:
int distMoney(int money, int children) {
if( money < children ) return -1;
money = money - children;
int ans = min(money / 7, children);
if(ans)
{
if((money%7 == 3 && children - ans == 1) || money > children * 7)
{
ans -= 1;
}
}
return ans;
}
};
```
## [2592. Maximize Greatness of an Array](https://leetcode.com/problems/maximize-greatness-of-an-array/)(<font color="FFC011">Medium</font>)
### 題意
將陣列重新排列後, 陣列中的值比原陣列同樣位置的值還大的數字個數
### 限制
>1 <= nums.length <= 10^5
0 <= nums[i] <= 10^9
### Solution 1
先用unordered_map計算陣列中的每個值有多少個
排序完後放到vector中(從小到大)
再利用雙指標(two pointer)
指標A從第0個開始, 指標B從第1個開始
一一配對消除, 消除的數量加到最後的答案
當指標B指到最後的時候就輸出答案
#### 時間複雜度 : ***O(nlogn)***
#### 空間複雜度 : ***O(n)***
程式碼 :
```c++=
class Solution {
public:
int maximizeGreatness(vector<int>& nums) {
vector<pair<int, int>> v;
vector<pair<int, int>> v1;
unordered_map<int, int> m;
int index = 1;
int ans = 0;
for(int i : nums){
++m[i]; // 計算數量
}
for(auto& i : m){
v.push_back({i.first, i.second});
}
sort(v.begin(), v.end());
for(auto& i : v){
v1.push_back(i);
}
// size = 1 代表只有同一種數字
// 不管怎麼移都不會比原本大
if(v.size() == 1) return 0;
// i從第0開始, index從第1開始
for(int i = 0; i < v.size(); ++i){
while(v[i].second){
//cout << v[i].first <<" " << v[i].second <<" : " << v1[index].first <<" " << v1[index].second << endl;
if(v1[index].second == 0 || index == i) index++;
if(index >= v1.size()){
return ans;
}
int temp = min(v[i].second, v1[index].second);
ans += temp;
v[i].second -= temp;
v1[index].second -= temp;
//cout << v[i].first <<" " << v[i].second <<" : " << v1[index].first <<" " << v1[index].second <<endl << ans << endl << endl;;
}
}
return ans;
}
};
```
### Solution 2
用數學的方法, 計算出現最多次的值的數量
用整個vector的size減去上面求出的數量就是答案
> [1 2 2 3 3 3 5 5 7 7 7]
> 出現最多次的是3跟7, 有3次
> 如果左移的次數小於3
> 就代表有一個3會跟左移後的3重疊, 7也是
>
>
> [1 2 2 <font color="ff0000">**3**</font> 3 3 5 5 <font color="ff0000">**7**</font> 7 7] <- <font color="ff5511">**原本的**</font>
> [2 3 3 <font color="ff0000">**3**</font> 5 5 7 7 <font color="ff0000">**7**</font> 1 2] <- <font color="ff5511">**左移2次**</font>
> >算出的答案是7
> >但應該是8, 因為少算了重複的部分
用sort過的陣列比較好想, 但實際上不用sort
#### 時間複雜度 : ***O(n)***
#### 空間複雜度 : ***O(1)***
程式碼 :
```c++=
class Solution {
public:
int maximizeGreatness(vector<int>& nums) {
unordered_map<int, int> m;
int max_cnt = 0;
for(int i : nums){
++m[i];
}
for(auto& i : m){
max_cnt = max(max_cnt, i.second);
}
return (nums.size() - max_cnt);
}
};
```
## [2593. Find Score of an Array After Marking All Elements](https://leetcode.com/problems/find-score-of-an-array-after-marking-all-elements/)(<font color="FFC011">Medium</font>)
### 題意
在陣列中尋找沒有被標記的最小值(值相同時index小優先)
將該值加入總和, 並標記該值及它左右的值
當所有值都被標記後回傳總和
### 限制
>1 <= nums.length <= 10^5
1 <= nums[i] <= 10^6
### Solution
用unordered_map紀錄每個值所在的位置
再放入priority_queue(從小排到大)
需要建立跟nums一樣大小的陣列來確認該格是否被標記
之後從最小的值開始一個一個搜尋
#### 時間複雜度 : ***O(n^2)***
#### 空間複雜度 : ***O(n)***
程式碼 :
```c++=
class Solution {
template <typename T>
class cmp
{
public:
//重載 () 運算符
bool operator()(T a, T b)
{
return a > b;
}
};
public:
long long findScore(vector<int>& nums) {
unordered_map<int, vector<int>> m; // 數字所在的index值
vector<bool> mark(nums.size()); // 紀錄是否被標記
priority_queue<int, vector<int>, cmp<int>> pq;
long long ans = 0;
int cnt = 0;
for(int i = 0; i < nums.size(); ++i){
m[nums[i]].push_back(i);
pq.push(nums[i]);
}
while(pq.size()){
if(cnt == mark.size()) return ans;
int temp = pq.top();
pq.pop();
for(auto& i : m[temp]){
if(!mark[i]){
if(i - 1 >= 0){
if(!mark[i - 1]){
++cnt;
}
mark[i - 1] = true;
}
mark[i] = true;
if(i + 1 < mark.size()){
if(!mark[i + 1]) ++cnt;
mark[i + 1] = true;
}
ans += nums[i];
++cnt;
//cout << nums[i] << " " << ans << endl;
}
}
}
return ans;
}
};
```
運用類似的想法,但priority_queue裡是儲存每個元素的index與value,運用priority_queue的特性,可以在logn的時間取得值最小的元素並標記,如果取得的元素是被標記過的,便直接捨棄。如此一來,實作程式碼會簡潔很多。
#### 時間複雜度 : ***O(nlogn)***
#### 空間複雜度 : ***O(n)***
程式碼 :
```c++=
class Solution {
public:
long long findScore(vector<int>& nums) {
int n=nums.size();
priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > pq;
vector<bool> b(n);
for(int i=0;i<n;i++){
pq.push(make_pair(nums[i], i));
}
long long ans=0;
while(!pq.empty()){
int idx=pq.top().second;
if(!b[idx]){
ans+=pq.top().first;
b[max(idx-1, 0)]=true;
b[idx]=true;
b[min(idx+1, n-1)]=true;
}
pq.pop();
}
return ans;
}
};
```
## [2594. Minimum Time to Repair Cars](https://leetcode.com/problems/minimum-time-to-repair-cars/description/)(<font color="FFC011">Medium</font>)
### 題意
找出可以洗完cars輛車的最小時間
### 限制
>1 <= ranks.length <= 10^5
1 <= ranks[i] <= 100
1 <= cars <= 10^6
### Solution
Binary Search
從 0~LLONG_MAX 中搜尋出一個時間
藉由遍歷確認能不能完成
不能的話就把時間拉長(left = mid + 1)
能的話就把時間縮短(right = mid - 1)
#### 時間複雜度 : ***O(nlogn)***
#### 空間複雜度 : ***O(1)***
程式碼 :
```c++=
class Solution {
public:
vector<int> r;
bool check(long long mid, int cars){
long long temp;
for(int i : r){
temp = mid;
temp /= i;
if(cars <= sqrt(temp)) return true;
cars -= int(sqrt(temp));
}
return false;
}
long long repairCars(vector<int>& ranks, int cars) {
for(int i : ranks){
r.push_back(i);
}
long long l = 0;
long long r = LLONG_MAX - 1;
long long mid;
while(l <= r){
// cout << l << " " << r << endl;
mid = (l + r) / 2;
if(check(mid, cars)){
r = mid - 1;
}
else{
l = mid + 1;
}
}
return max(l, r);
}
};
```
## []()(<font color="00b8a3"></font>)
### 題意
### 限制
### Solution
#### 時間複雜度 : ***O()***
#### 空間複雜度 : ***O()***
程式碼 :
```c++=
```
FFC011
ff375f