título: A 338ª competição semanal
data: 2023-03-29 16:31:08
categorias: Competição semanal Leetcode
mathjax: true
338º jogo semanal
Soma máxima de K itens
Ganancioso, basta escolher de acordo com 1, 0, -1
class Solution {
public:
int kItemsWithMaximumSum(int numOnes, int numZeros, int numNegOnes, int k) {
int res = 0;
if(k<=numOnes) return k;
else if(numOnes+numZeros>=k) return numOnes;
else return numOnes - (k - numOnes - numZeros);
}
};
subtração de números primos
Primeiro peneire os números primos dentro de 1000, pois a faixa de valores é relativamente pequena, você pode peneirar da forma que quiser. Como o título exige uma diminuição estrita, de acordo com a ideia gananciosa, tornamos cada número o menor possível sob a condição de aumentar.
class Solution {
public:
bool primeSubOperation(vector<int>& nums) {
vector<int>p;
for(int i=2;i<=1010;++i)
{
int st = 1;
for(int j =2;j*j<=i;++j)
if(i%j == 0) st = 0;
if(st == 1) p.push_back(i);
}
int lst = 0;
for(int i = 0;i<nums.size();++i)
{
int st = 0;
for(int j = p.size()-1;j>=0;j--)
{
if(p[j]< nums[i] && nums[i] - p[j] > lst)
{
lst = nums[i] - p[j];
st = 1;
break;
}
}
if(st == 0)
{
if(nums[i] > lst) lst = nums[i];
else return false;
}
}
return true;
}
};
Número mínimo de operações para tornar todos os elementos do array iguais
Ordene a matriz de inteiros. Se você quiser mudar para x, encontre o primeiro número maior ou igual a x na matriz classificada. O subscrito desse número é j, e o número de transformações é: t ∗ x − soma [ j − 1 ] + soma [ N ] − soma [ j − 1 ] − ( N − j + 1 ) ∗ xt *x - soma[j-1] + soma[N] - soma[j-1] - (N - j + 1) * xt∗x−s u m [ j−1 ]+s u m [ N ]−s u m [ j−1 ]−( N−j+1 )∗x
Preste atenção aos julgamentos de limites ao implementar.
#include <algorithm>
class Solution {
public:
vector<long long> minOperations(vector<int>& num, vector<int>& queries) {
vector<int>nums = num;
sort(nums.begin(),nums.end());
vector<long long>sum(1000010,0);
for(int i=0;i<nums.size();++i)
if(i == 0)sum[i] =nums[i];
else sum[i] =sum[i-1]+nums[i];
vector<long long>ans;
for(int i=0;i<queries.size();++i)
{
if(nums.size()==1) ans.push_back(abs(queries[i] - nums[0]));
else
{
long long t = lower_bound(nums.begin(),nums.end(),queries[i])-nums.begin();
long long x =0 ,y = 0;
if(t > 0) x = t * queries[i] - sum[t-1];
if(t == 0) y = sum[nums.size()-1] - (nums.size() - t) * queries[i];
else if(t <= nums.size()-1) y = sum[nums.size()-1] - sum[t-1] - (nums.size() - t) * queries[i];
ans.push_back(x + y);
}
}
return ans;
}
};
coletar moedas na árvore
Fácil de encontrar:
- Para nós folha (ramificação) sem moedas de ouro, não tem efeito na resposta final.
- Depois de deletar todas as folhas (galhos) sem moedas de ouro, uma nova árvore é obtida. Neste momento, não importa de qual nó a coleta comece, a resposta final é a mesma
De acordo com as conclusões acima, você pode usar a classificação topológica para excluir ramificações redundantes e, em seguida, executar a classificação topológica novamente para obter a resposta final.
class Solution {
public:
int collectTheCoins(vector<int>& coins, vector<vector<int>>& edges) {
const int N = coins.size(),M = edges.size()*2;
vector<int>e(M, 0),h(N, -1),ne(M, 0);
vector<int>d(N, 0),dist(N, 0),st(N, 1);
int idx = 0;
function<void(int, int)> add = [&](int a, int b)
{
e[idx] = b;
ne[idx] = h[a];
h[a] = idx ++;
};
for(auto p: edges)
{
int a = p[0], b = p[1];
add(a, b), add(b, a);
d[a] ++, d[b] ++;
}
int n = coins.size();
queue<int>q;
for(int i = 0; i < n; i ++ )
if(d[i] == 1 && coins[i] == 0) q.push(i);
while(!q.empty())
{
int p = q.front();
q.pop();
st[p] = 0;
for(int i = h[p]; i!=-1;i=ne[i])
{
int j =e[i];
if(--d[j] == 1 && coins[j] == 0) q.push(j);
}
}
for(int i = 0; i < n; ++ i) d[i] = 0;
for(auto p: edges)
{
int a = p[0], b = p[1];
if(st[a] == 0 || st[b] == 0) continue;
d[a] ++, d[b] ++;
}
while(!q.empty()) q.pop();
for(int i=0;i<n;++i)
if(d[i] == 1 && st[i] == 1)
{
q.push(i);
dist[i] = 0;
}
int mx = -1,mxid = -1;
while(!q.empty())
{
auto p = q.front();
q.pop();
for(int i = h[p];i!=-1;i=ne[i])
{
int j = e[i];
d[j] --;
if(d[j] == 1)
{
q.push(j);
dist[j] = dist[p] + 1;
}
if(dist[j] >= mx) mx = dist[j], mxid = j;
}
}
int cnt = 0;
function<void(int, int)> dfs = [&](int u, int fa)
{
for(int i = h[u];i!=-1;i=ne[i])
{
int j = e[i];
if(j == fa) continue;
if(st[j] == 0) continue;
if(dist[j] < 2) continue;
cnt ++;
dfs(j ,u);
}
};
if(mxid == -1) return 0;
dfs(mxid, -1);
return cnt * 2;
}
};