您的位置:首页 > 编程语言 > C语言/C++

C++_USACO_Milking Cows

2013-07-20 15:53 381 查看
/*
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,表示这段时间没有人挤牛奶。避免了开始时刻的排序。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: