Codeforces B. Frog Traveler
作者:
我不会取名字啊啊
,
2022-04-13 20:59:19
,
所有人可见
,
阅读 227
题目链接
我焯,好难...思维跟不上了...
分析一下:
观察到一个现象:
假设n能跳到j,则有两种情况,一种是直接就跳到j,另一种是跳到其它点然后滑跳...再到j
很显然,第一次跳到的时候就是最小操作了。
即:每个点第一次跳跃能到的点一定是最优的,
比如第一次跳跃时[n-a[n],n-1]这个区间都被跳到,之后跳到的步骤肯定没有第一次跳的优秀。
因此我们后面在跳的时候,如果跳到n-a[n]后面的点就都不用考虑了;
有了这个性质的话,我们直接模拟的话是线性的了。
所以我们直接bfs模拟就行,同时记录路径
好神奇的题目,好奇怪的思维...
参考题解:
https://blog.csdn.net/Alanrookie/article/details/120977824?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164985168816782246465538%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=164985168816782246465538&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-1-120977824.142^v7^pc_search_result_cache,157^v4^control&utm_term=B.+Frog+Traveler&spm=1018.2226.3001.4449
https://blog.csdn.net/weixin_45784984/article/details/121364442?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164985168816782246465538%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=164985168816782246465538&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-4-121364442.142^v7^pc_search_result_cache,157^v4^control&utm_term=B.+Frog+Traveler&spm=1018.2226.3001.4449
int a[maxn];
int b[maxn];
int pre[maxn]; //10跳到6滑倒9,则记录pre[9] = 10;
int d[maxn]; //10跳到6滑倒9,则记录d[9] = 6;
int vis[maxn]; //标记这个点是否被走过
int n;
vector<int> ans;
void bfs()
{
for(int i=0;i<maxn;i++)
{
vis[i] = 0;
pre[i] = d[i] = -1;
}
queue<int> q;
q.push(n);
vis[n] = 1;
int mini = n; //当前最远跳到哪
while(q.size())
{
int now = q.front();
q.pop();
if(now - a[now] >= mini) continue; //不能往上跳
for(int i=now-a[now];i<mini;i++) //枚举能跳的这一段
{
int ne = i + b[i]; //下滑
if(vis[ne]) continue; //之前走过
vis[ne] = 1;
pre[ne] = now;
d[ne] = i;
q.push(ne);
}
mini = now - a[now]; //更新最大能跳到的点
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) cin>>b[i];
bfs();
//下面输出
if(!vis[0])
{
cout<<-1<<endl;
return 0;
}
int x = 0;
while(pre[x] != -1)
{
ans.push_back(d[x]);
x = pre[x];
}
reverse(ans.begin(),ans.end());
cout<<ans.size()<<endl;
for(auto x : ans) cout<<x<<' ';
cout<<endl;
return 0;
}