B2.Koa and the Beach (Hard Version)
题目链接:https://vjudge.net/problem/CodeForces-1384B2
官方题解:https://codeforces.com/blog/entry/80562
解题思路:真的神仙Div2(太菜了QAQ),我们首先找到无论什么时候都是安全的地方(满足di+k<=l),同时,起始点和终点也都是安全的地方(i==0 || i==n+1),我们可以在安全点等任意长的时间。如果我们最终可以到达终点,则我们一定可以从一个安全点到另一个安全点。因此我们考虑的是两个安全点之间的策略
我们每次从安全点出发,贪心选择潮汐下降的时候,如果在潮汐上升的时候出发,一些不安全点可能就没有办法过去,我们肯定会在下次潮汐达到k的时候到达下一个安全点。具体解释看代码
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=2e5+10; vector<int>q[10000+10]; inline ll read(){ ll s=0,w=1;char ch = getchar(); while(ch<48 || ch>57) { if(ch=='-') w=-1;ch = getchar(); } while(ch>=48&&ch<=57) s = (s<<1) + (s<<3) + (ch^48),ch=getchar(); return s*w; } int n,k,l; int main() { int t; t=read(); while(t--) { int n,k,l; cin>>n>>k>>l; vector<int>dep(n+1),q; q.push_back(0); for(int i=1;i<=n;i++) { cin>>dep[i]; if(dep[i]+k<=l) q.push_back(i); //统计安全点 } bool ok=true; q.push_back(n+1); for(int i=1;i<q.size();i++) { int tide=k;bool down=true; //从潮汐下降的时候开始出发 for(int j=q[i-1]+1;j<q[i];j++)//在两个安全点之间 { tide+=down?-1:1; //考虑tide要+1还是-1 if(down) tide-=max(0,dep[j]+tide-l); //如果我们需要到达下一个点,tide一定要小于等于某个值,作用就是求这个值 if(tide<0||dep[j]+tide>l) {ok=false;break;} //如果tide<0 即为dep>l或者dep+tide大于l,则没有办法求出最后的答案 if(tide==0) down=false; } if(!ok) break; } if(ok) cout<<"Yes "; else cout<<"No "; } }