首页 > 其他 > 详细

微软编程一小时——Longest Repeated Sequence

时间:2014-04-25 02:37:40      阅读:499      评论:0      收藏:0      [点我收藏+]

  好,今晚兴致正浓,再来一篇,再说一遍,只是个人感想,高手一定轻喷啊,小弟还没上路呢。。。

  这篇是微软编程一小时的第二题,废话不多说,上题目描述先。

 

题目2 : Longest Repeated Sequence
  时间限制:10000ms
  单点时限:1000ms
  内存限制:256MB

 

描述
  You are given a sequence of integers, A = a1, a2, ... an. A consecutive subsequence of A (say ai, ai+1 ... aj) is called a "repeated sequence" if it appears more than once in A (there exists some positive k that ai+k = ai, ai+k+1 = ai+1, ... aj+k = aj) and its appearances are not intersected (i + k > j).

Can you find the longest repeated sequence in A?

 

输入
  Line 1: n (1 <= n <= 300), the length of A.
  Line 2: the sequence, a1 a2 ... an (0 <= ai <= 100).

 

输出
  The length of the longest repeated sequence.

 

样例输入
  5
  2 3 2 3 2


样例输出
  2

 

  不知道这题有没有哪位大侠直接暴力过的,感觉n的级别,三次方的话1s有点悬。。。我的想法是,用二分法确定序列最长的长度。然后为了快速判断某一个长度是否成立,建立一个next数组,保存的是从右边开始跟它相等的最近的一个元素的位置,若右方没有与之相等的元素,next数组值为-1,这样在寻找序列起始位置的时候就可以根据next数组直接往下跳了,节省了很多不必要的判断时间。不过这题我当时做的时候考虑不周,在使用next数组往后跳的时候只选择了第一个满足条件的位置,忘了后面还可能有很多个满足条件的位置,只得了90分,结果是WA。当时只剩下十几分钟,就没来得及细想,后来同学问我是怎么做的时候,我才发现这个问题,可惜已经无法提交了。先把比赛时候的代码贴出来吧。

 

bubuko.com,布布扣
 1 //  得分: 90 / 100
 2 //  题目: Longest Repeated Sequence
 3 //  结果: WA
 4 //  语言: G++
 5 //  时间: 14ms
 6 //  内存: 7MB
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 
11 const int N = 305;
12 
13 int n;
14 int seq[N], next[N];
15 
16 // 判断当前长度是否满足条件
17 bool check(int num)
18 {
19     if (0 == num)
20         return true;
21     int i, j, k, res, up = n - (num << 1) + 1;
22     for (i = 1; i <= up; i++) {
23         // next数组为-1,后面没有相等元素,跳过
24         if (-1 == next[i])
25             continue;
26         j = next[i];
27         k = j - i;
28         // 序列长度至少为num,才开始比较
29         while (k < num && -1 != next[j]) {
30             k += next[j] - j;
31             j = next[j];
32         }
33         if (k < num)
34             continue;
35         // 这个地方只考虑第一个满足条件的j,错了
36         k = i, res = 0;
37         while (seq[k] == seq[j] && j <= n) {
38             res++;
39             k++, j++;
40             if (res >= num)
41                 return true;
42         }
43     }
44     return false;
45 }
46 
47 int main(void)
48 {
49     int i, j;
50     int left, right, mid;
51     while (EOF != scanf("%d", &n)) {
52         memset(next, -1, sizeof(next));
53         for (i = 1; i <= n; i++) {
54             scanf("%d", &seq[i]);
55             // 设置元素的next数组,右边与其最接近的相等元素的位置
56             for (j = i - 1; j >= 1; j--) {
57                 if (seq[j] == seq[i]) {
58                     next[j] = i;
59                     break;
60                 }
61             }
62         }
63         left = 0, right = (n >> 1) + 1;
64         // 二分法确定满足条件的最长长度
65         while (left <= right) {
66             mid = (left + right) >> 1;
67             if (check(mid))
68                 left = mid + 1;
69             else
70                 right = mid - 1;
71         }
72         printf("%d\n", left - 1);
73     }
74     return 0;
75 }
bubuko.com,布布扣

 

  然后这是后来修改的版本,考虑了所有满足条件的位置。

 

bubuko.com,布布扣
 1 #include <cstdio>
 2 #include <cstring>
 3 
 4 const int N = 305;
 5 
 6 int n;
 7 int seq[N], next[N];
 8 
 9 // 判断当前长度是否满足条件
10 bool check(int num)
11 {
12     if (0 == num)
13         return true;
14     int i, j, k, res, up = n - (num << 1) + 1;
15     for (i = 1; i <= up; i++) {
16         // next数组为-1,后面没有相等元素,跳过
17         if (-1 == next[i])
18             continue;
19         j = next[i];
20         k = j - i;
21         // 序列长度至少为num,才开始比较
22         while (k < num && -1 != next[j]) {
23             k += next[j] - j;
24             j = next[j];
25         }
26         if (k < num)
27             continue;
28         // 考虑所有满足条件的位置j
29         do {
30             int l = i, r = j;
31             res = 0;
32             while (seq[l] == seq[r] && r <= n) {
33                 res++;
34                 l++, r++;
35                 if (res >= num)
36                     return true;
37             }
38             j = next[j];
39         } while (-1 != j);
40     }
41     return false;
42 }
43 
44 int main(void)
45 {
46     int i, j;
47     int left, right, mid;
48     while (EOF != scanf("%d", &n)) {
49         memset(next, -1, sizeof(next));
50         for (i = 1; i <= n; i++) {
51             scanf("%d", &seq[i]);
52             // 设置元素的next数组,右边与其最接近的相等元素的位置
53             for (j = i - 1; j >= 1; j--) {
54                 if (seq[j] == seq[i]) {
55                     next[j] = i;
56                     break;
57                 }
58             }
59         }
60         left = 0, right = (n >> 1) + 1;
61         // 二分法确定满足条件的最长长度
62         while (left <= right) {
63             mid = (left + right) >> 1;
64             if (check(mid))
65                 left = mid + 1;
66             else
67                 right = mid - 1;
68         }
69         printf("%d\n", left - 1);
70     }
71     return 0;
72 }
bubuko.com,布布扣

 

微软编程一小时——Longest Repeated Sequence,布布扣,bubuko.com

微软编程一小时——Longest Repeated Sequence

原文:http://www.cnblogs.com/guikeyi/p/3687418.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!