Cod sursa(job #2593169)

Utilizator sansRotaru Razvan Andrei sans Data 3 aprilie 2020 02:47:31
Problema Multiplu Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.14 kb
/**
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
}