浙工大OJ-1796

http://acm.zjut.edu.cn/ShowProblem.aspx?ShowID=1796

RunIDUserProblemResultTime(MS)Memory(K)LengthLanguageSubmit Time
871829Code1231796Accepted72562357GCC2012-1-8 0:46:22

Preparing for CET 6 
Time Limit:50MS  Memory Limit:32768K

Description:

英语6级就要开考了,可是Fatboy连单词都还没有背,这下可把他急坏了。于是他只好拿出单词册来,开始背单词。 背了一段时间后,Fatboy发现了一个背单词的高效方法。当把单词头尾相接串成一组单词后,可以一下子把串起来的所有单词都记住。比如:fatboy yard derv vivid ,这4个单词每个单词的头字母都与前一个单词的尾字母相同,那么Fatboy就可以一下子记住这4个单词。Fatboy拿着单词册,产生了一个疑问: “如果只串一次,我最多可以背多少单词呢?” 下面就请你编个程序来帮助他解决这个问题,记住:每个单词只能用一次,单词串接时单词出现的先后顺序必须和单词册中单词出现的先后顺序一样。如:假如单词册中单词出现的顺序是:12345 ,那么单词串接顺序不能是:5421或5134,而134则是一个合法串接。

Input:

每组数据第一行为数N(1≤N≤200),表示单词册里有多少个单词,紧接的N行按单词在单词册中出现顺序给出单词,输入文件以一个0表示结尾。

Output:

对应每一组单词输出一个M,表示Fatboy最多可以记住多少单词。每个输出占一行。

Sample Input:

4
fatboy 
yard 
derv 
vivid
5
fatboy 
yard 
derv 
vivid
uinque
2
apple
orange
0

Sample Output:

4
4
1

Source:

Fatboy

-------------------------------

思路:

     1. 由于单词只能用一次,要考虑单词重复问题。

     2. 顺序只能从头到尾,不能乱序。

     构造结构体如下:

#define CH_MAX			256
#define WORD_LENGTH		256

typedef struct word_t{
	char word[WORD_LENGTH];
	char length;
	char isUsed;
	int next;
} WORD_TYPE, * LPWORD_TYPE;

      next  用来串联所有一样的单词,减少比较的次数。

      单词的比较方法,拿来判断两个单词是否一样:

int compare(char *srcStr, char *tagStr) {
	while (*srcStr == *tagStr && *tagStr != '\0' && *srcStr != '\0') {
		srcStr++;
		tagStr++;
	}
	return (*tagStr == *tagStr && *tagStr == '\0') ? 1 : 0;
}

int WORDCompare(LPWORD_TYPE src, LPWORD_TYPE tag){
	if (src->length == tag->length)
		return compare(src->word, tag->word);
	else
		return 0;
}

    做完之后,就要开始填数据了。

   

while (EOF != scanf("%d%*c", &g_iCount) && g_iCount != 0) {
		for (i = 0; i < g_iCount; i++) {
			j = 0;
			WordList[i].word[j] = getchar();
			while ('\n' != WordList[i].word[j]) {
				j++;
				while (' ' == (WordList[i].word[j] = getchar())); //这句空格剔除去掉就WA,可以看出每条测试数据后面还有空格,这就是题目的悲催之处,OJ上这种问题挺多的。
			}
			WordList[i].word[j] = '\0';
			WordList[i].isUsed = 0;
			WordList[i].length = j;
			WordList[i].next = -1;
		}
		for (i = 0; i < g_iCount; i++)  {  //把所有一样的单词串联一起
			int k = i;
			for (j = k + 1; j < g_iCount; j++) {
				if (WORDCompare(&WordList[k], &WordList[j])) {
					WordList[k].next = j;
					k = j;
				}
			}
		}
		result = 0;

		for (i = 0; i< g_iCount; i++) {  //这里写的比较罗嗦。

			int k = WordList[i].next;
			while (k != -1) { //把所有和第一个单词一样的单词都标记为已经被使用。
				WordList[k].isUsed = 1;
				k = WordList[k].next;
			}

			if (result < (tempResult = deep(WordList[i].word[ WordList[i].length - 1 ], i + 1))) {
				result = tempResult;
			}

			k = WordList[i].next;
			while (k != -1) {//这里在上面的搜索结束之后恢复原样。
				WordList[k].isUsed = 0;
				k = WordList[k].next;
			}
		}

		printf("%d\n", result == 0 ? 1 : result);
	}

搜索方法:

     

int deep(char tp, int k)
{
	int j, i, tempResult, result = 0;
	if (k >= g_iCount)
		return 1;
	for (i = k; i < g_iCount; i++) {
		
		int k = WordList[i].next;

		if (WordList[i].isUsed) { //被使用了就跳过
			continue;
		}
		
		while (k != -1) { //否则做同样的事情,和第一个单词一样的单词都做标记
			WordList[k].isUsed = 1;
			k = WordList[k].next;
		}

		if (!WordList[i].isUsed && tp == WordList[i].word[0]) {
			if ( result < (tempResult = deep(WordList[i].word[ WordList[i].length - 1 ], i + 1) ) ) {
				result = tempResult;
			}
		}

		k = WordList[i].next;
		while (k != -1) {//回复
			WordList[k].isUsed = 0;
			k = WordList[k].next;
		}
	}

	return result + 1;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值