2 条题解

  • 0
    @ 2025-10-13 21:01:48

    ****雨露霜雪,雪霜露雨

    道理白秋月学长已经说明白,直接上代码

    参考代码(python)

    from sys import stdin,setrecursionlimit
    from math import inf,ceil,sqrt
    from collections import Counter,deque
    
    for _ in range(int(stdin.readline())):
        n=int(stdin.readline())
        a=[int(_) for _ in stdin.readline().split()]
        v=['0' for _ in range(n)]
        mn=a[0]
        mx=a[n-1]
        v[0]='1'
        v[n-1]='1'
        for i in range(n):
            if a[i]<=mn:
                mn=a[i]
                v[i]='1'
            if a[n-i-1]>=mx:
                mx=a[n-i-1]
                v[n-i-1]='1'
        print(''.join(v))
    
    
    • 0
      @ 2025-10-13 20:48:46

      我们来逐步说明:为什么一个元素 ai​ 能成为最终整个数组的值,当且仅当它是某个前缀的最小值,或是某个后缀的最大值。


      情况一:数组长度为 2

      如果数组只有两个元素,比如 [x,y],那么:

      • 使用一次前缀操作(选择整个数组),可以将数组变为 [min(x,y),min(x,y)]
      • 使用一次后缀操作(选择整个数组),可以将数组变为 [max(x,y),max(x,y)]

      因此,在两元素的情况下,最终数组只能变为两个数中的较小值或较大值,无法变为一个既非最小也非最大的值。


      情况二:ai​ 是前缀最小值或后缀最大值

      • 如果 aia_i​ 是从位置 1 到 i 的最小值,我们可以先对前 i 个元素执行前缀操作,使前 i 个数都变为 aia_i​。
        • 此时 aia_i​ 出现在数组开头。
        • 接下来可以通过一系列后缀操作,逐步将后面的元素也变为 aia_i​,最终使整个数组相同。
      • 类似地,如果 aia_i​ 是从位置 i 到末尾的最大值,我们可以先对从 i 开始的后缀执行后缀操作,使该后缀都变为 aia_i​。
        • 然后通过前缀操作逐步向前扩展,最终也能使整个数组变为 aia_i​。

      因此,只要 aia_i​ 是某个前缀的最小值或某个后缀的最大值,就存在一种操作序列,使整个数组最终都变为 aia_i​。


      情况三:aia_i​ 既不是前缀最小值,也不是后缀最大值

      假设 aia_i​ 不满足上述任一条件。

      我们记:

      • apa_p​ 为前缀 a1a_1​ 到 aia_i​ 中的最小值。由于 aia_i​ 不是前缀最小值,必有 apa_p​<aia_i​。
      • asa_s​ 为后缀 aia_i​ 到 ana_n​ 中的最大值。由于 aia_i​ 不是后缀最大值,必有 asa_s​>aia_i​。

      因此有:apa_p​<aia_i​<asa_s​,且 p<i<s。

      现在考虑任何一种操作序列。为了最终使整个数组变为 aia_i​,我们必须在某个时刻将 apa_p​ 和 asa_s​ 都变为 aia_i​,或者先改变其他位置,使得 aia_i​ 能逐步传播出去。

      但问题在于:

      • 如果我们尝试通过前缀操作改变包含 apa_p​ 的区间,由于 apa_p​ 是前缀最小值,该操作会将区间内所有元素变为 apa_p​ 或更小的值,而 aia_i​>apa_p​,因此 ai​ 也会被更新为更小的值,无法保留。
      • 如果我们尝试通过后缀操作改变包含 asa_s​ 的区间,由于 asa_s​ 是后缀最大值,该操作会将区间内所有元素变为 asa_s​ 或更大的值,而 aia_i​<asa_s​,因此 aia_i​ 也会被更新为更大的值。
      • 如果我们尝试通过后缀操作包含 apa_p​,那么该后缀必然包含 aia_i​,但由于 asa_s​>aia_i​,aia_i​ 不是该后缀的最大值,因此 aia_i​ 会被更新为更大的值。
      • 类似地,如果通过前缀操作包含 asa_s​,那么 aia_i​ 也会被包含,但由于 apa_p​<aia_i​,aia_i​ 不是最小值,也会被更新为更小的值。

      换句话说,任何能够影响 apa_p​ 或 asa_s​ 的操作,只要覆盖到 aia_i​,就会因为 aia_i​ 既不是最小也不是最大,而被更新为其他值

      因此,在所有可能的操作序列中,aia_i​ 很难保持不变,也无法逐步扩展到整个数组。


      最终结论

      综上所述,只有当 aia_i​ 是某个前缀的最小值或某个后缀的最大值时,才有可能通过一系列操作使整个数组变为 aia_i​。

      对于每个位置 i,我们只需检查:

      • aia_i​ 是否等于 a1a_1​ 到 aia_i​ 的最小值,或
      • aia_i​ 是否等于 aia_i​ 到 ana_n​ 的最大值。

      满足其一,则输出 1,否则输出 0

      #include <stdio.h>
      
      #define MAXN 200005
      #define MIN(a, b) ((a) < (b) ? (a) : (b))//相当于最小值函数
      #define MAX(a, b) ((a) > (b) ? (a) : (b))//相当于最大值函数
      //利用三目运算符实现快速判断
      int pre[MAXN], suf[MAXN], a[MAXN];
      
      int main() {
          int t;
          scanf("%d", &t);
          while (t--) {
              int n;
              scanf("%d", &n);
              pre[0] = 1000000000;
              suf[n + 1] = -1;
              for (int i = 1; i <= n; i++) {
                  scanf("%d", &a[i]);
                  pre[i] = MIN(pre[i - 1], a[i]);
              }
              for (int i = n; i >= 1; i--) {
                  suf[i] = MAX(suf[i + 1], a[i]);
              }
              for (int i = 1; i <= n; i++) {
                  if (a[i] == pre[i] || a[i] == suf[i]) {
                      printf("1");
                  } else {
                      printf("0");
                  }
              }
              printf("\n");
          }
          return 0;
      }
      
      • 1

      [2025 实验室一面] 雨露霜雪,雪霜露雨

      信息

      ID
      1103
      时间
      1000ms
      内存
      256MiB
      难度
      7
      标签
      递交数
      30
      已通过
      8
      上传者