Solução por Leonardo Paes
Para esse problema usaremos a ideia de soma de prefixos, ou soma acumulada, do vetor . A ideia é, guardamos um vetor , onde significa a soma de todas as posições de de até . Por exemplo, se então . Note que a soma do intervalo pode ser escrita como . Para a solução descrita abaixo, somente a ideia será utilizada, então não criaremos tal vetor .
Vamos considerar, inicialmente, que a quantidade de números é . Então, a resposta é uma sequência de números . Analogamente, se o número não estiver presente em nenhum papel, a resposta é uma sequência que contém números escritos. Agora, garantimos que, tanto a quantidade de números , como a de números , é maior que . Então, nesses casos, sempre é possível obtermos os números e como soma de prefixos da nossa sequência, utilizando, para isso, um número seguido por um , já que .
Por fim, a observação final é: Todos os números primos maiores que são ímpares, já que todo número par maior que possui pelo menos três divisores: e ele mesmo! Como o já é ímpar, ao somarmos uma quantidade de números pares a ele, continuaremos com um número ímpar.
Prova: . Todo o número, ao ser múltiplicado por , se torna par. Neste caso, é par. Um par somado com é um ímpar, então, é ímpar.
Como é o menor par maior que 0, ao escrevermos todos os consecutivamente, estaremos, obrigatoriamente, obtendo todos os primos como somas de prefixos de tal sequência, pois estaremos somando com uma quantidade de números . Após terem acabadas as quantidades de pedacinhos de papel contendo o número , basta finalizarmos a resposta com todos os restantes.
A complexidade final será .
Código da Solução:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Noic - Iniciante - Semana 55 - Problema 2 | |
// O(N) | |
#include <bits/stdc++.h> | |
using namespace std; | |
int main(){ | |
//um representa a quantidade de 1's, e dois a quantidade de 2's | |
int n, um=0, dois=0; | |
cin >> n; | |
for(int i=1; i<=n; i++){ | |
int x; | |
cin >> x; | |
if(x==1)um++; | |
else dois++; | |
} | |
if(dois==0){ | |
for(int i=1; i<=n; i++){ | |
cout << 1 << " "; | |
} | |
return 0; | |
} | |
else if(um==0){ | |
for(int i=1; i<=n; i++){ | |
cout << 2 << " "; | |
} | |
return 0; | |
} | |
for(int i=1; i<=n; i++){ | |
if(i==1){ | |
cout << 2 << " "; | |
dois--; | |
} | |
if(i==2){ | |
cout << 1 << " "; | |
um--; | |
} | |
if(i>=3){ | |
if(dois>=1){ | |
cout << 2 << " "; | |
dois--; | |
} | |
else{ | |
if(um>=1){ | |
cout << 1 << " "; | |
um--; | |
} | |
} | |
} | |
} | |
return 0; | |
} |