ENG  RUSTimus Online Judge
Online Judge
Problems
Authors
Online contests
About Online Judge
Frequently asked questions
Site news
Webboard
Links
Problem set
Submit solution
Judge status
Guide
Register
Update your info
Authors ranklist
Current contest
Scheduled contests
Past contests
Rules
back to board

Discussion of Problem 1002. Phone Numbers

what is wrong, test #6, 1002
Posted by Practician 19 Oct 2005 11:56
I've submitted 1002 43 times :( , with recursion and without
and cant find where is the error
___________________________________

#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>

const int MAX_SEQ_LEN = 100;
const int MAX_DW_LEN = 50;

struct Word
{
   char* strWord;
   char* numWord;

};

const int MAX_DICT_NUM = 50000;

struct WordArr
{
   public:

   typedef       Word  value_type;
   typedef value_type* iterator;

               WordArr(): lastWord(wordDict) {}

     iterator  begin() { return wordDict; }
     iterator  end()   { return lastWord; }

         void  push_back(const value_type& w)
               {
                  *lastWord = w;
                  lastWord++;
               }

          int  size() const { return lastWord-wordDict; }
         void  reserve(int /*sz*/) {}
         void  clear() { lastWord = wordDict; }

   value_type& operator[](int i) { return wordDict[i]; }

   protected:

      value_type  wordDict[MAX_DICT_NUM]; // словарь
        iterator  lastWord;
};

typedef WordArr DictContainer;
//typedef vector<Word> DictContainer;

const int DATA_DICT_SIZE = 1000*1024 - MAX_DICT_NUM * sizeof(Word);

char  dictBuf[DATA_DICT_SIZE]; // memory for dictionary strings
char* freePointer;             //

char numSeq[MAX_SEQ_LEN+1]; // what to translate
int dictNum;
DictContainer wordDict; // dictionary

std::vector<int> resSeq;   // result
bool isFound = false;      //

char TransTable[26] =
{
   '2',  // a
   '2',  // b
   '2',  // c
   '3',  // d
   '3',  // e
   '3',  // f
   '4',  // g
   '4',  // h
   '1',  // i
   '1',  // j
   '5',  // k
   '5',  // l
   '6',  // m
   '6',  // n
   '0',  // o
   '7',  // p
   '0',  // q
   '7',  // r
   '7',  // s
   '8',  // t
   '8',  // u
   '8',  // v
   '9',  // w
   '9',  // x
   '9',  // y
   '0',  // z
};

//////////////////////////////////////////////////////////////////////////////////

// for Words
char* NewMem(int sz)
{
   char* res = freePointer;
   freePointer += sz;
   return res;
}

void Clean()
{
   wordDict.clear();
   resSeq.clear();
   isFound = false;
   freePointer = dictBuf;
}

void TransWord(char* dest, char* src, int len)
{
   for(int i=0; i<len; i++)
      dest[i] = TransTable[src[i]-'a'];
}

void SetWord(Word& w, char* word, int len)
{
   w.strWord = NewMem(len+1);
   strcpy(w.strWord, word);
   w.numWord = NewMem(len+1);
   w.numWord[len] = 0;
   TransWord(w.numWord, w.strWord, len);
}

void Input()
{
   std::cin >> numSeq;
   if( strcmp(numSeq, "-1" ) == 0 )
       return; // end of work

   std::cin >> dictNum;

   char buf[MAX_DW_LEN+1];
   Word word;
   for(int i=0; i<dictNum; i++)
   {
      std::cin >> buf;
      int len = strlen(buf);
      SetWord(word, buf, len);

      wordDict.push_back(word);
   }
}

bool LessWordCompare(const Word& w1, const Word& w2)
{
   return strcmp(w1.numWord, w2.numWord) < 0;
}

// for recursion
struct FindPack
{
   DictContainer::iterator* beg;
   DictContainer::iterator* end;
                      Word* cur_match;
          std::vector<int>* cur_seq;
};

void FindNext(FindPack& pack)
{
   Word& cur_match = *pack.cur_match;
   if( *cur_match.numWord == 0 )
   {
      if( !isFound || (*pack.cur_seq).size() < resSeq.size() )
      {
         isFound = true;
         resSeq  = *pack.cur_seq;
      }
      return;
   }

   DictContainer::iterator upp_end = std::upper_bound(*pack.beg, *pack.end, *pack.cur_match, LessWordCompare);
   int word_len = strlen(cur_match.numWord);

   DictContainer::iterator cur_iter;
   for(DictContainer::iterator cur_iter1 = upp_end; cur_iter1 != *pack.beg ; --cur_iter1)
   {
      cur_iter = cur_iter1-1;
      Word& w = *cur_iter;

      int len = strlen(w.numWord);
      if( len > word_len ) break;
      if( strncmp(w.numWord, cur_match.numWord, len) != 0 ) break;

      cur_match.numWord += len;
      (*pack.cur_seq).push_back(cur_iter - *pack.beg);

      FindNext(pack);

      cur_match.numWord -= len;
      (*pack.cur_seq).pop_back();
   }
}
void Work()
{
   std::sort(wordDict.begin(), wordDict.end(), LessWordCompare);

   Word cur_match;
   cur_match.numWord = numSeq;

   std::vector<int> cur_seq;
   DictContainer::iterator beg = wordDict.begin();
   DictContainer::iterator end = wordDict.end();

   FindPack pack = { &beg, &end, &cur_match, &cur_seq };
   FindNext(pack);
}

void Output()
{
   if( !isFound )
   {
      std::cout << "No solution." << std::endl;
   }
   else
   {
      for(int i=0, cnt=resSeq.size(); i<cnt; i++)
         std::cout << wordDict[resSeq[i]].strWord << " ";
      std::cout << std::endl;
   }
}

int main(int /*argc*/, char * /*argv*/ [])
{
   for(;;)
   {
      Clean();
      Input();
      if( strcmp(numSeq, "-1" ) == 0 )
         break;

      Work();
      Output();
   }
   return 0;
}