zoukankan      html  css  js  c++  java
  • ZOJ3870 Team Formation

     1 /**
     2 Author: Oliver
     3 ProblemId: ZOJ3870 Team Formation
     4 */
     5 /*
     6 思路
     7 1.异或运算,使用^会爆,想到二进制;
     8 2.我们可以试着从前往后模拟一位一位的^那么只要当前位结果变大便是;
     9 3.一般我们如何利用二进制呢?既然要爆那我们就存1的位置;
    10 4.问题是怎么存,如何用?
    11 5.我之前想的是每个数的每位1都存,但是那样造成的重复计算还没想出怎么避免。看了一下别人的博客,再尝试把每位数的最高位1存起来。
    12 6.想想为什么是存最高位呢; 
    13 7.那好,现在是不是把所有的高1都存好了,然后我们up(1,n)把原本要和剩余数做异或的步骤变为和bin[]运算。
    14 我们要的是变得比max{A,B}大。那么先看变大,那就要找大一点的那个数,这个时候我们不是和数比较,而是和剩余数的最高位比较。
    15 注意我们要能想到,是以暴力的方法推移过去,做的优化,也就是说每次只要加上可以和这个队伍完成的数目就好了。
    16 注意这样不会有重复(类似A and B,B and A),不会这样。因为有没有发现,每次都是一遍历的这个数为max{A,B}。
    17 注意我们是一位一位往后移,直到吧0->1。 
    18 步骤 可以不写吗?思路很详细了吧。 
    19 *
    20 #include <cstdio>
    21 #include <cstring>
    22 #include <algorithm>
    23 
    24 using namespace std;
    25 
    26 const int MAXM = 100000+10; 
    27 int bin[100];
    28 int a[MAXM]; 
    29 int main()
    30 {
    31 int T,n;
    32 scanf("%d",&T);
    33 while(T--)
    34 {
    35 memset(bin,0,sizeof bin); 
    36 scanf("%d",&n);
    37 int X; 
    38 for(int i=0;i<n;i++) 
    39 {
    40 scanf("%d",&a[i]);
    41 X=a[i]; 
    42 for(int j=31;j>=0;j--)//这里若从32开始,你试试会发生什么事 
    43 if(X&(1<<j)){//提取最高位 
    44 bin[j]++; 
    45 break;
    46 } 
    47 } 
    48 long long ans=0;
    49 int j; 
    50 for(int i=0;i<n;i++)
    51 {
    52 X=a[i]; 
    53 for(j=31;j>=0;j--)
    54 if(X&(1<<j))break;
    55 for(;j>=0;j--)//bin[]运算 
    56 if(!(X&(1<<j))){
    57 ans+=bin[j]; 
    58 } 
    59 }
    60 
    61 printf("%lld
    ",ans); 
    62 }    
    63 }

    2015-04-29  22:30:05

  • 相关阅读:
    sql 存储过程参数为空则不作为条件
    sql 将某一列转成字符串并且去掉最后一个逗号
    日期时间格式加减操作
    未能加载文件或程序集“NPOI”或它的某一个依赖项
    SqlBulkCopy 批量插入
    字符串操作
    CSS基本知识汇总
    ORACLE创建表之前判断表是否存在与SQL Server 对比使用
    SELECT INTO FROM 与 INSERT INTO SELECT区别鉴赏
    SQL 养成一个好习惯是一笔财富
  • 原文地址:https://www.cnblogs.com/newadi/p/4467460.html
Copyright © 2011-2022 走看看