• USACO Milking Cow


      天下午无聊,花了1个多小时,做了下USACO中MilkCow这题。初看这题感觉似乎挺难的,求的是最值,莫非用DP?仔细想下,发现并不涉及什么高深的算法,解决这题的关键在于编程的相关技巧。

         按人类的思维,解决这题非常简单,就是合并各个时段,求取极值即可。那么按计算机该怎么做呢?很简单也是这几步,只是把人类合并集合的步骤展开来罢了(计算机可没这么聪明。。。)

      讨论程序首先要看的是数据结构,它关系着算法的效率以及对算法的理解。我这里用的是很简单的数据结构---low和high这两个数组,他们分别存储各个时段的下限和上限值。具体的步骤如下:

      1 对各个集合按下限值进行排序(上限值作为卫星数据),这里用的是插入排序,因为感觉数据量不是很大(5000个数据),还有就是很有可能大部分都是排好序的数据,用快排可能会退化。

      2 合并各集合,这里用到了两个指针i、j,分别指向待合并的集合以及将要被合并的集合,为了节省存储空间,我这里把被合并掉的集合的low和high的相应项都设为0,方便在解决求最值的问题。

      3 求取最值,这里比较简单就不赘述了。

         简单的思想就是如此,这也是这题官方答案的第一种思路,好了,上代码:

    Milking Cow
    1 /*
    2 ID: happyan3
    3 PROG: milk2
    4 LANG: C++
    5  */
    6
    7 #include <iostream>
    8 #include <fstream>
    9 #include <cassert>
    10
    11  using namespace std;
    12
    13  int N;
    14 unsigned int* low = NULL;
    15 unsigned int* high = NULL;
    16
    17  void sort(void); // use insertion sort
    18  void Merge(void);
    19 unsigned int FindLongestMilked(void);
    20 unsigned int FindLongestNoMilked(void);
    21
    22  int main(void)
    23 {
    24 ifstream milk2In;
    25 milk2In.open("milk2.in");
    26
    27 milk2In>>N;
    28
    29 low = new unsigned int[N];
    30 high = new unsigned int[N];
    31
    32 for(int i=0; i < N; i++)
    33 {
    34 milk2In>>low[i]>>high[i];
    35 }
    36
    37 sort();
    38 Merge();
    39
    40 int nLongestMilked = FindLongestMilked();
    41 int nLongestNoMilked = FindLongestNoMilked();
    42
    43 ofstream milk2Out;
    44 milk2Out.open("milk2.out");
    45
    46 milk2Out<<nLongestMilked<<" "<<nLongestNoMilked<<endl;
    47
    48 delete [] low;
    49 delete [] high;
    50 milk2In.close();
    51 milk2Out.close();
    52 return 0;
    53 }
    54  void sort(void)
    55 {
    56 int keyLow = 0;
    57 int keyHigh = 0;
    58 int i = 0;
    59 for(int j=1; j < N; j++)
    60 {
    61 keyLow = low[j];
    62 keyHigh = high[j];
    63
    64 i = j-1;
    65 while(i >= 0 && low[i] > keyLow)
    66 {
    67 low[i+1] = low[i];
    68 high[i+1] = high[i];
    69 i = i-1;
    70 }
    71 low[i+1] = keyLow;
    72 high[i+1]=keyHigh;
    73 }
    74 }
    75
    76
    77  void Merge(void)
    78 {
    79 int i = 0;
    80 int j = 1;
    81 while (i < N && j < N)
    82 {
    83 if(high[i] < low[j]) //无法合并
    84   {
    85 i = j;
    86 j++;
    87 }
    88 else
    89 {
    90 if(high[i] >= high[j]) //可全部包含在内
    91   {
    92 low[j] = 0; // 设置标志表示已被合并
    93   high[j] = 0;
    94 }
    95 else //原上限小于被合并时段上限,求并集
    96 {
    97 high[i] = high[j];
    98 low[j] = 0;
    99 high[j] = 0;
    100 }
    101 j++;
    102 }
    103 }
    104
    105 }
    106
    107
    108
    109
    110 unsigned int FindLongestMilked(void)
    111 {
    112 unsigned int res = 0;
    113
    114 int interval = 0;
    115 for(int i=0; i < N; i++)
    116 {
    117 interval = high[i] - low[i];
    118 if(res < interval)
    119 res = interval;
    120 }
    121
    122 return res;
    123 }
    124
    125
    126 unsigned int FindLongestNoMilked(void)
    127 {
    128 unsigned int res = 0;
    129
    130 int interval = 0;
    131
    132 int i=0;
    133 int j=1;
    134 while(i < N && j < N)
    135 {
    136 if(0 == high[i])
    137 {
    138 i=j;
    139 j++;
    140 }
    141 else
    142 {
    143 if(0 == low[j])
    144 {
    145 j++;
    146 }
    147 else //两者都不为0
    148 {
    149 interval = low[j] - high[i];
    150 if(res < interval)
    151 res = interval;
    152 i=j;
    153 j++;
    154 }
    155 }
    156 }
    157
    158 return res;
    159 }
    160
  • 相关阅读:
    【收集】各种hack
    CSS测试实录一:display的块状元素和行内元素的试验
    【转载加工】:after伪类+content内容生成经典应用举例
    CSS测试实录二:float和标准流
    onreadyStateChange&nbsp;&nbsp;DOMContentLoaded
    Extensions
    Accessing of Rows in Silverlight DataGrid
    Linux应用程序的装载和执行
    top状态细分,进程状态
    定时器的使用和原理浅析,alarm/sleep函数
  • 原文地址:https://www.cnblogs.com/HappyAngel/p/1754995.html
Copyright © 2020-2023  润新知