1 条题解

  • 1
    @ 2025-11-26 16:18:56

    如果k>=3 答案一定为0

    证明如下: 任选两个数x,y (y >= x),进行一次操作,得到|x-y|,再将|x-y| 和y进行一次操作,得到|x|,然后|x|和x进行操作,答案为0.

    • @ 2025-11-26 16:21:09

      然后当k = 1时,我们容易想到将数组排序,然后找最小的相邻差值,然后和最小数a[1]进行比较。

    • @ 2025-11-26 16:53:08

      当k==2,我们考虑ans存在的情况,

      (1):进行第一次操作,找最小的相邻最小值,然后和a[1]比较进行第二次操作,更新最大ans

      (2):还有一种可能答案可能并不在相邻数中去最值,比如

      数组a[]:1 4 6 10

      差值:3 2 4

      最优解应该是 |10-4| = 6, |6-6| = 0;

      n的范围可以让我们以O(n^2)的时间复杂度去模拟,我们可以找出来每两个数之间的差值

      然后排序,对于a[i],每次用log的时间复杂度去在差值数组中查找最近的c_i,然后更新ans

      最后ans取这两种情况最小的即可

    • @ 2025-11-26 16:54:59
      #define rep(i,l,r) for(int i = l; i <= r; i++)
      #define int long long
      #define pb push_back
      #define endl '\n'
      using namespace std;
      const int inf = 1e18+5;
      void solve() {
          int n,k; cin >> n >> k;
          vector<int> a(n+1);
          rep(i,1,n) cin >> a[i];
          if(k >= 3){
              cout << 0 << endl;
              return;
          }
          sort(a.begin() + 1,a.end());
          if(k == 1){
              int mn = a[1];
              rep(i,2,n) mn = min(mn,a[i] - a[i-1]);
              cout << mn << endl;
          }else{
              int mn = inf;
              rep(i,2,n) mn = min(mn,a[i] - a[i-1]);
              int ans = min(abs(mn - a[1]),min(mn,a[1]));
              vector<int> c;
              for(int i = 1; i <= n; i++){
                  for(int j = i + 1; j <= n; j++){
                      c.pb(abs(a[i]- a[j]));
                  }
              }
              sort(c.begin(),c.end());
              int len = c.size();
              for(int i = 1; i <= n; i++){
                  int l = 0,r = len - 1;
                  while(l < r){
                      int mid = (l + r) / 2;
                      if(c[mid] >= a[i]){
                          r = mid;
                      }else{
                          l = mid + 1;
                      }
                  }
                  ans = min(ans,abs(c[l] - a[i]));
                  l = 0,r = len - 1;
                  while(l < r){
                      int mid = (l + r + 1) / 2;
                      if(c[mid] <= a[i]){
                          l = mid;
                      }else{
                          r = mid - 1;
                      }
                  }
                  ans = min(ans,abs(a[i] - c[l]));
              }
              cout << ans << endl;
          }
      }
      
    • @ 2025-11-26 16:56:35

      考察 贪心,模拟,时间复杂度的判断。

      首先最重要的是判断k的情况,不然很难做。

      然后特判k=1,和k=2。

      分情况讨论即可。

  • 1

信息

ID
1217
时间
1000ms
内存
256MiB
难度
8
标签
(无)
递交数
33
已通过
5
上传者