zoukankan      html  css  js  c++  java
  • MZOJ #77 与

     分析

    因为要求的是“与”的最大值

    O(n2)的暴力从数据看不可行,但其实是可行的

    看代码:

    这样写代码的话如果不是特别构造数据,一般都能过

    时间比正解慢不了多少,有时甚至还快一点

    接下来我们说正解

    怎么想到正解的呢?

    首先,“&”的特征是结果包含于原数且为两数共有

    既然枚举原数不行,我们试试枚举答案,然后统计是否有两个以上的数包含就好

    但是a[i]<=1000000000

    当然,不能一个一个枚举

    再想,“&”是二进制运算,当然按位枚举比十进制的枚举要快的多

    怎么枚举呢?

    想想二进制数的特征,当然位数越高,答案越大,后面位数再大,不可能比高位的要大

    所以,贪心;

    贪心的从高位开始枚举,就可以得到最大答案

    就像这样:

    check函数是用于检验是否合法的

    代码

     1 /**************************
     2 User:Mandy.H.Y
     3 Language:c++
     4 Problem:and
     5 Algorithm:
     6 **************************/
     7 
     8 #include<bits/stdc++.h>
     9 
    10 using namespace std;
    11 
    12 const int maxn = 3e5 + 5;
    13 
    14 int n,ans = 0,s = 0;
    15 int a[maxn];
    16 
    17 template<class T>inline void read(T &x){
    18     x = 0;bool flag = 0;char ch = getchar();
    19     while(!isdigit(ch)) flag |= ch == '-',ch = getchar();
    20     while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48),ch = getchar();
    21     if(flag) x = -x;
    22 }
    23 
    24 template<class T>void putch(const T x){
    25     if(x > 9) putch(x / 10);
    26     putchar(x % 10 | 48);
    27 }
    28 
    29 template<class T>void put(const T x){
    30     if(x < 0) putchar('-'),putch(-x);
    31     else putch(x);
    32 }
    33 
    34 void file(){
    35     freopen("and.in","r",stdin);
    36     freopen("and.out","w",stdout);
    37 }
    38 
    39 void readdata(){
    40     read(n);
    41     for(int i = 1;i <= n; ++ i) read(a[i]);
    42 }
    43 
    44 bool cmp(int a,int b){
    45     return a > b;
    46 }
    47 
    48 bool check(int x){
    49     int tot = 0;
    50     for(int i = 1;i <= n; ++ i){
    51         if((a[i] & x) == x) tot ++;
    52         if(tot >= 2) return 1;
    53         if(a[i] < x) break;
    54         //事先将a从大到小排序 
    55     }
    56     return tot >= 2;
    57 }
    58 
    59 void work(){
    60     sort(a + 1,a + n + 1,cmp);
    61     for(int i = 30;i >= 0; -- i){
    62         if(check(ans | ((1 << i)))) ans |= (1 << i);
    63     }
    64     put(ans);
    65 }
    66 
    67 int main(){
    68 //    file();
    69     readdata();
    70     work();
    71     return 0;
    72 }
    View Code
    非做顽石不可,哪管他敬仰暗唾
  • 相关阅读:
    HDU2013 蟠桃记
    HDU2012 素数判定
    I00030 Grades conversion
    HDU2011 多项式求和
    HDU2009 求数列的和
    HDU2005 第几天?【日期计算】
    HDU2004 成绩转换
    HDU2006 求奇数的乘积
    HDU2007 平方和与立方和【序列处理】
    HDU2010 水仙花数【进制+趣味程序】
  • 原文地址:https://www.cnblogs.com/Mandy-H-Y/p/11454103.html
Copyright © 2011-2022 走看看