【题目描述】 小H发明了一个跳格子的游戏,地板上画了排成一排的n个格子,并以1…n按顺序编号。他规定第i个格子可以跳到第1到第i-1个格子中的任一个,且每个格子有一个不一定相同的反方向的跳跃度a[i],代表第i个格还可以跳到第i+1到i+a[i]个格子中的任一个。现在小H指定其中的一个格子,问从这个格子开始,最少需要连续踩几次格子(起始的格子也算在内),可以跳到第n个格子的后方,即若第k个格子有k+a[i]>n,那么从第k个格子就可以跳到第n个格子的后方。
【输入格式】 输入的第1行包含两个正整数n,m,为格子的数目以及询问的次数。第2行包含n个正整数,第i个正整数为a[i],即第i个格子向反方向最大跳跃的长度。第3行包含了m个正整数,为询问从哪一个格子开始,最少要几次跳到第n个格子的后方。 数字之间用空格隔开。
【输出格式】 输出包含1行,这一行有m个正整数,对于每一个询问,输出最少需要踩的格子数,数字之间用空格隔开。 行末换行且没有多余的空格。
【样例输入#1】 5 5 2 4 1 1 1 1 2 3 4 5
【样例输出#1】 2 1 2 2 1
【样例解释#1】 若从第1个格子开始则跳到第2个格子,接着就可以跳到第n个格子的后方。若从第3个格子开始则同样跳到第2个格子。若从第4个格子开始可以跳到第2个格子或最后一个格子,接着跳出第n个格子,答案同样为2。
【数据规模】 对于20%的数据,有n≤10;
对于40%的数据,有n≤100,m≤10;
对于60%的数据,有n≤1000,a[i]≤1000,m≤500;
对于100%的数据,有n≤100000,a[i]≤n,m≤50000
源码:
#include<bits/stdc++.h>
using namespace std;
int n, m, x, y, vis[100005];
queue <int> q;
struct t
{
int a, b, c;
}l[1000005];
int main()
{
freopen("lattice.in","r",stdin);
freopen("lattice.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; ++i)
{
cin >> x;
l[i].a = i, l[i].b = x + i;
if (l[i].b > n)
{
l[i].c = 1;
vis[i] = 1;
q.push(i);
}
}
while(!q.empty())
{
x = q.front();
y = l[x].c;
for (int i = 1; i <= n; ++i)
{
if (vis[i] == 1) continue;
if (l[i].b >= x && l[i].b <= l[x].b && vis[i] == 0)
{
l[i].c = y + 1;
vis[i] = 1;
q.push(i);
}
}
q.pop();
}
for (int i = 1; i <= m; ++i)
{
cin >> x;
cout << l[x].c << " ";
}
return 0;
}