Engine
Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 772 Accepted Submission(s): 172
Problem Description
谷歌、百度等搜索引擎已经成为了互连网中不可或缺的一部分。在本题中,你的任务也是设计一个搜索论文的搜索引擎,当然,本题的要求比起实际的需求要少了许多。
本题的输入将首先给出一系列的论文,对于每篇论文首先给出标题,然后给出它被引用的次数。然后会有一系列的搜索询问,询问标题中包含特定关键词的论文有哪些。
每一个询问可能包含多个关键词,你需要找出标题包含所有关键词的论文。
“包含”必须是标题中有一个词正好是给定的关键词,不区分大小写。
对每个询问,都按被引用的次数从多到少输出满足条件的论文的标题。如果有被引用的次数相同的论文,则按照论文在输入中的顺序排列,先给出的论文排在前面。
本题的输入将首先给出一系列的论文,对于每篇论文首先给出标题,然后给出它被引用的次数。然后会有一系列的搜索询问,询问标题中包含特定关键词的论文有哪些。
每一个询问可能包含多个关键词,你需要找出标题包含所有关键词的论文。
“包含”必须是标题中有一个词正好是给定的关键词,不区分大小写。
对每个询问,都按被引用的次数从多到少输出满足条件的论文的标题。如果有被引用的次数相同的论文,则按照论文在输入中的顺序排列,先给出的论文排在前面。

