首页 > 其他分享 >ATCoder [ABC167D] Teleporter

ATCoder [ABC167D] Teleporter

时间:2023-06-10 09:44:32浏览次数:46  
标签:ATCoder Teleporter int ABC167D cin vis vector 序列 操作

# 题目解析

这段代码的目标是处理一个含有 $n$ 个元素的整数序列,根据一定的规则,重复操作 $k$ 次后,确定操作结束时位于序列哪个位置。

## 解题思路

1. **读取输入**:首先,我们读取输入的整数 $n$ 和 $k$ ,以及整数序列 `a`。我们需要对序列的每个元素减一,以适应从 0 开始的索引。

cin >> n >> k;
vector<int> a(n);
for(int i = 0; i < n; i++) 
{
    cin >> a[i];
    a[i]--;
}

2. **初始化变量**:我们使用一个变量 `t` 来记录当前位置,以及一个数组 `vis` 来记录每个位置第一次被访问的次序。

vector<int> vis(n, -1);
int t = 0;
vis[t] = 0;

3. **进行操作**:我们按照规则进行操作。如果在某次操作后,当前位置已经被访问过,则表示找到了循环。此时,我们可以计算出循环的周期 `p`,以及还需进行的操作次数 `r`,然后快速进行 `r` 次操作。如果在进行 $k$ 次操作后还没有找到循环,则直接输出当前位置。

for(int i = 1; i <= k; i++)
{
    t = a[t];
    if(vis[t] != -1)
    {
        int p = i - vis[t];
        int r = (k - i) % p;
        for(int j = 0; j < r; j++) 
            t = a[t];
        break;
    }
    vis[t] = i;
}

4. **输出结果**:完成所有操作后,输出最终的位置,注意输出时要加一,以适应从 1 开始的索引。

cout << t + 1;

 

 

总的来说,这段代码通过模拟操作的过程,并在发现循环时利用循环的性质进行优化,找出重复操作 $k$ 次后位于序列的哪个位置。

# 完整代码:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    long long n, k;
    cin >> n >> k;
    vector<int> a(n);
    for(int i = 0; i < n; i++) 
    {
        cin >> a[i];
        a[i]--;
    }
    vector<int> vis(n, -1);
    int t = 0;
    vis[t] = 0;
    for(int i = 1; i <= k; i++)
    {
        t = a[t];
        if(vis[t] != -1)
        {
            int p = i - vis[t];
            int r = (k - i) % p;
            for(int j = 0; j < r; j++) 
                t = a[t];
            break;
        }
        vis[t] = i;
    }
    cout << t + 1;
    return 0;
}

 

标签:ATCoder,Teleporter,int,ABC167D,cin,vis,vector,序列,操作
From: https://www.cnblogs.com/YuTianQwQ/p/17470787.html

相关文章

  • AtCoder Beginner Contest 290 Ex Bow Meow Optimization
    洛谷传送门AtCoder传送门考虑观察答案形态。当\(n,m\)均为偶数时,前一半位置有\(\frac{n}{2}\)个是狗,\(\frac{m}{2}\)个是猫。并且前半段从前往后和后半段从后往前都是按权值从小到大放。调整法证明即可。当\(n\)或\(m\)为奇数时,把\(a_i\)或\(b_i\)最大的放中间......
  • Atcoder ARC100D Equal Cut
    发现是\(3\)个断点且数据范围的\(n\le2\times10^5\),根据2022CSP-SA留下的心理阴影不难想到可以枚举中间的那个点的同时移动左右两个端点。考虑如何移动,已知现在在枚举中间的断点\(i\),则现在被分为了两部分\(1\simi\)和\(i\simn\),因为要使极差最小,那就先可以让每一......
  • Atcoder ABC221G Jumping sequence
    发现这个\((x,y)\)对应的是曼哈顿距离不太好求,那直接逆时针旋转\(45\)度(其实应该还要伸长\(\sqrt{2}\)倍,但是可以当做\(d_i\)也伸长\(\sqrt{2}\)倍不用去管)转化成切比雪夫距离\((x-y,x+y)\)。同时对应的\(4\)个方向在旋转后对应的方向也得到了改变:\(U(-d,d),......
  • AtCoder Beginner Contest 240 D
    D-StrangeBallstag:栈模拟发现自己隔了快半年再做此题看错相同数字的球消失的条件,不是\(k\geq2\)而是\(k=a_i\)电子竞技不需要视力题意:当球\(a_i(1\leqi\leqN)\)有\(a_i\)个一起出现时,这\(a_i\)个球就会消失,问每次放一个球进去,放进去后还剩多少个球?用个......
  • AtCoder Beginner Contest 150 E Change a Little Bit
    洛谷传送门AtCoder传送门令\(S_i\getsS_i\oplusT_i\),那么代价中\(D\)变成\(S_i=1\)的\(i\)数量。转化为对所有\(f(S)\)求和,最后答案乘上\(2^n\)。考虑贪心地求\(f(S)\)。肯定是先选择小的\(C_i\),把\(S_i\)变成\(0\)。正确性显然。下面把\(C_i\)从大到......
  • AtCoder Beginner Contest 281 Ex Alchemy
    洛谷传送门AtCoder传送门考虑设\(f_i\)为\(i\)的答案,那么:\[f_i=[x_i](1+x)^A\prod\limits_{j=2}^{i-1}(1+f_jx)\]这个东西其实是可以分治FFT的。具体地,设分治区间为\([l,r]\),要求一个\(r-l+1\)次多项式\(\prod\limits_{i=l}^r(1+f_ix)\)。......
  • AtCoder Beginner Contest 287 G Balance Update Query
    洛谷传送门AtCoder传送门线段树上二分入门题。考虑一个贪心:每次询问按\(a_i\)从大到小选。正确性显然。考虑动态开点线段树,每个结点\(a_i\in[l,r]\)存\(\sum\limits_{a_i\in[l,r]}b_i\)和\(\sum\limits_{a_i\in[l,r]}a_ib_i\)。线段树上二分找到第一个\(......
  • AtCoder Beginner Contest 258 G Grid Card Game
    洛谷传送门AtCoder传送门记\(b_i=\sum\limits_{j=1}^ma_{i,j},c_j=\sum\limits_{i=1}^na_{i,j}\)。首先考虑这样一个事情,就是对于\(b_i\le0\)的行有没有可能被选。如果选了它:如果没有选任何列,选这一行肯定不优;如果选了若干列,根据题目的要求,这若干列与这......
  • AtCoder Regular Contest 145
    A答案为Yes当且仅当$s[1]\ne$A或$s[n]\ne$B。注意判\(n=2\)。BAlice可胜利当且仅当\(n\gea\wedgen\bmoda<b\)。C显然我们应该凑\((2i-1,2i)\)。那么我们用一个括号序列描述\(2i-1\)和\(2i\),不难发现答案为\[\frac{\binom{2n}{n}}{n+1}......
  • AtCoder Beginner Contest 304 ABCDE
    AtCoderBeginnerContest304感觉手速场,后\(80\)分钟纯纯坐牢,A-FirstPlayer一些人坐成一个环,从年龄最小开始输出名字constintN=2e5+10;intn;strings[N];inta[N];voidsolve(){intm=1e9+2,p=1;cin>>n;for(inti=1;i<=n;......