ENG  RUSTimus Online Judge
Online Judge
Задачи
Авторы
Соревнования
О системе
Часто задаваемые вопросы
Новости сайта
Форум
Ссылки
Архив задач
Отправить на проверку
Состояние проверки
Руководство
Регистрация
Исправить данные
Рейтинг авторов
Текущее соревнование
Расписание
Прошедшие соревнования
Правила
вернуться в форум

Обсуждение задачи 1002. Телефонные номера

what is wrong, test #6, 1002
Послано Practician 19 окт 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;
}