Problema A
A solução é uma simulação direta. Não há grandes complicações.
int main() { int linhas, colunas; cin >> linhas >> colunas; vector grade(linhas); for (int i = 0; i < linhas; i++) cin >> grade[i];
int contador = 0;
for (int i = 0; i < linhas; i++) {
for (int j = 0; j < colunas; j++) {
if (grade[i][j] == '.') {
// Lógica de contagem baseada na simulação
contador++;
}
}
}
cout << contador << endl;
return 0;
}
</details>**Problema B**
O ponto crucial é que as células umidificadas não precisam estar conectadas ao umidificadro. A abordagem é enumerar todas as pares possíveis de posições para os dois umidificadores e calcular, para cada par, quantas células são atingidas. A complexidade de tempo é O(h³ \* w³).
<details><summary>Clique para ver o código</summary>```
#include<iostream>
#include<vector>
#include<string>
#include<cstring>
using namespace std;
const int MAX_DIM = 10;
int altura, largura, alcance;
char mapa[MAX_DIM][MAX_DIM];
bool coberto[MAX_DIM][MAX_DIM];
int dirs_x[] = {0, 1, -1, 0, 0};
int dirs_y[] = {0, 0, 0, 1, -1};
int calcularCobertura(int origem_x, int origem_y) {
int contagem = 0;
for (int i = 1; i <= altura; i++) {
for (int j = 1; j <= largura; j++) {
if (!coberto[i][j] && mapa[i][j] != '#' && abs(i - origem_x) + abs(j - origem_y) <= alcance) {
coberto[i][j] = true;
contagem++;
}
}
}
return contagem;
}
int main() {
cin >> altura >> largura >> alcance;
for (int i = 1; i <= altura; i++)
for (int j = 1; j <= largura; j++)
cin >> mapa[i][j];
int maximo = 0;
for (int ux1 = 1; ux1 <= altura; ux1++) {
for (int uy1 = 1; uy1 <= largura; uy1++) {
if (mapa[ux1][uy1] == '#') continue;
for (int ux2 = 1; ux2 <= altura; ux2++) {
for (int uy2 = 1; uy2 <= largura; uy2++) {
if (ux2 == ux1 && uy2 == uy1) continue;
if (mapa[ux2][uy2] == '#') continue;
memset(coberto, 0, sizeof(coberto));
int total = calcularCobertura(ux1, uy1) + calcularCobertura(ux2, uy2);
maximo = max(maximo, total);
}
}
}
}
cout << maximo << endl;
return 0;
}
struct Posicao { int x, y, passos; bool operator<(const Posicao& outro) const { return passos < outro.passos; // Para max-heap } };
int main() { int linhas, colunas, max_passos; cin >> linhas >> colunas >> max_passos; vector grid(linhas); for (int i = 0; i < linhas; i++) cin >> grid[i];
vector<vector<bool>> visitado(linhas, vector<bool>(colunas, false));
priority_queue<Posicao> fila;
// Inicializa a fila com os pontos iniciais 'H'
for (int i = 0; i < linhas; i++) {
for (int j = 0; j < colunas; j++) {
if (grid[i][j] == 'H') {
fila.push({i, j, max_passos});
}
}
}
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
while (!fila.empty()) {
Posicao atual = fila.top();
fila.pop();
if (visitado[atual.x][atual.y]) continue;
visitado[atual.x][atual.y] = true;
if (atual.passos == 0) continue;
for (int d = 0; d < 4; d++) {
int nx = atual.x + dx[d];
int ny = atual.y + dy[d];
if (nx >= 0 && nx < linhas && ny >= 0 && ny < colunas &&
!visitado[nx][ny] && grid[nx][ny] != '#') {
fila.push({nx, ny, atual.passos - 1});
}
}
}
int total_visitado = 0;
for (int i = 0; i < linhas; i++)
for (int j = 0; j < colunas; j++)
if (visitado[i][j]) total_visitado++;
cout << total_visitado << endl;
return 0;
}
</details>**Problema D**
Um problema de contagem simples. Como o número de divisores é 9, e apenas números perfeitos quadrados têm uma quantidade ímpar de divisores, pansa-se em enumerar quadrados perfeitos. No entanto, essa abordagem direta não é viável.
Para otimizar, observa-se que a maioria desses números é da forma a²b² (onde a ≠ b, e a, b são primos), cujos divisores são a, a², b, b², ab, a²b, ab², a²b².
Além disso, existem números da forma a⁸ (a primo), cujos divisores são as potências de a de 1 a 8.
A solução é crivar os números primos e então buscar esses padrões. Os dados de teste mostram que a resposta é relativamente pequena, tornando a abordagem factível.
<details><summary>Clique para ver o código</summary>```
#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
int main() {
long long limite;
cin >> limite;
long long raiz_limite = sqrt(limite) + 1;
vector<bool> eh_primo(raiz_limite + 1, true);
vector<int> primos;
// Crivo de Eratosthenes
for (int i = 2; i <= raiz_limite; i++) {
if (eh_primo[i]) {
primos.push_back(i);
for (int j = i * i; j <= raiz_limite; j += i) {
eh_primo[j] = false;
}
}
}
long long resposta = 0;
int qtd_primos = primos.size();
// Contagem para números da forma a⁸
for (int idx = 0; idx < qtd_primos; idx++) {
long long p = primos[idx];
if (p * p * p * p * p * p * p * p <= limite) {
resposta++;
} else break;
}
// Contagem para números da forma a²b²
for (int i = 0; i < qtd_primos; i++) {
long long p1 = primos[i];
long long p1_quadrado = p1 * p1;
for (int j = i + 1; j < qtd_primos; j++) {
long long p2 = primos[j];
if (p1_quadrado * p2 * p2 <= limite) {
resposta++;
} else break;
}
}
cout << resposta << endl;
return 0;
}