[USACO] Broken Necklace
2011-02-23 15:01
204 查看
充满杯具的一道题,提交了5次才AC。。。
最简单的方法是步长为1的遍历整个项链,在断开处向两个方向搜索,然后求和的最大值(分析的解法一),但是效率不高。
如果我们找局部最长的满足要求的子串,则子串内部不再需要遍历,比如“rrrbb”,两个r之间是不需要隔断的,这样步长变大了,不过遇到brbrbr这样的情况也无能为力。。。
根据例子的提示,把字符串首尾相连构造一个2倍长的数组,就不需要考虑取模的问题了。
最外层循环i<n-1是因为i=n-1是表示在最末端断开,所以无须再进入循环了。
分析的解法一:定义break的位置和方向,从1到n进行遍历,找最大值。但是注意类似“rrr”这种情况会导致两个方向重复计算,要特殊处理。
分析的解法二:DP,唉!没想到啊,O(n)的复杂度。解法声明了两个800*2,一个800,一个400(这个可以省下的)的字符数组,明显的空间换时间。
分析的解法三:与解法一类似,但是是单向遍历找到每个开始字符可以构造的最长的序列,此序列是断开处两个字符串的整体,比如“rrrbbrr”,第一次遍历起始点为r,得到长度为5,断点在rrr和bb之间。
整体来说,此题没有想到DP很是失败,我的方法不好理解,想的条件还多,易错,调试麻烦,没有解法一的易懂以及解法二的简洁,解法三比较有新意。在分析题的过程中有些浮躁和草率,没有集中精神,比如右边子串与左边子串的重叠问题,当右边子串变成左边吸收原来的左边子串邻接的w问题等等,这导致在最后编码时很多边界条件和特殊情况没有考虑到,wa多次!
心平气和,再接再厉!!
最后一点:把心里想的用文字写出来真是一件不太容易的事情。。。:P
最简单的方法是步长为1的遍历整个项链,在断开处向两个方向搜索,然后求和的最大值(分析的解法一),但是效率不高。
如果我们找局部最长的满足要求的子串,则子串内部不再需要遍历,比如“rrrbb”,两个r之间是不需要隔断的,这样步长变大了,不过遇到brbrbr这样的情况也无能为力。。。
根据例子的提示,把字符串首尾相连构造一个2倍长的数组,就不需要考虑取模的问题了。
最外层循环i<n-1是因为i=n-1是表示在最末端断开,所以无须再进入循环了。
/* ID: LANG: C TASK: beads */ #include <stdio.h> #include <string.h> #include <stdlib.h> #define N 350 int main() { FILE *fin = fopen("beads.in", "r"); FILE *fout = fopen("beads.out", "w"); char nklace[2 * N + 1]; int left, right, max; int i, j, n; char rc; fscanf(fin, "%d %s", &n, nklace); for(i = 0; i < n; i++) nklace[n + i] = nklace[i]; i = -1; j = 0; right = max = 0; while(i < n - 1) {/*i指示断开处左边的末端,i<n造成一次wa,17个w那个用例*/ left = right; while(i - left > 0 && nklace[i - left] == 'w')/*向左搜索w,例子中最后7位bw|rwrrb出错*/ left++; rc = 'x'; while(j < n || (j - n < i - left)) {/*原来写成j<2n,结果3个r的用例wa,没想到j>n时会与前面的划分重叠这一条件*/ if(rc == 'x' && nklace[j] != 'w') rc = nklace[j]; else if(rc != 'x' && nklace[j] != 'w' && rc != nklace[j]) break; j++; } right = j - i - 1; if(left + right > max) max = left + right; i = j - 1; } fprintf(fout, "%d/n", max);/*写成了printf,杯具了一次!*/ exit(0); }
分析的解法一:定义break的位置和方向,从1到n进行遍历,找最大值。但是注意类似“rrr”这种情况会导致两个方向重复计算,要特殊处理。
分析的解法二:DP,唉!没想到啊,O(n)的复杂度。解法声明了两个800*2,一个800,一个400(这个可以省下的)的字符数组,明显的空间换时间。
分析的解法三:与解法一类似,但是是单向遍历找到每个开始字符可以构造的最长的序列,此序列是断开处两个字符串的整体,比如“rrrbbrr”,第一次遍历起始点为r,得到长度为5,断点在rrr和bb之间。
整体来说,此题没有想到DP很是失败,我的方法不好理解,想的条件还多,易错,调试麻烦,没有解法一的易懂以及解法二的简洁,解法三比较有新意。在分析题的过程中有些浮躁和草率,没有集中精神,比如右边子串与左边子串的重叠问题,当右边子串变成左边吸收原来的左边子串邻接的w问题等等,这导致在最后编码时很多边界条件和特殊情况没有考虑到,wa多次!
心平气和,再接再厉!!
最后一点:把心里想的用文字写出来真是一件不太容易的事情。。。:P
相关文章推荐
- USACO TRAINING - PROB Broken Necklace
- USACO 1.1.4 - Broken Necklace(DP)
- |洛谷|模拟|P1203 [USACO1.1]坏掉的项链Broken Necklace
- Broken Necklace(USACO)
- USACO 1.1 broken necklace 分析
- Usaco 1.1.4 破碎的项链(Broken Necklace)
- usaco 1.1.4 Broken Necklace 一道题可以犯多少脑残
- USACO天梯--Broken Necklace
- 自己的usaco代码---PROB Broken Necklace
- USACO_1_1_Broken Necklace
- [USACO1.1]坏掉的项链Broken Necklace
- Broken Necklace(USACO官方)
- 洛谷 P1203 [USACO1.1]坏掉的项链Broken Necklace
- USACO:Broken Necklace
- USACO - Chapter1 Section 1.1 - Broken Necklace
- USACO 1.1.4 Broken Necklace(模拟)
- Broken Necklace(USACO官方)
- USACO<s1.1.4:Broken Necklace>字符串
- USACO 1.1 Broken Necklace
- USACO-Section1.1 Broken Necklace【记忆化搜索】