我是受第一个题解的启发,然后写的, 但是我发现我误区了一个点,导致第二个测试点WA,ps: 我看了历史提交,好多人也是90分错第二个测试点
这是我第二个测试点错误90分的check函数:
bool check(int x) {
int t=0;
for(int i=1;i<=n;i++) {
int l=range[i].first, r=range[i].second;
if(t<l){
if(l-t<=x) t=r-(l-t);
}
else if(t==l) t=r;
else if(t>l) t=max(t,r+min(x,t-l));
}
return t>=20000;
}
这里我都是只对每一个点进行了一边查看,当第一个种情况(t<l&&l-t<=x)时我直接跳过了, 但这是错误的, 因为这个区间不是废物的, 它只是对于这一次的t来说是不可以更新的, 但后续对其他区间进行更新时,t的改变可能会导致这个区间的变成可行的(可以更新t 的)
这是正确check()函数
/*
为什么当 查一次不行,有些放过的区间,为什么后面还有遍历一边,
因为:
1. 你竟然贪心,就要贪的彻底,对每个区间都要尽可能的用
对于哪些t<l 但l-t>x的区间,虽然当前的情况(当前t)下他们动不了, 但不能就不用他们了, 需要在后续的每次中再查一次,因为 t有可能被其他区间 变动了呀,他们就有可能能了呀!!!
2. 谁告诉你一定要按照我这个给定的区间顺序来移动的,只要移了就OK(先入为主了)
3. 直到什么时候停下来??? { 他们这些都更新不了,已经没有t可以变动的了(但他们还是t<l 但l-t>x) || 所有的区间都更新完了 } 此时才停下来
*/
bool check(int x) {
memset(st,0,sizeof st);
int t=0, cnt=0; // 当cnt==n说明整个区间都更新完了
while(1) {
bool flag=false;
for(int i=1;i<=n;i++) {
if(st[i]) continue;
st[i]=1,cnt++;
int l=range[i].first, r=range[i].second;
if(t<l){
if(l-t<=x) t=r-(l-t),flag=true;
else st[i]=0,cnt--; //这个属于"他们"不能算,得后续再看看
}
else if(t==l) t=r,flag=true;
else if(t>l) t=max(t,r+min(x,t-l)),flag=true;
}
if(flag==false || cnt==n) break;
}
return t>=20000;
}
99.9999999=0
100=1