USTC OJ — 1008 Word Amalgamation(组合数学,全排列)

1. 题目描述

题目的输入数据有两部分,前一部分是dictionary,后一部分是待查的单词集合。

对于每一个待查单词word1,我们需要从dictionary中查找对应的词汇word2。查找规则是:word1和word2组成的字母集合(这里是多重集合)相等。

2. 算法设计

对于每一个待查单词word1,用它对应的字母集合构造全排列。

对于全排列中的每一个排列,去查找是否存在于dictionary中。如果存在,就保存下来。如果不存在,直接输出“NOT A VALID WORD”。

如果在dictionary中,匹配了多个单词,把它们按字典序排序,全部输出即可。

3. AC Code

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <stdlib.h>
  4
  5 #define N 105
  6 #define WORD_MAX_SIZE 10
  7
  8 char dictionary[N][WORD_MAX_SIZE];  // 字典
  9 int  dic_size;                      // 字典大小(字典中的word个数)
 10
 11 char scrambled_word[WORD_MAX_SIZE]; // 待查找word
 12
 13 char words[N][WORD_MAX_SIZE];   // 存放在字典中匹配查找到的单词
 14 int  words_num;                 // 纪录匹配的单词个数
 15
 16 void permutation_check(char* p_str, char* p_begin);
 17 void swap(char* a, char* b);
 18 void search_in_dictionary(char str[]);
 19 void print();
 20 void del_newline_symbol(char* str);
 21 int cmp(const void* a, const void* b);
 22
 23 int main()
 24 {
 25     int i = 0;
 26
 27     // freopen("in.txt", "r", stdin);
 28
 29     // load dictionary into memory
 30     while ( NULL != fgets(dictionary[i], WORD_MAX_SIZE, stdin) )
 31     {
 32         // 去掉读入的多余换行符
 33         del_newline_symbol(dictionary[i]);
 34
 35         // load over
 36         if ( 0 == strcmp(dictionary[i], "XXXXXX") )
 37         {
 38             dic_size = i;
 39             break;
 40         }
 41         ++i;
 42     }
 43
 44     while ( NULL != fgets(scrambled_word, WORD_MAX_SIZE, stdin) )
 45     {
 46         // 去掉读入的多余换行符
 47         del_newline_symbol(scrambled_word);
 48
 49         // 检查结束
 50         if ( 0 == strcmp(scrambled_word, "XXXXXX") )
 51             break;
 52
 53         // 初始化查找结果集合
 54         memset(words, 0, sizeof(words[0][0]) * N * WORD_MAX_SIZE);
 55         words_num = 0;
 56
 57         // 对scrambled_word生成全排列,依次检查每一个排列
 58         permutation_check(scrambled_word, scrambled_word);
 59
 60         // output 当前的scrambled_word的查找结果
 61         if ( 0 == words_num )
 62             printf("NOT A VALID WORD\n");
 63         else
 64             print();
 65         printf("******\n");
 66     }
 67     return 0;
 68 }
 69
 70 void del_newline_symbol(char* str)
 71 {
 72     int len = strlen(str);
 73     if ( ‘\n‘ == str[len-1] )
 74         str[len-1] = ‘\0‘;
 75 }
 76
 77 void print()
 78 {
 79     int i = 0;
 80     // 输出要求按照字典序递增,故先对words排序
 81     qsort(words, words_num, sizeof(words[0]), cmp);
 82
 83     printf("%s\n", words[i]);
 84     for ( i = 1; i < words_num; ++i )
 85     {
 86         // 如果存在重复匹配,只输出一次
 87         if ( 0 != strcmp(words[i], words[i-1]) )
 88             printf("%s\n", words[i]);
 89     }
 90 }
 91
 92 int cmp(const void* a, const void* b)
 93 {
 94     return strcmp((char *)a, (char *)b);
 95 }
 96
 97 /*
 98  * core algorithm: Permutation全排列算法
 99  * */
