2 条题解

  • 0
    @ 2025-10-8 17:09:05

    /* 位运算+贪心

    • 一开始设两个变量,一个二进制全部是1,一个全部是0,然后让他们经过所有的运算,接着每一位贪心,如果某一位原来是0,之后是1的话必须标1这一位.
    • 原来是1之后是1的话就判断一下是否符合条件 (是否会比m大),符合就把这一位标1, 不符标0; 原来是0或1,之后是0的话就直接标0.
    • 为什么可以这么贪? 因为在位运算里每一位都是独立的不受其他位影响。如果一个位是1经过一些位运算之后是1,那么不管其他位是什么,只要那个位是1,经过相同运算就还是1 */
    #include <bits/stdc++.h>
    using namespace std;
     
    int main()
    {
        char st[10];int n, m;scanf("%d%d", &n, &m );
        int h0=0;                   //全设0
        int h1=(1<<30)-1+(1<<30);   //全设1, (10^9=111011100110101100101000000000,有30位) (注:此处可能为笔误,实际应为(1<<30)-1表示30个1,或其他逻辑)
        for(int i=1,x; i<=n; i++)
        {
            scanf("%s%d", st, &x );
            if(st[0]=='A' )       h1 &= x, h0 &= x;
            else if( st[0]=='O' ) h1 |= x, h0 |= x;
            else                  h1 ^= x, h0 ^= x;
        }
        int ans=0, x=0;
        for(int i=30;i>=1;i--) 
        {
            if( h0 & (1<<(i-1)) ) ans += (1<<(i-1)); //如果原来是0之后是1, 就选这个, 让数字尽量小
            else
            {
                if ( ( h1 & (1<<(i-1)) ) && ( x + (1 << (i-1)) ) <= m ) ans += (1<<(i-1)), x += (1 << (i-1)); //原来是1之后还是1, 判断是否会比m大
            }
        }
        printf("%d\n", ans);
        return 0;
    }
    
    • 0
      @ 2025-10-8 17:08:52
      /* 位运算+贪心
       * 一开始设两个变量,一个二进制全部是1, 一个全部是0, 然后让他们经过所有的运算,
       * 接着每一位贪心, 如果某一位原来是0, 之后是1的话必须标1这一位.
       * 原来是1之后是1的话就判断一下是否符合条件 (是否会比m大),
       * 符合就把这意味标1,不符标0; 原来是0或1, 之后是0的话就直接标0.
       * 为什么可以这么贪? 因为在位运算里每一位都是独立的不受其他位影响。
       * 如果一个位是1经过一些位运算之后是1, 那么不管其他位是什么, 只要那个位是1,
       * 经过相同运算就还是1
       */
      #include<bits/stdc++.h>
      using namespace std;
       
      int main()
      {
          char st[10];int n,m;scanf("%d%d", &n, &m );
      	int h0=0;                   //全设0
          int h1=(1<<30)-1+(1<<30);   //全设1, (10^9=111011100110101100101000000000,有30位)
          for(int i=1,x; i<=n; i++)
          {
              scanf("%s%d", st, &x );
              if(st[0]=='A' )       h1 &= x, h0 &= x;
              else if( st[0]=='O' ) h1 |= x, h0 |= x;
              else                  h1 ^= x, h0 ^= x;
          }
          int ans=0,x=0;
          for(int i=30;i>=1;i--) 
          {
              if( h0 & (1<<(i-1)) ) ans+= (1<<(i-1)); //如果原来是0之后是1, 就选这个, 让数字尽量小
              else
      		{
      			if ( ( h1 & (1<<(i-1)) )  && ( x+(1 << (i-1)) ) <= m ) ans+= (1<<(i-1)),x+=(1 << (i-1));//原来是1之后还是1, 判断	
              }
          }
          printf("%d\n",ans);
          return 0;
      }
      • 1

      信息

      ID
      5333
      时间
      1000ms
      内存
      256MiB
      难度
      10
      标签
      递交数
      2
      已通过
      2
      上传者