Cod sursa(job #2260446)

Utilizator q1e123Solca Robert-Nicolae q1e123 Data 14 octombrie 2018 23:25:28
Problema Al k-lea termen Fibonacci Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 7.27 kb
#include <bits/stdc++.h>


std::ifstream INPUT_FILE("kfib.in");
std::ofstream OUTPUT_FILE("kfib.out");

class Matrice {
public:
    Matrice( long n, long m);
    virtual ~Matrice();
    //get & set
    bool isPatratica() const;
    void setPatratica(bool patratica);
    long int getM() const;
    long int getN() const;

    double getElement(long i,long j) const;
    void setElement(long i,long j,double x);
    //operatii
    Matrice&operator+=(Matrice&);
    Matrice&operator-=(Matrice&);
    Matrice&operator+(Matrice&);
    Matrice&operator-(Matrice&);
    Matrice&operator*=(Matrice&);
    Matrice&operator*(Matrice&);
    Matrice&operator*=(double);
    Matrice&operator*(double);
    Matrice&operator/=(double);
    Matrice&operator/(double);
    Matrice operator^(long);
    Matrice&operator=(Matrice);
    bool operator==(Matrice&);

    friend std::ostream& operator<<(std::ostream& os, const Matrice& mat);
    // friend ostream& operator>>(ostream& os, const Matrice& mat);


    //functii
    static double Tr(Matrice mat);
    static  Matrice transpusa(Matrice mat);
    static bool simetrica(Matrice mat);
    static double determinant(Matrice mat);
    static  Matrice I(long marime);
protected:

private:
    bool patratica;
    long long m, n;
    double **matrice;
    double det(Matrice mat,long i,long j);
    Matrice cofactor(Matrice mat,long i,long j);
    void faMatricea();
    Matrice puteri( Matrice&,long);


};


Matrice::Matrice( long n,  long m){
    //ctor
    this->m=m;
    this->n=n;
    if(n==m) patratica= 1;
    else patratica=0;
    faMatricea();
}

Matrice::~Matrice(){
    //dtor
}

double Matrice::Tr(Matrice mat) {
    if(mat.isPatratica()){
        double sum=0;
        for(int tmp=0;tmp<mat.getM();tmp++) sum+=mat.getElement(tmp,tmp);
        return sum;
    }else{
        std::cerr<<"Matricea nu e patratica!\n";
    }

}

void Matrice::faMatricea() {
    matrice=new double*[m];
    for(long tmp=0;tmp<n;tmp++){
        matrice[tmp]=new double[n];
    }
}

bool Matrice::isPatratica() const {
    return patratica;
}

void Matrice::setPatratica(bool patratica) {
    Matrice::patratica = patratica;
}

long int Matrice::getM() const {
    return m;
}

long int Matrice::getN() const {
    return n;
}

Matrice &Matrice::operator+=(Matrice &mat) {
    if(this->m==mat.getM() && this->n==mat.getN()){
        for(long i=0;i<n;i++){
            for(long j=0;j<m;j++) matrice[i][j]+=mat.getElement(i,j);
        }
        return  *this;
    }else{
        std::cerr<<"Nu sunt de acelasi tip\n";
    }
}

Matrice &Matrice::operator-=(Matrice &mat) {
    if(this->m==mat.getM() && this->n==mat.getN()){
        for(long i=0;i<n;i++){
            for(long j=0;j<m;j++) matrice[i][j]-=mat.getElement(i,j);
        }
        return  *this;
    }else{
        std::cerr<<"Nu sunt de acelasi tip\n";
    }
}

Matrice &Matrice::operator+(Matrice &mat) {
    if(this->m==mat.getM() && this->n==mat.getN()){
        for(long i=0;i<n;i++){
            for(long j=0;j<m;j++) matrice[i][j]+=mat.getElement(i,j);
        }
        return  *this;
    }else{
        std::cerr<<"Nu sunt de acelasi tip\n";
    }
}

Matrice &Matrice::operator-(Matrice &mat) {
    if(this->m==mat.getM() && this->n==mat.getN()){
        for(long i=0;i<n;i++){
            for(long j=0;j<m;j++) matrice[i][j]-=mat.getElement(i,j);
        }
        return  *this;
    }else{
        std::cerr<<"Nu sunt de acelasi tip\n";
    }
}

Matrice &Matrice::operator*=(Matrice &mat) {
    if(m==mat.getN()){
        Matrice tmp(n,mat.getM());
        for(long i=0;i<tmp.getN();i++){
            for(long j=0;j<tmp.getM();j++){
                for(long k=0;k<m;k++) tmp.setElement(i,j,tmp.getElement(i,j)+(getElement(i,k)*mat.getElement(k,i)));
            }
        }
        return  tmp;
    }else{
        std::cerr<<"Inmultirea nu se poate face\n";
    }
}

Matrice &Matrice::operator*(Matrice &mat) {
    if(m==mat.getN()){
        Matrice tmp(n,mat.getM());
        for(long i=0;i<tmp.getN();i++){
            for(long j=0;j<tmp.getM();j++){
                for(long k=0;k<m;k++) tmp.setElement(i,j,tmp.getElement(i,j)+(getElement(i,k)*mat.getElement(k,j)));
            }
            // std::cout<<tmp;
        }
        return (*this=tmp);
    }else{

        std::cerr<<"Inmultirea nu se poate face\n"<<mat;
        std::cout<<*this;
    }
}

Matrice &Matrice::operator*=(double x) {
    for(long i=0;i<n;i++){
        for(long j=0;j<m;j++){
            matrice[i][j]*= x;
        }
    }
    return  *this;
}

Matrice &Matrice::operator*(double x) {
    for(long i=0;i<n;i++){
        for(long j=0;j<m;j++){
            matrice[i][j]*= x;
        }
    }
    return  *this;
}

Matrice &Matrice::operator/=(double x) {
    for(long i=0;i<n;i++){
        for(long j=0;j<m;j++){
            matrice[i][j]/= x;
        }
    }
    return  *this;
}

Matrice &Matrice::operator/(double x) {
    for(long i=0;i<n;i++){
        for(long j=0;j<m;j++){
            matrice[i][j]/= x;
        }
    }
    return  *this;
}

Matrice Matrice::operator^(long x) {
    Matrice tmp(*this);
    return  puteri(tmp,x);
}

Matrice &Matrice::operator=(Matrice mat) {
    if(n==mat.getN() && m==mat.getM()){
        for(long i=0;i<n;i++){
            for(long j=0;j<m;j++){
                setElement(i,j,mat.getElement(i,j));
            }
        }
        return  *this;
    } else{
        std::cerr<<"Matricele nu sunt de acelasi tip\n";
    }

}

Matrice Matrice::transpusa(Matrice mat) {
    Matrice tmp(mat.getM(),mat.getN());
    for(long i=0;i<mat.getN();i++){
        for(long j=0;j<mat.getM();j++){
            tmp.setElement(j,i,mat.getElement(i,j));
        }
    }
    return mat;
}

bool Matrice::simetrica(Matrice mat) {
    if(transpusa(mat) == mat) return 1;
    return  0;
}

double Matrice::determinant(Matrice mat) {
    if(mat.getN()!=mat.getM()){
        std::cerr<<"Matricea nu e patratica\n";
        return 0;
    }

}

double Matrice::getElement(long i, long j) const {
    return matrice[i][j];
}

void Matrice::setElement(long i,long j,double x) {
    matrice[i][j]=x;
}

Matrice Matrice::I(long marime) {
    Matrice tmp(marime,marime);
    for(long i=0;i<marime;i++){
        for(long j=0;j<marime;j++){
            if(i==j) tmp.setElement(i,j,1);
            else tmp.setElement(i,j,0);
        }
    }
    return tmp;
}

Matrice Matrice::puteri(Matrice &mat, long putere) {
    if(!putere) return I(mat.getN());
    if(putere==1) return  mat;
    if(putere%2) return puteri(mat*mat,(putere-1)/2);
    return puteri(mat*mat,(putere)/2);
}

bool Matrice::operator==(Matrice &mat) {
    if(n!=mat.getN() || m!=mat.getM())return false;
    for(long i=0;i<n;i++){
        for(long j=0;j<m;j++){
            if(getElement(i,j)==mat.getElement(i,j)) return 0;
        }
    }
    return 0;
}

std::ostream &operator<<(std::ostream &os, const Matrice &mat) {
    for(long i=0;i<mat.getN();i++){
        for(long j=0;j<mat.getM();j++){
            os<<mat.getElement(i,j)<<" ";
        }
        os<<"\n";
    }
}


int main() {
    Matrice Z(2,2);
    Matrice M1(1,2);
    long n;

    Z.setElement(0,0,0);
    Z.setElement(0,1,1);
    Z.setElement(1,0,1);
    Z.setElement(1,1,1);
    M1.setElement(0,0,0);
    M1.setElement(0,1,1);
    INPUT_FILE>>n;
    Matrice rez(1,2);
    Matrice rez1(2,2);
    rez1=Z^n;
    std::cout<<rez1;
    std::cout<<rez;
    rez=M1*rez1;
    OUTPUT_FILE<<rez.getElement(0,1);

    return 0;
}