【备战蓝桥杯】USACO--> Milking Cows[2]
2014-01-29 11:34
288 查看
题目网址:http://wikioi.com/problem/1385/
昨天由于家里有点事情,就没有继续忙了。其实昨天上午已经按照我自己的思路把代码写出来了。可惜结果总有两个不能ac了。
后来参考了相关思路,发现自己思考问题的时候,太过拘谨。不过也可以理解,因为我本身对排序算法就不是很熟悉,总觉得像快速排序里面有递归调用就会很慢。
其实不是这样。后来写出的算法,明显比自己之前想象的算法要快一倍,而且思路清晰,容易调试。
果然,到了真正比赛的时候,还是写思路清晰的算法比较好。一是好调试错误。二是未必会慢。
这个是我自己设想的算法,一个是实现起来繁琐。情况复杂。前后融合都要考虑,二是,写到后面发现,还是要借助排序。因为再不排序,又会复杂,成指数级= =。
其实,本训练的目的,就是掌握不同问题的解决思路,在每个问题解决的时候,学会使用其中应当明白的算法。
自然,解法还是有很多的。但是要以题目本身的目的来围绕着学习。
像本类题目的目的,就是写出容易理解的枚举算法。或者通过一定的优化手段,再来枚举。之前一直没想通这个怎么优化。原来就是利用我一直不熟悉的排序算法。
看来之后还要好好补补排序算法了。先把快排弄好吓,快速理解。
昨天由于家里有点事情,就没有继续忙了。其实昨天上午已经按照我自己的思路把代码写出来了。可惜结果总有两个不能ac了。
后来参考了相关思路,发现自己思考问题的时候,太过拘谨。不过也可以理解,因为我本身对排序算法就不是很熟悉,总觉得像快速排序里面有递归调用就会很慢。
其实不是这样。后来写出的算法,明显比自己之前想象的算法要快一倍,而且思路清晰,容易调试。
果然,到了真正比赛的时候,还是写思路清晰的算法比较好。一是好调试错误。二是未必会慢。
这个是我自己设想的算法,一个是实现起来繁琐。情况复杂。前后融合都要考虑,二是,写到后面发现,还是要借助排序。因为再不排序,又会复杂,成指数级= =。
/* 300---------1000 700-------1200 1500---------2100 2000 2700 1、第一个组合与所有匹配,能融合,就融合,并标记融合过的; 2、产生的新组合与剩下的未标记的融合,同上; 3、该组合不能再融合时,从下一个未标记的开始搜索融合; 4、下一个标记的不能融合时候,再下一个; 5、所有都标记上了,结束。选出最长时间与最短时间 */ #include <stdio.h> #include <stdlib.h> typedef struct _NODE { int beg; int end; }NODE; //0,右边融合;1,左边融合;2,中间,不用理会;-1,不相交 int check(NODE i1,NODE i2) { if( i2.beg >= i1.beg && i2.beg <= i1.end && i2.end > i1.end ) return 0; else if( i2.end >= i1.beg && i2.end <= i1.end && i2.beg < i1.beg ) return 1; else if( i2.beg >= i1.beg&& i2.end<= i1.end) return 2; else return -1; } void quick_sort(NODE *node,int l,int r) { if (l < r) { //Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1 int i = l, j = r; NODE x = node[l]; while (i < j) { while(i < j && node[j].beg >= x.beg) // 从右向左找第一个小于x的数 j--; if(i < j) node[i++] = node[j]; while(i < j && node[i].beg < x.beg) // 从左向右找第一个大于等于x的数 i++; if(i < j) node[j--] = node[i]; } node[i] = x; quick_sort(node, l, i - 1); // 递归调用 quick_sort(node, i + 1, r); } } int main() { int n; scanf("%d",&n); int i; NODE *input = (NODE *)malloc(sizeof(NODE) * n); int *flag = (int *)malloc(sizeof(int) * n); for(i=0 ; i< n; i++) { //0 未标记 ;1已经融合过; 2加工过 flag[i] = 0; scanf("%d %d",&input[i].beg,&input[i].end); } flag[0] = 2; int isAdd = 0; int j=0; int status; int cou=1; while(1) { for( i=j+1 ; i< n ; i++) { if( flag[i]==0) { status = check(input[j],input[i]); if( status==0) { input[j].end= input[i].end; isAdd = 1; flag[i]=1; } else if( status==1) { input[j].beg= input[i].beg; isAdd = 1; flag[i]=1; } else if(status==2 ) { flag[i]=1; } } } //当融合到无法融合的时候,寻找下一个 if( isAdd == 0) { for(i=j ; i < n && flag[i]!=0; i++); //全被标记,结束寻找 if( i==n) { break; } j = i; flag[j] = 2; cou++; } isAdd = 0; } int max_ji = 0,max_meiji = 0; NODE *getMax = (NODE *)malloc(sizeof(NODE) * cou); //筛选出最终的时间组合,并找出最大挤奶时间 for(i=0,j=0 ; i < n; i++) { if(flag[i] ==2) { getMax[j++] = input[i]; max_ji = (input[i].end-input[i].beg) > max_ji ? (input[i].end-input[i].beg) : max_ji; } } //排序先 quick_sort(getMax,0, cou-1); //筛选最大不挤奶时间 for(i=0 ; i< cou-1 ; i++) { max_meiji = (getMax[i+1].beg- getMax[i].end)>max_meiji ?(getMax[i+1].beg- getMax[i].end):max_meiji; } printf("%d %d",max_ji,max_meiji); return 0; }这个是后来根据参考,自己纠正的算法,首先把排序做了。用快排,然后思路就瞬间清晰了。
其实,本训练的目的,就是掌握不同问题的解决思路,在每个问题解决的时候,学会使用其中应当明白的算法。
自然,解法还是有很多的。但是要以题目本身的目的来围绕着学习。
像本类题目的目的,就是写出容易理解的枚举算法。或者通过一定的优化手段,再来枚举。之前一直没想通这个怎么优化。原来就是利用我一直不熟悉的排序算法。
看来之后还要好好补补排序算法了。先把快排弄好吓,快速理解。
#include <stdio.h> #include <stdlib.h> typedef struct _NODE { int beg; int end; }NODE; void quick_sort(NODE *node,int l,int r) { if (l < r) { //Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1 int i = l, j = r; NODE x = node[l]; while (i < j) { while(i < j && node[j].beg >= x.beg) // 从右向左找第一个小于x的数 j--; if(i < j) node[i++] = node[j]; while(i < j && node[i].beg < x.beg) // 从左向右找第一个大于等于x的数 i++; if(i < j) node[j--] = node[i]; } node[i] = x; quick_sort(node, l, i - 1); // 递归调用 quick_sort(node, i + 1, r); } } int main() { int n; scanf("%d",&n); NODE *input = (NODE *)malloc(sizeof(NODE) *n); int i; for(i=0 ; i < n; i++) { scanf("%d %d",&input[i].beg,&input[i].end); } //通过排序的方法,就解决了情况复杂多变的情况。 //本题的核心,就是用排序的方法,简化线段离散化的情况, //使得问题分析变得简单。 quick_sort(input,0,n-1); int max_continus=0,max_idle=0; int max_beg= input[0].beg,max_end = input[0].end; for(i=1 ; i< n ; i++) { //下一个线段的beg在前一个线段内部,下一个线段将被吸收,取两者最大的end if( input[i].beg <= max_end) { max_end = input[i].end>max_end ? input[i].end:max_end; } //反之,将开始另外一段线段的比较。 else { max_continus = (max_end-max_beg)>max_continus ? (max_end-max_beg):max_continus; max_idle = (input[i].beg - max_end)> max_idle ?(input[i].beg - max_end): max_idle; max_beg = input[i].beg; max_end = input[i].end; } } //竟然忽略了最后要把结果再次比较一下。嘿哈。浪费了我20分钟。 max_continus = (max_end-max_beg)>max_continus ? (max_end-max_beg):max_continus; max_idle = (input[i].beg - max_end)> max_idle ?(input[i].beg - max_end): max_idle; printf("%d %d",max_continus,max_idle); return 0; }
相关文章推荐
- 【备战蓝桥杯】USACO--> Milking Cows[1]
- 【备战蓝桥杯】USACO--> Transformation
- 【备战蓝桥杯】USACO-->palsquare
- 【备战蓝桥杯】USACO-> Beads
- 【备战蓝桥杯】USACO--> milk
- 【备战蓝桥杯】USACo--> airpro【改变策略】
- 【备战蓝桥杯】USACO-->dualpul
- 【备战蓝桥杯】USACO-->barn(未完)
- 【备战蓝桥杯】USACO-->crypt
- 【备战蓝桥杯】USACO--> Beads 2.0
- 【备战蓝桥杯】USACO--> calfflac 奶牛回文
- 【备战蓝桥杯】USACO--> barn (终结)
- <备战蓝桥杯之嵌入式>——TIM
- <备战蓝桥杯之嵌入式>——PWM
- <备战蓝桥杯之嵌入式>——输入捕获
- <备战蓝桥杯之嵌入式>——USART
- <备战蓝桥杯之嵌入式>——SYSTICK
- <备战蓝桥杯之嵌入式>——BUTTON按键实验
- <备战蓝桥杯之嵌入式>——USART
- <备战蓝桥杯之嵌入式>——EXTI