USACO Milking Cows

Three farmers rise at 5 am each morning and head for the barnto milk three cows. The first farmer begins milking his cow at time300 (measured in seconds after 5 am) and ends at time 1000. Thesecond farmer begins at time 700 and ends at time 1200. The thirdfarmer begins at time 1500 and ends at time 2100. The longestcontinuous time during which at least one farmer was milking a cowwas 900 seconds (from 300 to 1200). The longest time no milking wasdone, between the beginning and the ending of all milking, was 300seconds (1500 minus 1200).

Your job is to write a program that will examine a list ofbeginning and ending times for N (1 <= N <= 5000) farmersmilking N cows and compute (in seconds):

  • The longest time interval at least one cow was milked.
  • The longest time interval (after milking starts) during whichno cows were being milked.

PROGRAM NAME: milk2

INPUT FORMAT

Line 1: The single integer
Lines 2..N+1: Two non-negative integers lessthan 1,000,000, respectively the starting and ending time in secondsafter 0500

SAMPLE INPUT (file milk2.in)

3
300 1000
700 1200
1500 2100

OUTPUT FORMAT

A single line with two integers that represent the longestcontinuous time of milking and the longest idle time.

SAMPLE OUTPUT (file milk2.out)

900 300

 -----------------------------------------------------------------------------------------------------------------


這道題典型的棧的思想。


把開始和結束操作放在一起排序,成爲時間線,而開始和結束操作都位於時間線上某一點,因此可以維護一個保存開始操作的棧,程序按時間線走,遇到開始就把開始壓入棧,遇到結束就彈出一個開始。

(每一個結束必定在它的開始後,所以棧永遠不爲負。)

題目就轉化爲求棧爲空和不爲空的最長時間。

維護一個棧底變量,當全部彈出時棧爲空,此時時間減去最開始的時間就是這次棧不爲空的持續時間;

維護一個最後棧爲空時刻的變量,當壓入開始操作時若棧爲空,則這個開始的時間減去上一次彈出的時間,即爲這次棧爲空的持續時間。


還有一個問題是有可能兩個人的開始和結束位於同一個時間點,造成棧爲負的情況。解決辦法可以在qsort的cmp函數裏把入棧放在前面,也可以在遍歷時間線時判斷前後的時間值,如果時間值相同且操作相反,直接continue。


/*
ID: windroid
LANG: C++
TASK: milk2
*/
#include<iostream>
#include<fstream>
#include<list>
#include<algorithm>
using namespace std;

int cmp(const void* p1, const void* p2){
    return (*(pair<int,int>*)p1).first - (*(pair<int,int>*)p2).first;
}
pair<int ,bool> t[10005];
int main(){
    ifstream fin("milk2.in");
    ofstream fout("milk2.out");
    int n;

    fin>>n;
    for(int i=0;i<2*n;i+=2){
        int b1,e1;

        fin>>b1>>e1;
        t[i].first = b1;
        t[i].second = true;
        t[i+1].first = e1;
        t[i+1].second = false;
    }
    qsort(t,2*n,sizeof(t[0]),cmp);
//    for(int i=0;i<2*n;i++){
//        fout<<t[i].first<<"-"<<t[i].second<<endl;
//    }
    //stack<int> st;
    int st = 0;
    int maxt = 0, maxi = 0;
    //棧 壓入b
    int buttom = 0;
    int lastend = t[0].first;
    for(int i=0;i<2*n;i++){
        if(i != 2*n-1 && t[i].first == t[i+1].first && t[i].second != t[i+1].second){
            i++;
            continue;
        }
        if(t[i].second == true){
            if(st == 0){
                if(t[i].first - lastend > maxi){
                    maxi = t[i].first - lastend;
                }
                buttom = t[i].first;
            }
            //st.push(t[i].first);
            st++;
        }else{
            //st.pop();
            st--;
            if(st == 0){
                cout<<"end-buttom  "<<t[i].first<<" - "<<buttom<<" = "<<t[i].first - buttom<<endl;
                if(t[i].first - buttom > maxt){
                    maxt = t[i].first - buttom;
                }
                lastend = t[i].first;
            }
        }
        cout<<"t[i] "<<t[i].first<<"  "<<t[i].second<<endl;
        cout<<"st "<<st<<endl;
    }
    cout<<maxt<<" "<<maxi<<endl;
    fout<<maxt<<" "<<maxi<<endl;
    return 0;
}



發佈了26 篇原創文章 · 獲贊 6 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章