Cod sursa(job #2258584)

Utilizator rares9301Sarmasag Rares rares9301 Data 11 octombrie 2018 18:08:22
Problema Numere 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.86 kb
#include <fstream>
#include <cstring>
#include <iostream>
 
using namespace std;
 
ifstream fin ("numere2.in");
ofstream fout ("numere2.out");
 
const int Dim = 100;
 
class Big{
    enum { MAX = 300 };
    short x[MAX];
    int n;
public:
    Big(int nr = 0);
    short& operator [] (int i) { return x[i]; }
    friend Big operator * (Big A, int B);
    friend Big operator * (Big A, Big B);
    friend Big operator + (Big o1, Big o2);
    friend void Atrib(Big &x, int b);
    friend void Atrib1(Big &x, int b);
    friend Big operator / ( Big o1, int x);
    friend Big operator - ( Big o1, Big o2);
    friend ostream& operator << (ostream& os, const Big& ob);
    friend istream& operator >> ( istream& is, Big& ob);
    bool operator <= (const Big & B)  const {
        if ( n < B.n)
            return true;
        if ( n > B.n)
            return false;
        for ( int  i = n; i >= 1; --i) {
            if ( x[i] < B.x[i] )
                return true;
            if ( x[i] > B.x[i] )
                return false;
            }
        return true;
    }
    bool operator == ( const Big & ob ) const {
        if ( n != ob.n)
            return false;
        for (int i = 1; i <= n; ++i)
            if ( ob.x[i] != x[i] )
                return false;
        return true;
    }
};
 
Big a,p,sol;
int b; 
bool BinarySearch(int b);
 Big Pow(Big x, int n);
 bool SeparatSearch(int b) ;
int main() {
     
    fin >> p;
    bool ok = false;
    for ( int power = Dim; power >= 20; --power)
    if ( BinarySearch(power) ) {
            fout << sol << "\n" << power;
            ok = true;
            break;
            }
    for ( int i = 10; i >= 2; --i)
        if ( SeparatSearch(i) ) {
            fout << sol << "\n" << i;
            ok = true;
            break;
            }
         
    if( !ok )
        fout << p << "\n" << 1 << "\n";
}
     
 
 
bool BinarySearch(int b) {
     
    Big st = 1,mj,dr;
    Atrib(dr,b);
    while ( st <= dr ) {
        mj = ( st + dr ) / 2;
             
        Big P =  Pow(mj,b);
        if ( P == p) {
            sol = mj;
            return true;
        }
        else
            if ( P <= p )
                st = mj + (Big)1;
        else
            dr = mj - (Big)1;
    }
    return false;
     
}
bool SeparatSearch(int b) {
     
    Big st = 1,mj,dr;
    Atrib1(dr,b);
    while ( st <= dr ) {
        mj = ( st + dr ) / 2;
             
        Big P =  Pow(mj,b);
        if ( P == p) {
            sol = mj;
            return true;
        }
        else
            if ( P <= p )
                st = mj + (Big)1;
        else
            dr = mj - (Big)1;
    }
    return false;
     
}
 
Big Pow(Big x, int n) {
     
         if ( n == 0 ) return 1;
          
        Big res = Pow(x, n / 2);
        if ( res <= p ) {
        res = ( res * res) ;
        if ( n % 2 == 1 )
            res = (res * x); 
        }
        return res;
}
 
istream& operator >> ( istream& is,  Big& ob) {
     
    char x[201];
    is.getline(x,201);
    ob.n = strlen(x);
    int poz = 0;
    for ( int i = ob.n; i >= 1; --i)
        ob.x[i] = x[poz++] - '0';
    return is;
}
ostream& operator << (ostream& os, const Big& ob)
{
    for ( int i = ob.n; i >= 1; --i )
        os << ob.x[i];
    return os;
}
  
Big operator + (Big a, Big b)
{
    Big c; int i, t = 0;
    for (i = 1; i <= a.n or i <= b.n or t; ++i, t /= 10)
        c[i] = (t += a[i] + b[i]) % 10;
    c.n = i - 1;
    return c;
}
 
Big operator * (Big a, Big b) {
    int i, j, k = 0;
    Big c;
    for(i = 1;i <= a.n; ++i){
        for(j = 1; j <= b.n or k > 0; j++ ,k /= 10)
            c.x[i+j-1] = ( k += c.x[i+j-1] + a.x[i] * b.x[j] ) % 10;
        if(i + j - 2 > c.n)
            c. n =i+j-2;
    }
    return c;
}
Big operator - (Big a, Big b) {
    int  t = 0;
    Big A = a;
  for ( int i = b.n + 1; i <= A[0]; ++i) b.x[i]=0;
  for ( int i = 1;i <= A.n; ++i)
    A.x[i] +=  ( t = (A.x[i]-=b.x[i] + t) < 0 ) ? 10 : 0;
  while (!A[A.n]) A.n--;
  return A;
}
 
  
Big operator * (Big a, int b)
{
    Big c; int i, t = 0;
    if ( b == 0 ) return c;
    for (i = 1; i <= a.n or t; ++i, t /= 10)
        c[i] = (t += a[i] * b) % 10;
    c.n = i - 1;
    return c;
}
Big operator /(Big o1, int x) { 
  Big C;
  int R = 0;
  C.n= o1.n;
  for ( int i = o1.n; i >= 1 ; --i)
    { C[i] = (R = 10 * R+o1.x[i]) / x;
      R %= x;
    }
  while (!C.x[C.n] and C.n>1) --C.n;
  return C;
}
  
Big::Big(int nr) {
    memset(x, 0, sizeof(x)); n = 0;
    while ( nr ) {
        x[++n] = nr % 10; nr /= 10;
    }
}
 
void Atrib(Big &x,int b) {
     
    x.n = 10;
    x.x[x.n] = 1;
         
}
void Atrib1(Big &x,int b) {
     
    x.n = 40;
    x.x[x.n] = 1;
    for ( int i = 1; i <= 39; ++i)
        x.x[i] = 0;
         
}