Cod sursa(job #1656749)

Utilizator SolcanMihaiSolcan Mihai Andrei SolcanMihai Data 19 martie 2016 19:06:47
Problema Combinari Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 5.87 kb
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

class Numar{
public:
    Numar()
    {
        dimensiune = 0;

        for(int i = 0; i < 3000; i++)
        {
            cifre[i] = 0;
        }
    }

    friend istream &operator>>(istream &input, Numar &nr)
    {
        char tmp[3000];

        input >> tmp;

        nr.dimensiune = strlen(tmp);

        for(int i = 0; i < nr.dimensiune; i++)
        {
            nr.cifre[nr.dimensiune - 1 - i] = tmp[i] - '0';
        }

        return input;
    }

    friend ostream &operator<<(ostream &output, Numar &nr)
    {
        for(int i = nr.dimensiune - 1; i >= 0; i--)
        {
            output << nr.cifre[i];
        }

        return output;
    }

    Numar operator*(Numar &nr)
    {
        Numar rezultat;

        for(int i = 0; i < nr.dimensiune; i++)
        {
            for(int j = 0; j < this->dimensiune; j++)
            {
                rezultat.cifre[i + j] += nr.cifre[i] * this->cifre[j];
            }
        }

        rezultat.recalculateSize();

        for(int i = 0; i < rezultat.dimensiune; i++)
        {
            rezultat.cifre[i + 1] += rezultat.cifre[i] / 10;
            rezultat.cifre[i] %= 10;
        }

        while(rezultat.cifre[rezultat.dimensiune])
        {
            rezultat.dimensiune++;
            rezultat.cifre[rezultat.dimensiune] += rezultat.cifre[rezultat.dimensiune - 1] / 10;
            rezultat.cifre[rezultat.dimensiune - 1] %= 10;
        }

        return rezultat;
    }

    Numar operator*(int nrx)
    {
        Numar rezultat;
        Numar nr;

        while(nrx)
        {
            nr.cifre[nr.dimensiune] = nrx % 10;
            nr.dimensiune++;
            nrx /= 10;
        }

        for(int i = 0; i < nr.dimensiune; i++)
        {
            for(int j = 0; j < this->dimensiune; j++)
            {
                rezultat.cifre[i + j] += nr.cifre[i] * this->cifre[j];
            }
        }

        rezultat.recalculateSize();

        for(int i = 0; i < rezultat.dimensiune; i++)
        {
            rezultat.cifre[i + 1] += rezultat.cifre[i] / 10;
            rezultat.cifre[i] %= 10;
        }

        while(rezultat.cifre[rezultat.dimensiune])
        {
            rezultat.dimensiune++;
            rezultat.cifre[rezultat.dimensiune] += rezultat.cifre[rezultat.dimensiune - 1] / 10;
            rezultat.cifre[rezultat.dimensiune - 1] %= 10;
        }

        return rezultat;
    }

    Numar operator+(int &nrx)
    {
        Numar rezultat;
        Numar nr;

        while(nrx)
        {
            nr.cifre[nr.dimensiune] = nrx % 10;
            nr.dimensiune++;
            nrx /= 10;
        }

        rezultat.dimensiune = max(nr.dimensiune, this->dimensiune);

        for(int i = 0; i < rezultat.dimensiune; i++)
        {
            rezultat.cifre[i] += this->cifre[i] + nr.cifre[i];
            rezultat.cifre[i + 1] += rezultat.cifre[i] / 10;
            rezultat.cifre[i] %= 10;
        }

        if(rezultat.cifre[rezultat.dimensiune] != 0)
        {
            rezultat.dimensiune++;
        }

        return rezultat;
    }

    Numar operator+(Numar &nr)
    {
        Numar rezultat;

        rezultat.dimensiune = max(nr.dimensiune, this->dimensiune);

        for(int i = 0; i < rezultat.dimensiune; i++)
        {
            rezultat.cifre[i] += this->cifre[i] + nr.cifre[i];
            rezultat.cifre[i + 1] += rezultat.cifre[i] / 10;
            rezultat.cifre[i] %= 10;
        }

        if(rezultat.cifre[rezultat.dimensiune] != 0)
        {
            rezultat.dimensiune++;
        }

        return rezultat;
    }

    void initializeToOne()
    {
        this->dimensiune = 1;
        this->cifre[0] = 1;
    }

private:
    int cifre[3000];
    int dimensiune;

    void recalculateSize()
    {
        for(int i = 2999; i >= 0; i--)
        {
            if(cifre[i] != 0)
            {
                dimensiune = i + 1;
                return;
            }
        }
    }
};

Numar factoriale[3000];
int n;
int sir[3000];
int permutare[3000];
int permutareIndici[3000];
bool viz[3000];
Numar rezultat;
int numere[3000];

void generateFactorials()
{
    factoriale[0].initializeToOne();

    for(int i = 1; i < n; i++)
    {
        factoriale[i] = factoriale[i - 1] * i;
    }
}

void citire()
{
    scanf("%d", &n);
    int tmp;

    for(int i = 0; i < n; i++)
    {
        scanf("%d", &sir[i]);
    }

    for(int i = 0; i < n; i++)
    {
        scanf("%d", &permutare[i]);
    }

    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < n; j++)
        {
            if(permutare[i] == sir[j])
            {
                permutareIndici[i] = j + 1;
                break;
            }
        }
    }
}

void solveDinamic()
{
    int l = n;
    int unu, doi;
    unu = 1;
    doi = 2;
    Numar tmpx;

    for(int i = 0; i < l - 2; i++)
    {
        tmpx = factoriale[n - 1 - i] * numere[i];
        rezultat = rezultat + tmpx;

        viz[permutareIndici[i]] = true;
    }

    if(permutareIndici[n - 2] < permutareIndici[n - 1])
    {
        rezultat = rezultat + unu;
    }
    else
    {
        rezultat = rezultat + doi;
    }
}

void generateNumere()
{
    for(int i = 0; i < n - 2; i++)
    {
        for(int j = 1; j < permutareIndici[i]; j++)
        {
            if(viz[j] == false)
            {
                numere[i]++;
            }
        }

        viz[permutareIndici[i]] = true;
    }
}

int main()
{
    freopen("perm3.in", "r", stdin);
    freopen("perm3.out", "w", stdout);

    citire();
    generateFactorials();
    generateNumere();
    solveDinamic();
    cout << rezultat;


    return 0;
}