Input
输入包含多组数据。
每组数据首先有一行包含一个整数N(1<=N<=1000),表示论文的数目,N=0表示输入结束。每组论文的信息第一行是论文的标题,由字母(大小写均可)和空格组成,不超过10个词,每个词不超过20个字符,标题总共不超过250个字符。第二行是一个整数K(0<=K<=108),表示它被引用的次数。在论文信息结束以后,有一行包含一个整数M(1<=M<=100),表示询问的数目。接下来有M行,每行是一个询问,由L(1<=L<=10)个空格分开的词构成,每个词不超过20个字符。
每组数据首先有一行包含一个整数N(1<=N<=1000),表示论文的数目,N=0表示输入结束。每组论文的信息第一行是论文的标题,由字母(大小写均可)和空格组成,不超过10个词,每个词不超过20个字符,标题总共不超过250个字符。第二行是一个整数K(0<=K<=108),表示它被引用的次数。在论文信息结束以后,有一行包含一个整数M(1<=M<=100),表示询问的数目。接下来有M行,每行是一个询问,由L(1<=L<=10)个空格分开的词构成,每个词不超过20个字符。
Output
对每个询问,按照题目给定的顺序输出满足条件的论文的标题;如果没有满足条件的论文,就不输出。在每组询问的输出之后输出一行”***”,在每组数据的输出之后输出一行”---”。
Sample Input
6 Finding the Shortest Path 120 Finding the k Shortest Path 80 Find Augmenting Path in General Graph 80 Matching in Bipartite Graph 200 Finding kth Shortest Path 50 Graph Theory and its Applications 40 6 shortest path k shortest path graph path find application 0
Sample Output
Finding the Shortest Path Finding the k Shortest Path Finding kth Shortest Path *** Finding the k Shortest Path *** Matching in Bipartite Graph Find Augmenting Path in General Graph Graph Theory and its Applications *** Finding the Shortest Path Finding the k Shortest Path Find Augmenting Path in General Graph Finding kth Shortest Path *** Find Augmenting Path in General Graph *** *** ---//搜索之后才知道这也是个模拟题,自己认为怎么也是和字符 //串查找有关系 //第一次WA //输入有问题,要while,第二次还是WA,额,继续查错 //最后发现错误竟然是是在strcmpp()函数里没有把s2改成小写字母,只是把s1改成小写字母,好吧,查了很久,就是找不到问题,后来一句句看才发现。。。 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #define MAXN 1005 #define MAXS 255 #define MAXG 11 #define MAXL 21 typedef struct headlines { char stringwen[MAXS]; //最多10个词,整个长度最长不超过250 int yiyongnum; int index; char singlestr[MAXG][MAXL]; int len; }headline; headline filewen[MAXN]; headline searchwen; int tc = 0; void init() { int i = 0; int j = 0; int m = 0; int n = 0; for (i = 0; i < MAXN;i++) { for (j = 0; j < MAXS;j++) { filewen[i].stringwen[j] = '\0'; } filewen[i].yiyongnum = 0; filewen[i].index = 0; filewen[i].len = 0; for (m = 0; m < MAXG; m++) { for (n = 0; n < MAXL; n++) { filewen[i].singlestr[m][n] = '\0'; } } } return; } void initquery() { int j = 0; int m = 0; int n = 0; for (j = 0; j < MAXS; j++) { searchwen.stringwen[j] = '\0'; } searchwen.len = 0; for (m = 0; m < MAXG; m++) { for (n = 0; n < MAXL; n++) { searchwen.singlestr[m][n] = '\0'; } } return; } int strlength(char *str) { int size = 0; while ('\0' != *str) { size += 1; str++; } return size; } void parse(headline* input) { int i = 0; int len = strlength(input->stringwen); int num = 0; int sinleindex = 0; int spaceflag = 0; for (i = 0; i < len; i++) { //不能让空格进来,也不能让空字符串过来 if ((' ' == input->stringwen[i]) || ('\0' == input->stringwen[i])) { spaceflag = 1; continue;//空格直接过滤 } //什么情况下需要转到下一行 if ((1 == spaceflag) && (0 != sinleindex))//如果第一个就是空格,肯定要去掉这个空格 { //那就是之前已经保存了一些字符,然后遇到了空格 input->singlestr[num][sinleindex] = '\0'; num += 1; sinleindex = 0; } spaceflag = 0; input->singlestr[num][sinleindex] = input->stringwen[i]; sinleindex += 1; } input->len = num + 1; return; } int cmp(headline check1, headline check2) { if (check1.yiyongnum > check2.yiyongnum) { return 1; } else if (check1.yiyongnum == check2.yiyongnum) { if (check1.index > check2.index) { return -1; } else { return 1; } } else { return -1; } } //这样就是从大到小排序,也可以吧,cmp一定要注意啊,就是这么写的 void paixu(headline *str, int start , int end) { int i = start; int j = end; //char tmp[MAXS]; int m = 0; /*for (m = 0; m < str[start].len;m++) { tmp[m] = str[start].stringwen[m]; }*/ headline tmp; tmp = str[start]; //先用引用数作为关键字排序,然后再用序号作为第二关键字来排序 //排序还是用快排来做 if (start > end) return; while (i<j) { //先从右往左找,右边的数总是大的 while ((i < j) && (cmp(str[j], tmp) <=0)) { j--; } str[i] = str[j]; while ((i < j) && (cmp(str[i], tmp)>=0)) { i++; } str[j] = str[i]; } str[i] = tmp; paixu(str, start, i-1); paixu(str, i+1, end); //不能写i return; } int strcmpp(char* s1, char* s2) { while (s1 && s2 && ('\0' != *s1) && ('\0' != *s2)) { //先弄下大小写 if ((*s1 >= 'A') && (*s1 <= 'Z')) { *s1 += ('a' - 'A'); //这个要注意,自己一开始写错了 } if ((*s2 >= 'A') && (*s2 <= 'Z')) { *s2 += ('a' - 'A'); //这个要注意,自己一开始写错了 } if (*s1 != *s2) return 0; s1++; s2++; } return 1; } int find(int fileindex, int searchindex) { int i = 0; int len1 = 0; int len2 = strlength(searchwen.singlestr[searchindex]); for (i = 0; i < filewen[fileindex].len; i++) { len1 = strlength(filewen[fileindex].singlestr[i]); if (len1 != len2) continue; if (1 == strcmpp(filewen[fileindex].singlestr[i], searchwen.singlestr[searchindex])) { return 1; } } return 0; } void getans() { int i = 0; int j = 0; int findflag = 1; for (i = 1; i <= tc;i++) { findflag = 1; //在第一条论文里比较查询的单词 for (j = 0; j < searchwen.len;j++) { if (0 == find(i, j)) { findflag = 0; break;//说明这条没找到,那下面的就不用找了 } } if (1 == findflag) { //如果都找到了,就输出 printf("%s\n", filewen[i].stringwen); } } return; } int main() { int checknum = 0; int i = 0; freopen("input.txt","r",stdin); while ((1 == scanf("%d", &tc))&& (0 != tc)) { init(); for (i = 1; i <= tc; i++) { getchar(); gets(filewen[i].stringwen); //之前没管那个\n就这一直gets不到字符串 scanf("%d", &filewen[i].yiyongnum); filewen[i].index = i;//因为后面需要排序,所以这个序列号也要存着 if (7 == i) { tc = tc; } parse(&filewen[i]); //getchar(); } paixu(filewen, 1, tc); //开始排序了,用快排 scanf("%d", &checknum); getchar(); for (i = 1; i <= checknum; i++) { initquery(); gets(searchwen.stringwen); //分解 parse(&searchwen); getans(); printf("***\n"); } printf("---\n"); } return 0; }