100 void permutation_check(char* p_str, char* p_begin)
101 {
102     char * p_ch;
103     if ( ‘\0‘ == *p_begin )
104     {
105         search_in_dictionary(p_str);
106     }
107     else
108     {
109         for ( p_ch = p_begin; *p_ch != ‘\0‘; p_ch++ )
110         {
111             swap(p_begin, p_ch);
112             permutation_check(p_str, p_begin+1);
113             swap(p_begin, p_ch);
114         }
115     }
116 }
117
118 void swap(char* a, char* b)
119 {
120     char t = *a;
121     *a = *b;
122     *b = t;
123 }
124
125 void search_in_dictionary(char str[])
126 {
127     int i;
128     for ( i = 0; i < dic_size; ++i )
129     {
130         // 从字典中找到了,纪录下来
131         if ( 0 == strcmp(str, dictionary[i]) )
132         {
133             strncpy(words[words_num], str, WORD_MAX_SIZE);
134             ++words_num;
135         }
136     }
137 }

时间: 2024-10-25 17:21:15

USTC OJ — 1008 Word Amalgamation(组合数学,全排列)的相关文章

Uva 642 - Word Amalgamation sort qsort

 Word Amalgamation  In millions of newspapers across the United States there is a word game called Jumble. The object of this game is to solve a riddle, but in order to find the letters that appear in the answer it is necessary to unscramble four wor

POJ 1318 Word Amalgamation (字符串 STL大水)

Word Amalgamation Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 8665   Accepted: 4172 Description In millions of newspapers across the United States there is a word game called Jumble. The object of this game is to solve a riddle, but

【LeetCode OJ】Word Ladder I

Problem Link: http://oj.leetcode.com/problems/word-ladder/ Two typical techniques are inspected in this problem: Hash Table. One hash set is the words dictionary where we can check if a word is in the dictionary in O(1) time. The other hash set is us

HDU1113 Word Amalgamation

问题链接:HDU1113 Word Amalgamation. 这个问题是一个字典问题,自然用map来实现.问题在于还需要转个弯,不然会掉进陷阱里去的. 查字典问题,通常是单词按照字典顺序存放,然后将要查的单词拆成字母,按单词的字母顺序去查字典.然而要是这样做程序的逻辑就太零碎繁杂了. 于是,把单词中的字符排个顺序作为关键字,来查单词的话就方便了.需要注意的一点,不同的单词有可能具有相同的关键字. 这个程序的关键有容器类map的使用,算法库<algorithm>中函数sort()的使用. AC

hdu1113 Word Amalgamation(超详细解释--map和string的运用)

转载请注明出处:http://blog.csdn.net/u012860063天资 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1113 来吧!!欢迎"热爱编程"的同学报考杭电,期待你加入"杭电ACM集训队"! 7月22-8月21多校联合训练期间,会根据实际负载关闭部分模块,若有不便,请谅解~ Word Amalgamation Time Limit: 2000/1000 MS (Java/Others)    Me

hdu 1113 Word Amalgamation (map)

# include <stdio.h> # include <string> # include <map> # include <iostream> # include <algorithm> using namespace std; int main() { string s,t; int flag; map<string,string>q; while(cin>>s&&s!="XXXXXX&

poj 1318 Word Amalgamation

Word Amalgamation Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9968   Accepted: 4774 Description In millions of newspapers across the United States there is a word game called Jumble. The object of this game is to solve a riddle, but

USTC OJ — 1003 Fibonacci Numbers(组合数学, 简单题)

1. 题目描述 Fibonacci数列定义为: A0 = 0, A1 = 1; An = An-1 + An-2, if n >= 2. 问题:输入一个n( 0 ≤ n ≤ 40 ),计算An. 2. 算法设计 直接利用公式计算即可,时间复杂度O(N),由于数据规模很小,可以选择 先打表,然后对每一个测试数据n,直接输出An: 或者分别对每一个n,计算An. 3. AC Code 1 #include <stdio.h> 2 #define N 41 3 int f[N]; 4 void

USTC OJ — 1011 Problem of Deck(组合数学,递推关系)

1. 题目描述 根据题意,我们可以知道: 在桌子边上放一个尺子(长度为L),为了保持其不掉落,伸出桌面边缘最大长度为1/2L. 在上面的基础上,再累加一个尺子,为了保持其不掉落,伸出下面尺子的边缘最大长度为1/4L. 在累加一个尺子,为了保持其不掉落,伸出下面尺子的边缘最大长度为1/6L. 依次下去... 2. 算法设计 由上面的描述,我们可以得到递推关系: 累加了n把尺子时,延伸出桌子边缘的长度为 length(0) = 0 length(n) = length(n-1) + 1/(2n) ,