| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
跑sample过了,简单dfs,密文单词没有排序,迅速runtime error,(ZJU上WA),找不到原因,请帮忙(附代码)
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <new>
#define MAX_DICT_WORDS 50000
#define MAX_DICT_CHARS 350000
#define MAX_WORD_LEN 20
class DictWord
{
public:
DictWord* next;
char *word;
};
class DictWordList
{
public:
DictWord *head;
int size;
DictWordList() :head(NULL),size(0) { }
void push(DictWord* node)
{
node->next = head;
head = node;
};
};
class Dict
{
public:
static char allWords[MAX_DICT_CHARS + MAX_DICT_WORDS];
DictWord words[MAX_DICT_WORDS];
DictWordList wordOfLen[MAX_WORD_LEN];
int nWords;
void readDict()
{
int i, len;
char *pWord = &allWords[0];
scanf("%d", &nWords);
for (i = 0; i < nWords; i++) {
scanf("%s", pWord);
len = strlen(pWord);
words[i].word = pWord;
wordOfLen[len].push(&words[i]);
pWord += len + 1;
}
}
};
char Dict::allWords[MAX_DICT_CHARS + MAX_DICT_WORDS];
class CodeMap
{
public:
char decodeTable[26];
char encodeTable[26];
CodeMap()
{
for (int i = 0; i < 26; i++) {
decodeTable[i] = encodeTable[i] = '*';
}
};
inline char decode(char cryptChar) {
return decodeTable[cryptChar - 'A'];
};
inline char encode(char clearChar) {
return encodeTable[clearChar - 'A'];
};
inline void setMapping(char cryptChar, char clearChar) {
decodeTable[cryptChar - 'A'] = clearChar;
encodeTable[clearChar - 'A'] = cryptChar;
};
inline void unsetMapping(char cryptChar, char clearChar) {
decodeTable[cryptChar - 'A'] =
encodeTable[clearChar - 'A'] = '*';
};
};
class TextWord
{
public:
char* str;
int len;
};
class TextWords
{
public:
int nWords;
TextWord* words;
char* textBuf;
int bufLen;
CodeMap map;
int nAnswers;
int nCalls;
CodeMap answer1;
Dict* dict;
TextWords(Dict* d)
: nWords(0), words(NULL), dict(d)
{
bufLen = 800;
textBuf = (char*)malloc(bufLen * sizeof(char));
}
~TextWords()
{
if (words)
free(words);
free(textBuf);
}
void readText()
{
int i, j, wordsInLine, textLen, prevChar, thisChar, len;
char *lineBuf;
enum {WORD_CHAR = 0, BLANK_CHAR = 1};
lineBuf = textBuf;
nWords = 0; textLen = 0;
do {
if (bufLen - textLen < 81) {
bufLen += 800;
textBuf = (char*)realloc(textBuf, bufLen);
lineBuf = textBuf + textLen;
}
wordsInLine = 0;
gets(lineBuf);
len = strlen(lineBuf);
prevChar = BLANK_CHAR;
for (i = 0; i < len; i++) {
if (lineBuf[i] >= 'A' && lineBuf[i] <= 'Z')
thisChar = WORD_CHAR;
else
thisChar = BLANK_CHAR;
if (prevChar == BLANK_CHAR && thisChar == WORD_CHAR) {
wordsInLine++;
}
prevChar = thisChar;
}
nWords += wordsInLine;
// to avoid "joining last word of this line and first word of next line"
lineBuf[len] = ' ';
lineBuf += len + 1;
textLen += len + 1;
} while ((wordsInLine > 0) && !feof(stdin));
words = (TextWord*)malloc(nWords * sizeof(TextWord));
prevChar = BLANK_CHAR;
j = 0;
for (i = 0; i < textLen; i++) {
if (textBuf[i] >= 'A' && textBuf[i] <= 'Z')
thisChar = WORD_CHAR;
else
thisChar = BLANK_CHAR;
if (prevChar == BLANK_CHAR && thisChar == WORD_CHAR) {
words[j].str = textBuf + i;
} else if (prevChar == WORD_CHAR && thisChar == BLANK_CHAR) {
textBuf[i] = '\0';
words[j].len = textBuf + i - words[j].str;
j++;
}
prevChar = thisChar;
}
}
void sortWords()
{
int i, j, k, freq[26], maxF, iMaxF, f;
bool seen[26];
TextWord tmpW;
// eliminate duplicate words
for (i = nWords - 2; i >= 0 ; i--) {
for (j = nWords - 1; j > i; j--) {
if (strcmp(words[i].str, words[j].str) == 0) {
for (k = j; k < nWords - 1; k++) {
words[k] = words[k + 1];
}
nWords--;
}
}
}
// Choose the word that share the most large number of chars
// with other words as the first. This should make 'conflicts'
// between words show up early (in the iterations of tryDecode()).
for (i = 0; i < 26; i++) {
freq[i] = 0;
}
for (i = 0; i < nWords; i++) {
for (j = 0; j < words[i].len; j++) {
freq[words[i].str[j] - 'A']++;
}
}
iMaxF = 0; maxF = 0;
for (i = 0; i < nWords; i++) {
f = 0;
for (j = 0; j < words[i].len; j++) {
f += freq[words[i].str[j] - 'A'];
}
if (f > maxF) {
maxF = f;
iMaxF = i;
}
}
tmpW = words[0]; words[0] = words[iMaxF]; words[iMaxF] = tmpW;
// Starting from the second wrod, we try to maximize char sharing
// with preceeding words. This is meant to reduce branches
// and also to discover confilicts as early as possible.
for (i = 0; i < 26; i++) {
seen[i] = false;
}
for (k = 1; k < nWords - 1; k++) {
for (j = 0; j < words[k].len; j++) {
seen[words[k - 1].str[j] - 'A'] = true;
}
maxF = 0; iMaxF = 0;
for (i = k; i < nWords; i++) {
f = 0;
for (j = 0; j < words[i].len; j++) {
if (seen[words[i].str[j] - 'A'])
f++;
}
if (f > maxF) {
maxF = f;
iMaxF = i;
}
}
tmpW = words[k]; words[k] = words[iMaxF]; words[iMaxF] = tmpW;
}
};
void innerTryDecode(int k)
{
DictWord* pw;
int j;
bool isNew[MAX_WORD_LEN];
char dec, enc;
nCalls++;
if (k >= nWords) {
nAnswers++;
if (nAnswers == 1)
answer1 = map;
return;
}
for (pw = dict->wordOfLen[words[k].len].head; pw != NULL; pw = pw->next) {
for (j = 0; j < words[k].len; j++)
isNew[j] = false;
j = 0;
while (j < words[k].len) {
dec = map.decode(words[k].str[j]);
enc = map.encode(pw->word[j]);
if (enc == '*' && dec == '*') {
isNew[j] = true;
map.setMapping(words[k].str[j], pw->word[j]);
} else if (!(dec == pw->word[j] && enc == words[k].str[j])) {
// confict with current map
break; // while j
}
j++;
}
if (j == words[k].len) {
// no conflicts, go decode next word in text
innerTryDecode(k + 1);
if (nAnswers >= 2)
return;
}
j--;
// mapping words[k] to pw->word has been tried
// (either it conflicts or recursive search finished),
// undo mappings set for this word.
while (j >= 0) {
if (isNew[j])
map.unsetMapping(words[k].str[j], pw->word[j]);
j--;
}
}
};
void tryDecode()
{
nAnswers = 0;
nCalls = 0;
new(&map) CodeMap();
//sortWords();
innerTryDecode(0);
if (nAnswers == 0)
printf("#No solution#");
else if (nAnswers >= 2)
printf("#More than one solution#");
else { // one answer
for (char c = 'A'; c <= 'Z' ; c++)
printf("%c", answer1.encode(c));
}
#ifndef ONLINE_JUDGE
printf(" %d calls", nCalls);
#endif
printf("\n");
};
};
int main(int argc, char *argv[])
{
Dict dict;
int t;
unsigned char c;
dict.readDict();
scanf("%d",&t);
while (t > 0) {
t--;
c = ' ';
while (! (c >= 'A' && c <= 'Z') && !feof(stdin)) {
c = getc(stdin);
}
ungetc(c, stdin);
TextWords textWords(&dict);
textWords.readText();
textWords.tryDecode();
}
return 0;
}
Followed by:
Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator