记 X 为当前精力,Y为当前经验,我们先从 X = initialEnergy 与 Y = initialExperience 开始比赛。若 X <= energy[i],那么我们一开始至少需要增加 energy[i] - X + 1的精力,才能让现在的精力刚好超过对手 i 。若 Y <= experience[i],那么我们一开始至少需要增加 experience[i] - Y + 1 的经验,才能让现在的经验刚好超过对手 i 。用ans表示需要训练的最少小时数目。
class Solution {
public:
int minNumberOfHours(int X, int Y, vector& energy, vector& experience) {
int n = energy.size();
int ans = 0;
for (int i = 0; i < n; i++) {
if (X <= energy[i]) {
int t = energy[i] - X + 1;
X += t;
ans += t;
}
if (Y <= experience[i]) {
int t = experience[i] - Y + 1;
Y += t;
ans += t;
}
X -= energy[i];
Y += experience[i];
}
return ans;
}
};
首先使用一个数组记录0-9出现的次数,在满足回文数的条件下,最大的数出现在最前面更好,所以从9开始添加数字,如果计数每超过2就可以在前面和后面个添加一个9,最中间会选择从9-0中最大的单个数字,即计数%2==1,由于不能有前导0,需要使用一个flag标记前面是否有数字,而且还可能存在全是0的情况,此时需要输出"0"
class Solution {
public:
string largestPalindromic(string num) {
int n = num.size();
int a[10];
memset(a, 0, sizeof(a));
for(int i = 0; i < n; i++){
a[num[i] - '0']++;
}
int flag = 0;
string result = "", result2 = "";
for(int i = 9; i >= 0; i--){
for(int j = 0; j < a[i] / 2; j++){
if(i != 0)flag = 1;
if(i == 0 && !flag)break;
result += '0' + i;
}
}
result2 = result;
reverse(result2.begin(), result2.end());
for(int i = 9; i >= 0; i--){
if(a[i] % 2 == 1){
result += '0'+i;
break;
}
}
if(result.size() == 0)return "0";
return result + result2;
}
};
实际上就是求长度为 K 的区间中最少有几个" W ",用双指针枚举所有长度为 K 的区间并取最小值即可。
class Solution {
public:
int minimumRecolors(string blocks, int k) {
int n = blocks.size();
int cnt = 0;
for (int i = 0; i < k; i++) if (blocks[i] == 'W') cnt++;
int ans = cnt;
for (int i = 1; i + k - 1 < n; i++) {
if (blocks[i - 1] == 'W') cnt--;
if (blocks[i + k - 1] == 'W') cnt++;
ans = min(ans, cnt);
}
return ans;
}
};
动态规划
1.题目的要求是将所有的1移动到最左侧;
2.f[i]表示为重新排序s[0,i]所需的秒数;
3.s[i]='0'时,f[i]=f[i-1],不需要额外移动;
4.s[i]='1'时,前面如果没有0,不需要移动,
前面如果有一个挨着的1,需要将1移走后,再移动当前的1;
递推公式为: f[i]=max(f[i-1]+1, pre0)
class Solution {
public:
int secondsToRemoveOccurrences(string s) {
int n = s.size();
vector f(n);
int pre0 = (s[0] == '0');
for (int i = 1; i < n; i++) {
if (s[i] == '0') {
f[i] = f[i - 1];
pre0++;
} else if (pre0 > 0) {
f[i] = max(f[i - 1] + 1, pre0);
}
}
return f[n - 1];
}
};
双指针(实际上是单指针)从头到尾遍历,是 P 就计数,是 A 就更新最大值,这里需要注意的边界就是当 i = -1 时会更新一次最大值,所以需要添加一个判断。
#include
#include
using namespace std;
int main()
{
int t;
cin >> t;
while (t -- )
{
int n;
string str;
cin >> n >> str;
int res = 0;
for (int i = str.size() - 1; i >= 0; i -- )
{
int tmp = 0;
while (str[i] == 'P') i -- , tmp ++ ;
if (i >= 0) res = max(res, tmp);
}
cout << res << endl;
}
return 0;
}
对于每一个字符串只需要将他们转化一种形式,比如说223132这个字符串,转换一下是001110,那么只需要在哈希表中存储1110即可,前缀0可以不用存储,对于每次查询也将前缀零不存储然后输出一下每个键所对用的值即可。
#include
#include
using namespace std;
unordered_map ma;
int main(){
int t;
cin >> t;
while(t --){
char ar[2];
string s1 , s2 = "";
cin >> ar >> s1;
for(int i = 0; i < s1.size(); i ++ ){
if(s1[i] % 2 == 0) s2 += "0";
else s2 += "1";
}
string s3 = "";
for(int i = 0;i < s2.size(); i ++ ){
if(s2[i] != '0' || i == s2.size() - 1){
for(i ; i < s2.size(); i ++ )s3 += s2[i];
}
}
if(*ar == '+') ma[s3] ++;
else if(*ar == '-') ma[s3] --;
if(*ar == '?'){
cout << ma[s3] << endl;
}
}
}