C++_USACO_Milking Cows

/*
PROB:milk2
LANG:C++
*/
#include<iostream>
#include<fstream>
#include<string>
#include<vector>
using namespace std;
int main(){
    ifstream fin("milk2.in");
    ofstream fout("milk2.out");
    int n;
    int start_t;
    int end_t;
    int t;
    fin>>n;
    int i=0;
    int count=0;
    int max_yes;
    int max_no;
    fin>>start_t;
    while(i<2*n-1&&count==0){
        count++;
        fin>>end_t;
        i++;
        if(i==1){
            max_yes=end_t-start_t;
            max_no=0;
        }
        while(i<2*n-1){
            fin>>t;
            i++;
            if(t<=end_t&&t>=start_t){
                fin>>t;
                i++;
                end_t=(t>end_t?t:end_t);                
            }
            else if(t>end_t){
                max_yes=(end_t-start_t>max_yes?end_t-start_t:max_yes);
                max_no=(t-end_t>max_no?t-end_t:max_no);
                start_t=t;
                count=0;
                break;
            }
        }
    }
    fout<<max_yes<<" "<<max_no<<endl;
}

这是我自己的代码,但还需要之前进行一次快速排序,把每个初始时间按从小到大的顺序排列之后,才可以。现在只能对开始时间已经排好的计算出正确的答案。
沙老师提到的方法,我已经实现如下:

预处理:
 建立一个数组a。
 读入,若为起点将a[i]加1,若为终点将a[i]减1。
 (这时顺便找出总的起点与终点);
算法开始:
 将数组扫一遍(注意从总的起点扫到总的终点),这时将x(初始为0)加上a[i]。
  若遇到x由0变1,或由1变0,
  将这个点计入数组ans[]。
  然后再将ans扫描一遍,大家可能都想到了:
   若i为奇数,a[i+1]-a[i] 应该是有人的时间间隔;
   若i为偶数,反之。

 

#include<iostream>
#include<fstream>
using namespace std;
int main(){
    ifstream fin("milk2.in");
    ofstream fout("milk2.out");
    int n;
    int i=0;
    int t;
    static long times[1000000]={0};
    int count=0;
    int start_t=0;
    int end_t=0;
    int max_yes=0;
    int max_no=0;
    bool is_end=false;
    fin>>n;
    while(i<2*n){
        fin>>t;
        times[t]++;
        fin>>t;
        times[t]--;
        i++;
    }
    for(long k=0;k<1000000;k++){
        if(times[k]){
            start_t=k;
            break;
        }
    }
    for(long j=0;j<1000000;j++){
        if(times[j]){
            count+=times[j];
            if(count==1&&is_end){
                start_t=j;
                max_no=(max_no>start_t-end_t?max_no:start_t-end_t);
                is_end=false;
                continue;
            }
            if(count==0){
                end_t=j;
                max_yes=(max_yes>end_t-start_t?max_yes:end_t-start_t);
                is_end=true;
                continue;
            }
        }
    }
    fout<<max_yes<<" "<<max_no<<endl;
    return 0;
}

相当于建立了一个坐标轴,以各个时刻为下标记录在数组中。count从1到0,表示是一段时间有人挤牛奶;count从0到1,表示这段时间没有人挤牛奶。避免了开始时刻的排序。

posted @ 2013-07-20 15:53  开心成长  阅读(177)  评论(0编辑  收藏  举报