zoukankan      html  css  js  c++  java
  • BZOJ 3668 起床苦难综合症

        看到这道题,分析后第一反应是取1的数最大的数,很明显我是忽略了 XOR 可以把0变成1的可能性。 后来想了想,又看了别人的题解后发现。这二进制的变换中每一位都是互相独立的,因为每一个数都只有两种初始状态和终止状态。即一开始为0的二进制位经过多次变换后可能为1或者为0, 为1的二进制位经过变换后也有可能变为1或0, 很明显,如果一开始为0的二进制位经过多次变换后变成了1,那么我们优先选择该二进制位的初始状态为0,如果不成立,如果一开始为1的二进制经过多次变换后可以变成1,且该数小于 m, 那么我们也可以将其初始状态设为1,若该二进制位无论0或1,最终都只是0,那么我们将其赋值为0.很显然,用两个数一个是0,一个是2的31次方减1, 去进行多次变换后看两者的值进行舍取得到最终的答案。

       经验教训:

       1:盲目认为0xfffffff 是2的31次方-1. WA了几次。

       2:一开始在于初始状态为0的二进制位上认为要小于m,WA了几次。

      心酸啊!

      启发,有时候把一些复杂的题中各部分独立出来,一个个去解决。当然前提也是这道题中各部分不会相互影响。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #define rep(i,j,k) for(int i = j; i <= k; i++)
     5 #define down(i,j,k) for(int i = j; i >= k; i--)
     6 #define LL long long
     7 using namespace std;
     8 LL num = pow(2,31)-1;
     9 LL num2 = 0;
    10   
    11 int read()
    12 {
    13     int s = 0, t = 1; char c = getchar();
    14     while( !isdigit(c) ){
    15         if( c == '-' ) t = -1; c = getchar();
    16     }
    17     while( isdigit(c) ){
    18         s = s * 10 + c - '0'; c = getchar();
    19     }
    20     return s * t;
    21 }
    22   
    23 int main()
    24 {
    25     int n = read(), m = read();
    26     char c[5] = {0};
    27     rep(i,1,n){
    28         scanf("%s", &c);
    29         int x = read();
    30         if( c[0] == 'A' ){
    31             num &= x;
    32             num2 &= x;  
    33         }
    34         if( c[0] == 'X' ){
    35             num ^= x;
    36             num2 ^= x;
    37         }
    38         if( c[0] == 'O' ){
    39             num |= x;
    40             num2 |= x;
    41         }
    42     }
    43     LL ans = 0;
    44     down(i,31,0){
    45         if( (num2 & (1<<i)) ){
    46             ans += (1 << i);
    47         }
    48         else if( (num & (1<<i)) && ((1<<i) <= m) ){
    49             m -= (1 << i);
    50             ans += (1 << i);
    51         }
    52     }
    53     cout<<ans<<endl;
    54     return 0;
    55 }

    3668: [Noi2014]起床困难综合症

    Time Limit: 10 Sec  Memory Limit: 512 MB
    Submit: 1164  Solved: 660
    [Submit][Status][Discuss]

    Description

    21 世纪,许多人得了一种奇怪的病:起床困难综合症,其临床表现为:起床难,起床后精神不佳。作为一名青春阳光好少年,atm 一直坚持与起床困难综合症作斗争。通过研究相关文献,他找到了该病的发病原因:在深邃的太平洋海底中,出现了一条名为 drd 的巨龙,它掌握着睡眠之精髓,能随意延长大家的睡眠时间。正是由于 drd 的活动,起床困难综合症愈演愈烈,以惊人的速度在世界上传播。为了彻底消灭这种病,atm 决定前往海底,消灭这条恶龙。
    历经千辛万苦,atm 终于来到了 drd 所在的地方,准备与其展开艰苦卓绝的战斗。drd 有着十分特殊的技能,他的防御战线能够使用一定的运算来改变他受到的伤害。具体说来,drd 的防御战线由 n扇防御门组成。每扇防御门包括一个运算op和一个参数t,其中运算一定是OR,XOR,AND中的一种,参数则一定为非负整数。如果还未通过防御门时攻击力为x,则其通过这扇防御门后攻击力将变为x op t。最终drd 受到的伤害为对方初始攻击力x依次经过所有n扇防御门后转变得到的攻击力。
    由于atm水平有限,他的初始攻击力只能为0到m之间的一个整数(即他的初始攻击力只能在0,1,...,m中任选,但在通过防御门之后的攻击力不受 m的限制)。为了节省体力,他希望通过选择合适的初始攻击力使得他的攻击能让 drd 受到最大的伤害,请你帮他计算一下,他的一次攻击最多能使 drd 受到多少伤害。

    Input

    第1行包含2个整数,依次为n,m,表示drd有n扇防御门,atm的初始攻击力为0到m之间的整数。接下来n行,依次表示每一扇防御门。每行包括一个字符串op和一个非负整数t,两者由一个空格隔开,且op在前,t在后,op表示该防御门所对应的操作, t表示对应的参数。

    Output

    一行一个整数,表示atm的一次攻击最多使 drd 受到多少伤害。

    Sample Input

    3 10
    AND 5
    OR 6
    XOR 7

    Sample Output

    1
    人一我十,人十我万!追逐青春的梦想,怀着自信的心,永不放弃!仿佛已看到希望,尽管还在远方
  • 相关阅读:
    0593. Valid Square (M)
    0832. Flipping an Image (E)
    1026. Maximum Difference Between Node and Ancestor (M)
    0563. Binary Tree Tilt (E)
    0445. Add Two Numbers II (M)
    1283. Find the Smallest Divisor Given a Threshold (M)
    C Primer Plus note9
    C Primer Plus note8
    C Primer Plus note7
    C Primer Plus note6
  • 原文地址:https://www.cnblogs.com/83131yyl/p/5053824.html
Copyright © 2011-2022 走看看