CF round 908 div1A题

文章讲述了CFround908div1A题中的解决方案,重点在于理解如何通过指针移动代替数组移动,避免因步数过大导致整数溢出。作者分享了解题关键部分的代码,并提到队长处理边界情况的方法,确保代码健壮性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CF round 908 div1A题

题目

题目

输入输出范例:
input

6
5 3
4 3 3 2 3
3 100
7 2 1
5 5
6 1 1 1 1
1 1000000000
1
8 48
9 10 11 12 13 14 15 8
2 1
1 42

output

Yes
Yes
No
Yes
Yes
No

输入输出范例释义

释义

解释

主要思维
主要的难点其实不在于数组左右移动上面,主要是能够发现,每一次操作找到ax=x的那一个点,都是要把数组往左移动x下,那么原来的ax必然会移动到an的位置,所以每一次反向思维观察bn就可以看出来这一步的b数列能否由a数列得到a_{x}=x的那一个点,都是要把数组往左移动x下,那么原来的a_{x}必然会移动到a_{n}的位置,所以每一次反向思维观察b_{n}就可以看出来这一步的b数列能否由a数列得到 ax=x的那一个点,都是要把数组往左移动x下,那么原来的ax必然会移动到an的位置,所以每一次反向思维观察bn就可以看出来这一步的b数列能否由a数列得到
然后在数组左右移动这类问题中,都会选择以指针移动来代替数组移动,而在指针移动的时候要注意不要因为移动的步数太多而导致超出int范围或者在访问数组元素时候超出数组范围。
这个问题在后面代码会详细解释,在这道题就可以用到。

代码

完整代码展示
这个是我们队长的代码

#include <bits/stdc++.h>
using namespace std;

#define MAXN 205

inline string solve(int _) {

    int n, k; cin >> n >> k;
    vector<int > a(n);

    for (int i=0;i<n;++i) cin >> a[i];

    int pos = n - 1;
    for (int i=1;i<=min(n,k);++i) {
        if ( a[pos] > n ) return "No";
        pos = (( pos - a[pos] ) % n + n) % n;
    }

    return "Yes";
}


int main() {

    ios::sync_with_stdio(0);
    
    int T; cin >> T;
    while (T -- ) cout << solve(T) << "\n";
    return 0;
}

片段化解析

    int pos = n - 1;
    for (int i=1;i<=min(n,k);++i) {
        if ( a[pos] > n ) return "No";
        pos = (( pos - a[pos] ) % n + n) % n;
    }
    ```
   这一部分是关键部分,当初我写的时候感觉只用这样就够了
   int pos = n - 1;
for (int i=1;i<=min(n,k);++i) {
    if ( a[pos] > n ) return "No";
    pos = ( pos - a[pos]  + n) % n;
}
```

后来cmx提醒了我,这么搞遇到一些题容易出现括号里的数值超出Int范围的情况,所以队长这么做一定有他的道理,上面的才是万金油版数组移动转指针移动。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值