emmm,这次去做核酸,回来的时候就只剩12分钟,只写出来了第一题和第三题,掉大分qaq
因为这里是按照数数的奇偶性来交换数字,所以我们可以很简单地就知道把每个数位上的数字分成奇偶两组,依次把大的往前放,但这里注意检查原来此位置的数字是否能够交换,签到题,具体看代码
class Solution {
public:
int largestInteger(int num) {
string str = to_string(num);
int ans=0;
for (int i = 0; i < str.size(); i++)
for (int j = str.size()-1; j >= i; j--)
if ((str[i] - str[j])%2 == 0 && str[i] < str[j])
swap(str[i], str[j]);
for(int i=0;i<str.length();i++){
ans*=10;
ans+=(int)(str[i]-'0');
}
return ans;
}
};
因为此题给的字符串数据不是挺大的,所以枚举是一个比较容易想到的方法,也算个签到题吧,主要考个API的应用吧
主要就是找到+的位置
然后就是数据大到枚举会爆的时候,我也不会qaq
class Solution {
public:
string minimizeResult(string expression) {
int plus=0,len=expression.length(),m=INT_MAX;
string ans;
for(int i=0;i<len;i++){
if(expression[i]=='+'){
plus=i;
break;
}
}
for(int i=0;i<plus;i++){
for(int j=plus+1;j<len;j++){
if(m>sum(expression,i,j,plus)){
m=sum(expression,i,j,plus);
ans=expression.substr(0,i)+'('+expression.substr(i,plus-i)+'+'+expression.substr(plus+1,j-plus)+')'+expression.substr(j+1,expression.length()-j-1);
}
}
}
return ans;
}
//求和函数,l与r分别代表括号的位置
int sum(string str,int l,int r,int plus){
int s=0;
string n1=str.substr(0,l);
string n2=str.substr(l,plus-l);
string n3=str.substr(plus+1,r-plus);
string n4=str.substr(r+1,str.length()-r-1);
int num2=stoi(n2),num3=stoi(n3);
int num1=(n1.size()==0?1:stoi(n1));
int num4=(n4.size()==0?1:stoi(n4));
s=num1*(num2+num3)*num4;
return s;
}
};
emmm,,这题的数学证明我不会,但我是通过观察它那个示例输入来得到每次让最小值增加,最后的结果最大的结论
现在就是主要就是每次对最小值进行加1,所以很直观地优先队列的写法,但是由于效率太低了
我们其实可以考虑使用先排序后贪心的写法,具体代码如下
//优先队列
class Solution {
const int div=1e9+7;
public:
int maximumProduct(vector<int>& nums, int k) {
long long ans=1;
priority_queue<int,vector<int>,greater<int>> que;
for(auto num:nums){
que.push(num);
}
while(k--){
int n=que.top();
que.pop();
que.push(n+1);
}
while(!que.empty()){
int num=que.top();
ans=ans*num%div;
que.pop();
}
return ans;
}
};
//排序加贪心
//这个代码来自力扣
class Solution {
const int MOD = 1e9+7;
public:
int maximumProduct(vector<int>& nums, int k) {
sort(nums.begin(),nums.end());
int n = nums.size();
//排序后,当前最小值就是nums[0]
int cnt = 1 , minv = nums[0];
//利用次最小值与当前最小值的差值贪心地使得当前最小值最大,cnt为最小值的个数
for(int i=1;i<n&&k>0;i++){
int gap=nums[i]-minv;
//将次最小值变成最小值,因此,如果可以的话,前cnt个最小值都要加上次最小值与当前最小值的差值
if(gap*i<=k){
k-=gap*i;
minv=nums[i];
cnt=i+1;
}
else break;
}
long long res = 1L;
if(k>0){
//如果还有k次操作,首先将剩余的k平分给这cnt个最小值
minv+=k/cnt;
k-=(k/cnt)*cnt;
int idx=0;
//如果均分后还剩k'>0,无法完全平分给这个cnt个最小值,那么k'个数为minv+1,剩下(cnt-k')个数为minv
//后面的while循环就都是连乘代码了
while(k){
res=(res*(minv+1))%MOD;
k--;
idx++;
}
while(idx<cnt){
res=(res*minv)%MOD;
idx++;
}
}else{
int idx=0;
while(idx<cnt){
res=(res*minv)%MOD;
idx++;
}
}
while(cnt<n){
res=(res*nums[cnt])%MOD;
cnt++;
}
return (int)res;
}
};
/*
作者:feng-476
链接:https://leetcode-cn.com/problems/maximum-product-after-k-increments/solution/zhi-jie-tan-xin-by-feng-476-puzy/
*/
首先排序数组。一开始,如果花坛已经是 完整的,那么它就永远是完整的了(因为不能拔去)。因此,可以把这些完好的花坛 除去,并统计它们的数量,返回 fcnt×fcnt即可。
否则我们
枚举出能够变成完美花坛的数量x,然后把剩下的花坛找一个最大值T_M,,使每个数都不比T_M小
思路来源:[链接](https://leetcode-cn.com/problems/maximum-total-beauty-of-the-gardens/solution/by-newhar-nk6l/)
class Solution {
public:
long long maximumBeauty(vector<int>& flowers, long long newFlowers, int target, int full, int partial) {
sort(flowers.begin(), flowers.end());
long long n = flowers.size(), sum = 0, fcnt = 0, j = (int)flowers.size() - 1, T = target - 1;
for(int i : flowers) {
sum += i;
}
long long res = 0;
/* flowers 为剩余需要成为 partial 花坛 */
while(flowers.size() && newFlowers >= 0) {
/* 数量超过 T 的花坛不需要再种花 */
while(j >= 0 && flowers[j] > T) {
sum -= flowers[j];
j--;
}
if(j >= 0) {
/* 双指针 */
while(T * (j + 1) - sum > newFlowers) {
--T;
while(j >= 0 && (flowers[j] > T)) {
sum -= flowers[j];
--j;
}
}
res = max(res, T * partial + (n - (long long)flowers.size()) * full);
}
newFlowers -= max(0, target - flowers.back());
if(j == (int)flowers.size() - 1) {
sum -= flowers[j];
j--;
}
flowers.pop_back();
}
/* 所有花坛都是 full */
if(newFlowers >= 0) {
res = max(res, n * full);
}
return res;
}
};