Pagini recente » Cod sursa (job #2589895) | Cod sursa (job #2718646) | Cod sursa (job #2584099) | Cod sursa (job #2983843) | Cod sursa (job #2593169)
/**
Informatii despre rezolvare:
Aceasta rezolvare se bazeaza pe tehnica de parcurgere a grafurilor BFS.
In loc de un graf, avem numere intr-un format "binar".
De la un numar, sa zicem x = 101; putem ajunge doar la x1 = 1010, x2 = 1011;
Ca sa pastram ambele numerele si sa le verificam daca sunt candidate pentru
multiplu le punem intr-o coada.
Vectorul q[] va fi coada in sine, in care adauagam resturile.
O optimizare a algoritmului este sa nu mai verificam numerele la care deja am gasit
un rest y si numerele care se pot forma din acesta, deoarce stim deja ca nu vor fi
minime. O sa pastram informatia despre fiecare rest daca a fost gasit in vectorul flags[].
Din moment ce numerele vor fi foarte mari, neincapand pe formatele normale, o
sa le pastram forma binara in vectorul v[].
Vectorul t[] o sa il folosim pentru reconstituirea numarului asemenea vectorului de
tati de la arbori.
*/
#define NMAX 2000000
#include <fstream>
#include <algorithm>
using namespace std;
typedef long long ll;
ifstream in("multiplu.in");
ofstream out("multiplu.out");
bool flag[NMAX+1];
int st, dr, q[NMAX+1]; /// elemente utilizate pentru coada
int v[NMAX+1], t[NMAX+1]; /// elemente utilizate pentru reconstructia numarului
void back(int x){
if(x){
back(t[x]);
out << v[x];
}
}
int main(){
ll a, b, mm;
in >> a >> b;
mm = (a / __gcd(a, b) * b);
q[1] = st = dr = v[1] = flag[1] = 1;
while (st <= dr){
for(int d = 0; d <= 1; d++){
int rest = (q[st] * 10 + d) % mm; /// Calculam urmatorul numar de verificat
if(!flag[rest]){
flag[rest] = 1;
q[++dr] = rest; /// Adaugam in coada restul
v[dr] = d; /// Punem cifra "binara" in vectorul v[];
t[dr] = st; /// Marcam pozitia la care trebuie sa ne intoarcem
if(rest == 0){ /// Am gasit raspunsul, oprim cautarea
st = dr;
break;
}
}
}
st++; /// Avansam la urmatorul element in coada
}
back(dr); /// Reconstituim numarul
}