👤

#3036 raganama
La nașterea unei fete în tribul Ragan Ama părinții trebuie să îi găsească cel mai frumos nume posibil. Sunt considerate nume frumoase doar anagramele unui cuvânt care, în limba lor, înseamnă “frumoasă ca roua dimineților, blândă ca mângâierea vântului printre frunze, binecuvântată de lumina soarelui și a lunii”.
Viața fetei va sta sub o stea norocoasă dacă numele său este cel mai mic din punct de vedere lexicografic, diferit de al oricăreia dintre fetele din trib.
Cerința

Fiindcă astăzi în trib s-a născut o fetiță, scrieți un program care, cunoscând numele fetelor din trib, rezolvă următoarele cerințe:
1. afișează numele pe care părinții ar trebui să i-l dea fetei pentru ca viața să-i stea sub o stea norocoasă;
2. determină câte nume frumoase, diferite de cele ale fetelor din trib, există.
Date de intrare

Fișierul de intrare raganama.in conține pe prima linie un număr natural C, care reprezintă cerința care trebuie să fie rezolvată (1 sau 2). Pe următoarele linii se află numele fetelor din trib, câte un nume pe o linie, în ordine lexicografică; toate numele sunt anagrame ale aceluiași cuvânt.
Date de ieșire

Fișierul de ieșire raganama.out va conține o singură linie.
Dacă C = 1, pe această linie pe care va fi scris numele pe care părinții ar trebui să i-l dea fetei.
Dacă C = 2, pe această linie va fi scris numărul de nume frumoase, diferite de cele ale fetelor din trib.
Restricții și precizări

Numele fetelor sunt formate din maximum 100 de litere mici din alfabetul englez.
În trib există maximum 100.000 de fete.
O anagramă a unui cuvânt este formată din aceleași litere cu cuvântul dat, eventual într-o altă ordine. De exemplu cuvântul “armata” este o anagramă a cuvântului “tamara”.
Spunem că un cuvânt a1a2… an este mai mic din punct de vedere lexicografic decât un cuvânt b1b2… bn dacă există 1 ≤ k ≤ n astfel încât ai=bi, pentru orice 1 ≤ i < k și ak=bk.
Se garantează că pentru datele de test există un nume ce poate fi dat fetei nou-născute.
Pentru teste valorând 20 de puncte rezultatul la cerința 2 va avea maximum 18 cifre.
Pentru teste valorând 50 de puncte cerința este 1.

Daca puteti optimiza programul atasat :)
Multumesc!


3036 Raganama La Nașterea Unei Fete În Tribul Ragan Ama Părinții Trebuie Să Îi Găsească Cel Mai Frumos Nume Posibil Sunt Considerate Nume Frumoase Doar Anagrame class=

Răspuns :

L-am optimizat cat de mult am putut(si am mai modificat cate ceva sa fie corect):

#include <fstream>

#include <cstring>

#include <algorithm>

#define NMax 100002

#define lgMax 100

#define lMax 26

using namespace std;

ifstream fin("raganama.in");

ofstream fout("raganama.out");

int cer,p;

short int ap[lMax],E[lgMax+85];

char x[lgMax+5];

string s[NMax+100];

typedef short int NrMare[lgMax+30];

NrMare a;

bool cb(string y,string x[],int st,int dr)

{

   if(st > dr)

       return 0;

   int mij=(st+dr)/2;

   

   int cmprez = y.compare(x[mij]);

   if(cmprez == 0)

       return 1;

   else if(cmprez < 0)

       return cb(y,x,1,mij-1);

   else if(cmprez > 0)

       return cb(y,x,mij+1,dr);

   return 0;

}

void dp1(int x)

{

   int d=2,p;

   if(!x)

       return;

   while(d*d<=x)

   {

       p=0;

       while(x%d==0)

       {

           x/=d;

           p++;

       }

       E[d++]+=p;

   }

   E[x]++;

}

void dp2(int x)

{

   int d=2,p;

   if(!x)

       return;

   while(d*d<=x)

   {

       p=0;

       while(x%d==0)

       {

           x/=d;

           p++;

       }

       E[d++]-=p;

   }

   E[x]--;

}

void Produs(NrMare a,int x)

{

   int i,ct;

   for(i=1,ct=0; i<=p; i++)

   {

       a[i]=a[i]*x+ct;

       ct=a[i]/10;

       a[i]=a[i]%10;

   }

   while(ct)

   {

       a[++p]=ct%10;

       ct/=10;

   }

}

void Scadere(NrMare a, int x){

   int carry = 0;

   for(int i = 1; i <= p; i++){

       a[i] = a[i] - carry - x%10;

       x/=10;

       if(a[i] < 0){

           carry = 1;

           a[i] += 10;

       }

       else carry = 0;

   }

   while(a[p] == 0)

       p--;

}

int main()

{

   int n=0;

   fin>>cer;

   while(fin.getline(x,NMax))

       s[n++]=x;

   n--;

   int len = s[1].length();

   if(cer==1)

   {

       string sir;

       memcpy(x, s[1].c_str(), len+1);

       do

       {

           sir=x;

           if(!cb(sir,s,0,n))

           {

               fout<<sir;

               return 0;

           }

       }

       while(next_permutation(x,x+len));

   }

   else

   {

       int i,j,lg;

       lg=len;

       p=a[1]=1;

       for(i=0; i<=lg; i++)

           ap[s[1][i]-'a']++;

       for(i=1; i<=lg; i++)

           dp1(i);

       for(i=0; i<=25; i++)

           for(j=2; j<=ap[i]; j++)

               dp2(j);

///---------Calculez Totalul---------///

       for(i=2; i<=lg; i++)

           for(j=1; j<=E[i]; j++)

               Produs(a,i);

       Scadere(a, n);

///--------------------------------///

       for(i=p; i>=1; i--)

           fout<<a[i];

   }

   return 0;

}