Problem Description
输入T代表有T组测试数据,输入n代表有n个商城分别是1-n。每个商城都有一个值num,在这个商城可以直接跳到i-num的商城 or i+num的商城。问你每个商城到n这个商城最少需要跳几次,如果不能到输出-1。
思路:
看到这个题第一反应想到的是记忆化搜索,因为求的一个商城的最少跳跃距离,就可以用数组保存起来,下次在访问到直接返回值就可以了。也许是个人水平问题,样例过了,没能AC。百度看了下别人做法,求n到各个点的最短距离,不就是反向建边,跑bfs而已。
#include<bits/stdc++.h>
using namespace std;
struct node
{
int to, next;
};
#define nn 112345
#define inf 0x3f3f3f3f
node Map[5*nn];
int head[nn], dist[nn], cnt;
void add(int u, int v)
{
Map[cnt].to = v;
Map[cnt].next = head[u];
head[u] = cnt++;
}
void bfs(int u)
{
memset(dist, inf, sizeof(dist));
dist[u] = 0;
queue<int> q;
q.push(u);
while(!q.empty())
{
u = q.front(), q.pop();
for(int i = head[u]; ~i; i = Map[i].next)
{
int to = Map[i].to;
if(dist[to] > dist[u] + 1)
{
dist[to] = dist[u] + 1;
q.push(to);
}
}
}
}
int main()
{
freopen("jumping.in", "r", stdin);//因为这个写在了while()循环里面错了好久。。
int T, n, num;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
memset(head, -1, sizeof(head));
cnt = 0;
for(int i = 1; i <= n; i++)
{
scanf("%d", &num);
if(i-num >= 1) add(i-num, i);//反向建边
if(i+num <= n) add(i+num, i);
}
bfs(n);//求n到各个点的最短路
for(int i = 1; i <= n; i++)
{
if(dist[i] != inf) printf("%d\n", dist[i]);
else printf("-1\n");
}
}
}