ACM题“Harry Potter and His Magic Scroll”的一种解法

来源:互联网 发布:microsoft fix it 64 编辑:程序博客网 时间:2024/06/04 19:50

ACM题“Harry Potter and His Magic Scroll”的一种解法

 

1.        题目

  该题目原文见HDU ACM 2664:

    http://acm.hdu.edu.cn/showproblem.php?pid=2664

  或WHU ACM 1360:

    http://acm.whu.edu.cn/oak/problem/problem.jsp?problem_id=1360

 

2.        需求解析

  根据题意可解析出如下需求:

a)        输入的第1行是用例数。

b)        输入的每个用例中有一个词典。词典最多包含100000个单词,单词之间只用一个空格符隔开,一个单词可能跨2行,每个单词的长度不超过20

c)        按行输入词典,每行最多包含2000个字符,最后一行只有一个字符“#”,表示词典结束。

d)        词典结束后的下一行输入是一个整数T,表示文卷数。

e)        文卷数的下一行输入是一个整数m,表示文卷中要包含的魔力单词数。

f)          随后输入m行魔力单词,每个单词的长度不超过20

g)        在词典中寻找包含一个文卷的所有魔力单词的一段连续的单词(以下简称为passage)。

h)        魔力单词与词典中的单词大小写相同。

i)          魔力单词在这段单词中出现的位置可以是任意的。

j)          由于要求是连续的,这段单词可能包含非魔力单词。

k)        这段连续的单词应是在词典中最短的,并且是最先出现的。

l)          输出这段连续的单词的首字符和尾字符在词典中的位置,词典中第一个字符的位置为0

 

3.        数据结构设计

#define MAX_LINE 2002

#define MAX_WORD_NUMBER 100001

#define MAX_WORD_LENGTH 21

#define MAX_PASSAGE_LENGTH /

(MAX_WORD_NUMBER*MAX_WORD_LENGTH)

 

typedef struct

{

  char word[MAX_WORD_LENGTH];

  int start_position;

  int end_position;

  int magic_id; /*词典单词所对应的魔力单词编号,

0 开始,-1表示不是魔力单词*/

} dict_word_type; /*词典单词属性*/

 

char line[MAX_LINE]; /*输入的一行辞典内容*/

dict_word_type dictionary[MAX_WORD_NUMBER]; /*词典*/

int dictionary_word_number;/*词典单词总数*/

unsigned case_number; /*用例数*/

unsigned scroll_number; /*文卷数*/

int magic_word_number; /*魔力单词数*/

int magic_word_length_sum; /*魔力单词长度总和*/

int search_start; /*第一个魔力单词在辞典中的编号*/

int word_count_for_dictionary[MAX_WORD_NUMBER];/*辞典中每个魔力单词的出现次数*/

int word_count_for_passage[MAX_WORD_NUMBER]; /*辞典中一段单词中每个魔力单词的出现次数*/

 

4.        算法设计

读入case_number

while (case_number--)

{

按行读入词典内容;

存入dictionary并计算每个单词的属性;

读入scroll_number

while (scroll_number--)

{

读入魔力单词并计算词典中每个单词的魔力单词编号和word_count_for_dictionary

在词典寻找最先出现的passage(用指针pq分别其首单词和尾单词);

minimun_length = MAX_PASSAGE_LENGTH;

for (;;)

{

计算pq之间的长度k

if (minimun_length > k)

{

minimun_length = k;

保存pq中的位置到best_first_positionbest_last_position

if (k == magic_word_length_sum) break;

}

pmagic_id;

移动p/q使其指向下一段passage;

if (没有新的passage) break;

}

输出最短passage的首尾位置;

               }

}

 

5.        测试用例

    输入:

1

Potter to Harry want to make scrolls some Harry going Harry go

ing to Potter improve some scrolls

to his magic power.

#

2

1

to

3

Harry

Potter

going 

 

输出:

7 8

54 74

 

6.        结论

本题的关键是正确解析题意和设计高效的搜索算法。

 

原创粉丝点击