C、5219每个小孩最多能分到多少糖果
给你一个 下标从 0 开始 的整数数组 candies 。数组中的每个元素表示大小为 candies[i] 的一堆糖果。你可以将每堆糖果分成任意数量的子堆 ,但 无法 再将两堆合并到一起。
另给你一个整数 k 。你需要将这些糖果分配给 k 个小孩,使每个小孩分到 相同 数量的糖果。每个小孩可以拿走至多一堆 糖果,有些糖果可能会不被分配。
返回每个小孩可以拿走的 最大糖果数目 。
提示:
- 1 <= candies.length <= 105
- 1 <= candies[i] <= 107
- 1 <= k <= 1012
class Solution {
public:
//判断mid是否满足
bool C(int mid, vector<int>& candies, long long k) {
if(mid == 0) return true;
long long ans = 0;
rep(0, candies.size()) {
ans += candies[i] / mid;
}
return ans >= k;
}
int maximumCandies(vector<int>& candies, long long k) {
int lb = 0, ub = 1e7;
int mid = 0;
while(ub - lb > 1) {
mid = (lb + ub) / 2;
if(C(mid, candies, k)) lb = mid;
else ub = mid;
}
//就是这个地方卡了
if(C(ub, candies, k)) return ub;
else return lb;
}
};
D、5302加密解密字符串
给你一个字符数组 keys ,由若干 互不相同 的字符组成。还有一个字符串数组 values ,内含若干长度为 2 的字符串。另给你一个字符串数组 dictionary ,包含解密后所有允许的原字符串。请你设计并实现一个支持加密及解密下标从 0 开始字符串的数据结构。
字符串加密按下述步骤进行:
-
对字符串中的每个字符 c ,先从 keys 中找出满足 keys[i] == c 的下标 i 。
-
在字符串中,用 values[i] 替换字符 c 。
字符串解密按下述步骤进行:
-
将字符串每相邻 2 个字符划分为一个子字符串,对于每个子字符串 s ,找出满足 values[i] == s 的一个下标 i 。如果存在多个有效的 i ,从中选择任意 一个。这意味着一个字符串解密可能得到多个解密字符串。
-
在字符串中,用 keys[i] 替换 s 。
实现 Encrypter 类:
-
Encrypter(char[] keys, String[] values, String[] dictionary) 用 keys、values 和 dictionary 初始化 Encrypter 类。
-
String encrypt(String word1) 按上述加密过程完成对 word1 的加密,并返回加密后的字符串。
-
int decrypt(String word2) 统计并返回可以由 word2 解密得到且出现在 dictionary 中的字符串数目。
提示:
-
1 <= keys.length == values.length <= 26
-
values[i].length == 2
-
1 <= dictionary.length <= 100
-
1 <= dictionary[i].length <= 100
-
所有 keys[i] 和 dictionary[i] 互不相同
-
1 <= word1.length <= 2000
-
1 <= word2.length <= 200
-
所有 word1[i] 都出现在 keys 中
-
word2.length 是偶数
-
keys、values[i]、dictionary[i]、word1 和 word2 只含小写英文字母
-
至多调用 encrypt 和 decrypt 总计 200 次
这是我TLE的代码,总结就是别想优化的事,这种O难求的题当想着优化的那一刻就g了,代码还越改越乱。。
#include<bits/stdc++.h>
class Encrypter {
public:
vector<char> keys;
vector<string> values;
vector<string> dictionary;
vector<int> idx;
map<string, vector<int>> v_idx;
Encrypter(vector<char>& keys, vector<string>& values, vector<string>& dictionary) {
this->keys = keys;
this->values = values;
this->dictionary = dictionary;
for(int i = 0; i < 26; ++i) this->idx.push_back(-1);
for(int i = 0; i < keys.size(); ++i) {
int num = keys[i] - 'a';
this->idx[num] = i;
}
for(int i = 0; i < values.size(); ++i) {
if(this->v_idx.find(values[i]) == this->v_idx.end()) {
vector<int> tmp;
tmp.push_back(i);
this->v_idx[values[i]] = tmp;
}
else {
this->v_idx[values[i]].push_back(i);
}
}
sort(this->dictionary.begin(), this->dictionary.end());
}
string encrypt(string word1) {
string ans;
for(int i = 0; i < word1.size(); ++i) {
int q = word1[i] - 'a';
if(this->idx[q] != -1) {
ans += this->values[this->idx[q]];
}
}
return ans;
}
void dfs(int now, string word2, string tmp, int &cnt) {
if(now == word2.size() / 2) {
if(upper_bound(this->dictionary.begin(), this->dictionary.end(), tmp) - lower_bound(this->dictionary.begin(), this->dictionary.end(), tmp) >= 1) ++cnt;
return;
}
string ne = word2.substr(now * 2, 2);
for(int j = 0; j < this->v_idx[ne].size(); ++j) {
string nn = tmp + this->keys[this->v_idx[ne][j]];
dfs(now + 1, word2, nn, cnt);
}
return;
}
int decrypt(string word2) {
int cnt = 0;
dfs(0, word2, "", cnt);
return cnt;
}
};
后来的标准写法,不得不说,静下心来思路又清晰,代码又简洁,复杂度都是线性。
#include<bits/stdc++.h>
class Encrypter {
public:
unordered_map<char, string> mp;// keys和values的映射
unordered_map<string, int> cnt;// 保存解密dictionary的结果
Encrypter(vector<char>& keys, vector<string>& values, vector<string>& dictionary) {
for(int i = 0; i < keys.size(); ++i) mp[keys[i]] = values[i];
for(auto &i : dictionary) ++cnt[encrypt(i)];
}
string encrypt(string word1) {
string ans;
for(auto &i : word1) ans += mp[i];
return ans;
}
int decrypt(string word2) { return cnt[word2];}
};