题解 | #变化的飞行棋#
变化的飞行棋
https://ac.nowcoder.com/acm/contest/37895/D
暴力的建出循环次的飞行器图,长度,
之后考虑每个点处能一次跳到的位置共有个,即筛子数为直接走到 处后选择不走,或者
走到处后继续选择走步,即一步内共种走法: 和 ,考虑边数上限为条,时间复杂度还算可以,所以直接从起点跑即可,但是注意的是不能真的把图建出来,我建图跑了一发MLE,因为每个点的边都是固定的条直接过程中扩展就行了。
总时间复杂度。
const int N = 5e6 + 10, M = 1e4 + 10;
int a[N];
int dis[N];
int b[M];
int n, m;
void bfs()
{
queue<int> que;
que.push(1);
dis[1] = 0;
while(!que.empty())
{
int u = que.front(); que.pop();
for(int i = 1;i <= 6;i ++)
{
int v = min(n * m + 1, u + i);
if(dis[v] > dis[u] + 1)
{
dis[v] = dis[u] + 1;
que.push(v);
}
v = min(n * m + 1, u + i + a[u + i]);
if(dis[v] > dis[u] + 1)
{
dis[v] = dis[u] + 1;
que.push(v);
}
}
}
}
void solve(int Case)
{
n = read(), m = read();
for(int i = 1;i <= n;i ++) a[i] = read();
for(int i = 1;i <= n;i ++) b[i] = read();
for(int i = n + 1;i <= n * m;i ++)
a[i] = a[i - n] + b[(i - 1) % n + 1];
for(int i = 1;i <= n * m + 1;i ++) dis[i] = inf;
bfs();
printf("%lld\n", dis[n * m + 1]);
}
signed main()
{
// ios;
int t = 1;// t = read();
for(int i = 1;i <= t;i ++) solve(i);
return 0;
}