诈骗系列之-CF2059B

闲话

本文同步发布在 cnblogs


诈骗好题,因数组开小吃掉两发罚时。

分两种情况:

\(n = k\),比较简单,暴力模拟即可。

\(n \not = k\),此时思考一个问题:

如何使成本最小?

答案显而易见,设 \(a_i = x\),则使 \(a_{i + 1} \not = x + 1\) 即可。

于是我们得到这样的代码:

#include<bits/stdc++.h>
using namespace std;
int t, n, k, a[200005];
int main(){
     ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
     cin >> t;
     while(t --){
          cin >> n >> k;
          for(int i = 1; i <= n; i ++){
               cin >> a[i];
          }
          if(n == k){
               int flag = 1, maxn = 0;
               for(int i = 2; i <= n; i += 2){
                    maxn = max(maxn, a[i]);
                    if(a[i] != i / 2){
                         cout << i / 2 << "\n";
                         flag = 0; break;
                    }
               }
               if(flag) cout << maxn + 1 << "\n";
          }
          else{
               int ans = 2e9;
               for(int i = 1; i < n; i ++){
                    if(a[i + 1] != a[i] + 1){
                         ans = i + 1;
                         break;
                    }
               }
               cout << ans << "\n";
          }
     }
     return 0;
}

毫无疑问,这是错的。

思考错在哪里,刚才我们只是找了中间部分是否会断,但并没有提到起始位置。

如果我们能使它刚开始就不符合要求,答案就是最小的 \(1\)。由于后面还需要分块,简单进行数学运算可得,我们只能在前面 \(n - k + 2\) 处查找 \(a_i \not = 1\) 的数,注意 \(i \not = 1\),因为 \(1\) 只能在奇数块。

正确代码如下:

#include<bits/stdc++.h>
using namespace std;
int t, n, k, a[200005];
int main(){
     ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
     cin >> t;
     while(t --){
          cin >> n >> k;
          for(int i = 1; i <= n; i ++){
               cin >> a[i];
          }
          if(n == k){
               int flag = 1, maxn = 0;
               for(int i = 2; i <= n; i += 2){
                    maxn = max(maxn, a[i]);
                    if(a[i] != i / 2){
                         cout << i / 2 << "\n";
                         flag = 0; break;
                    }
               }
               if(flag) cout << maxn + 1 << "\n";
          }
          else{
               int ans = 2e9;
               for(int i = 1; i < n; i ++){
                    if(a[i + 1] != a[i] + 1){
                         ans = i + 1;
                         break;
                    }
               }
               for(int i = 2; i <= n - k + 2; i ++){
                    if(a[i] != 1){
                         ans = 1;
                         break;
                    }
               }
               cout << ans << "\n";
          }
     }
     return 0;
}

posted on 2025-02-03 00:51  zhangzirui66  阅读(24)  评论(0)    收藏  举报

导航