[Swust OJ 763]--校门外的树 Plus(暴力枚举)

 

题目链接:http://acm.swust.edu.cn/problem/0763/

Time limit(ms): 1000      Memory limit(kb): 65535

西南某科技大学的校门外有N排树,每一排树的长度可能不同。每一棵树都用字符作了一个标记。


现在由于学校修建教师公寓,需要在每排树中砍一段连续的树。要求是在每一排树中砍掉的那一段树标记序列都相同。


例如第1排:ABCD,第2排BCDFF,第3排:BRCD,那么我们就可以在每一排树中砍掉CD。请注意下面测试数据的第二组,我们可以砍掉RO,和OR,即只要求标记序列相同,但是在原来那一排树里的方向没有要求。

Description

第一行输入有几组测试数据t (1 <= t <= 10)。


对每一组测试数据,首先输入数字N (1 <= n <= 100)表示有多少排树,每排树的最大长度为100。


接下来的N行,为每一排树的序列。

Input

对于每一组测试数据,输出最多能在一排树砍掉多少棵树。

Output
1
2
3
4
5
6
7
8
9
2
3
ABCD
BCDFF
BRCD
2
rose
orchid
 
Sample Input
1
2
2
2
Sample Output
 
解题思路:直接从大到小暴力枚举所有字符串即可(数据较小,貌似较大用的是后缀数组,并不会Orz~~),不考虑正反,需把字符串反向考虑进来
 
代码如下:
 1 #include <stdio.h>
 2 #include <string.h>
 3 int main(){
 4     int t, n, i, j, k, L, len, ans;
 5     char str[101][101], s1[101], s2[101];
 6     scanf("%d", &t);
 7     while (t--){
 8         int min = 105, ptr;
 9         scanf("%d", &n);
10         for (i = 0; i < n; i++){
11             scanf("%s", str[i]);
12             len = strlen(str[i]);
13             if (len<min){
14                 min = len;
15                 ptr = i;
16             }
17         }
18         //从大到小枚举所有可能长度
19         for (i = min; i>0; i--){
20             for (j = 0; j <= min - i; j++){
21                 //枚举当前长度下的所有子序列的正反序列
22                 for (k = j, L = 0; k <= i + j - 1; k++, L++){
23                     s1[L] = str[ptr][k];
24                     s2[L] = str[ptr][j + i - 1 - L];
25                 }
26                 s1[L] = s2[L] = '\0';
27                 for (k = 0; k < n; k++){
28                     if (!strstr(str[k], s1) && !strstr(str[k], s2))
29                         break;
30                 }
31                 if (k == n)break;
32             }
33             if (k == n)break;
34         }
35         printf("%d\n", i);
36     }
37     return 0;
38 }
View Code

 

posted @ 2015-06-14 14:02  繁夜  阅读(501)  评论(0编辑  收藏  举报