题目链接:http://codeforces.com/problemset/problem/336/C

题目意思:给出一个递增的正整数序列 a1, a2, ..., an,要求从中选出一堆数b1, b2, ..., bk,这堆数进行完按位&运算之后(b1 and b2 and ... and bk),能被2v整除。除此,还要求所选中的这堆数是两两不同的,&之后要最大,换句话来说,v 要尽可能最大,如果找到最大的v的方法有多种,即在 a1, a2, ..., an 中有很多种不同的组合 & 完后能求得最大的v,则挑中的这堆数要尽可能最多。如果得到最多的数还是有多种,只需要写出其中一种即可,如果没找到符合条件的v,则输出-1。

这道题目想了4天多,看来要做出一条综合题的题目真的需要花费很长时间。一开始很天真的以为,暴力从a1往an搜,一个一个&,如果&完之后的结果是0,则置从&中最后运算完的数开始重新初始化。即假设给出序列1 2 3 4 5,1&2之后会等于0,于是不要&前的1,从2开始继续&,2&3......,直到最后一个数&完为止即可。很明显,这是不符合题意的,因为不能保证v最大。

(例如,给出10个数

109070199    215498062    361633800    406156967    452258663

530571268    670482660    704334662    841023955    967424642

错误的解法会得出  704334662    841023955    967424642, &的结果是

1,0000,0001,0000,1000,0000,1000,0010,v = 1。

而正确的结果是    361633800    406156967   452258663    530571268   841023955   967424642, &的结果是1,0000,0000,0000,0000,0000,0000,0000,v = 28。)

看来,&完之后的结果大并不意味着v会更大。关键取决于v的右边的0尽可能最多。

正确的思路:进行两轮筛选。考虑到 an 最大为109 ,且要使v最大,那么应该从v = 31(109 约为 2^30)开始遍历序列,分别尝试与序列中的每个数相&,如果不为0,代表这个数的第 v 位为1,把这个数先保存下来(第一轮筛选,并不保证是最后的结果), 接着从这些被筛选出的数中验证哪些符合第 v-1~1 位与一个第 v-1~1 位都为1的数(也就是下面所说的temp) 相&等于0,符合的就代表v是最优的,则为结果。题目的关键是设置一个临时变量temp,其从第1位到第v-1位都是1,每次将满足第v位为1的,与这个变量做&操作。

能得到这个思路,很谢谢hdu 群的silence,深感位运算的基础没打好啊,要继续努力才行。

 #include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std; const int maxn = + ;
int a[maxn], b[maxn], c[maxn]; // a[]是输入的序列,b[]是第一轮筛选出的数,c[]是第二轮即最后得出符合条件的数 int main()
{
int i, j, k, l, n, v, temp, flag;
while (scanf("%d", &n) != EOF)
{
for (i = ; i < n; i++)
{
scanf("%d", &a[i]);
}
for (v = ; v >= ; v--)
{
temp = ( << v) - ; // 关键所在,使得v-1~1位都置为1
// printf("tempout = %d\n", temp);
flag = j = ;
for (i = ; i < n; i++)
{
if (a[i] & ( << v)) // 挑出序列中满足第v位为1的数
{
// printf("a[%d] = %d\n", i, a[i]);
b[j++] = a[i];
// printf("b[%d] = %d\n", j-1, b[j-1]);
// printf("tempin1 = %d\n", temp);
temp &= a[i];
// printf("tempin2 = %d\n", temp);
}
}
if (j == )
continue; // 没找到进行下一轮循环
// printf("j = %d\n", j);
// printf("temp_num = %d\n", temp);
for (l = k = ; k < j; k++)
{
if (!(temp & b[k])) // 验证第一轮筛选出的数中是否符合第v-1~1位与temp中相&后是否都为0
{
temp &= b[k];
c[l++] = b[k];
// printf("c[%d] = %d\n", l-1, c[l-1]);
}
}
if (l == ) // l 保存找到的总个数
continue;
for (k = ; k < l; k++) // 找到一组解,且这个解满足是最优解
{
if (k == )
printf("%d\n%d", l, c[k]);
else
printf(" %d", c[k]);
}
printf("\n");
flag = ; // 找到符合条件的v的标志
break;
}
if (!flag) // 没有找到
printf("-1\n");
}
return ;
}

codeforces C. Vasily the Bear and Sequence 解题报告的更多相关文章

  1. codeforces A. Vasily the Bear and Triangle 解题报告

    题目链接:http://codeforces.com/problemset/problem/336/A 好简单的一条数学题,是8月9日的.比赛中没有做出来,今天看,从pupil变成Newbie了,那个 ...

  2. codeforces 336C Vasily the Bear and Sequence(贪心)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Vasily the Bear and Sequence Vasily the b ...

  3. C. Vasily the Bear and Sequence Codeforces 336C(枚举,思维)

    C. Vasily the Bear and Sequence time limit per test 1 second memory limit per test 256 megabytes inp ...

  4. codeforces 336D Vasily the Bear and Beautiful Strings(组合数学)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Vasily the Bear and Beautiful Strings Vas ...

  5. USACO Section2.1 Sorting a Three-Valued Sequence 解题报告

    sort3解题报告 —— icedream61 博客园(转载请注明出处)---------------------------------------------------------------- ...

  6. codeforces B. Bear and Strings 解题报告

    题目链接:http://codeforces.com/problemset/problem/385/B 题目意思:给定一条只有小写英文组成的序列,需要找出至少包含一个“bear”的单词的子序列个数.注 ...

  7. codeforces C. Cows and Sequence 解题报告

    题目链接:http://codeforces.com/problemset/problem/284/C 题目意思:给出3种操作:t = 1:在前 a 个数中每个数都加上x: t= 2:在数组末尾增加一 ...

  8. codeforces 336D. Vasily the Bear and Beautiful Strings 组合数学 dp

    题意: 给出n,m,g,求好串的个数 0 <= n,m <= 10^5,n + m >= 1,0 <= g <= 1 好串的定义: 1.只由0,1组成,并且恰好有n个0, ...

  9. timus 1175. Strange Sequence 解题报告

    1.题目描述: 1175. Strange Sequence Time limit: 1.0 secondMemory limit: 2 MB You have been asked to disco ...

随机推荐

  1. 找回Reshaprer的Alt+Enter快捷键的方法

    用过Reshaprer一段时间发现这个Visual Studio插件确实是个好东东,特别是神级快捷键Alt+Enter更是好用至极,可以解决大部分代码问题,不过会发现装上Reshaprer后VS自带的 ...

  2. Bzoj1150 数据备份Backup

    Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家 ...

  3. ECSHOP \admin\edit_languages.php GETSHELL Based On Injection PHP Code Into /languages/zh_cn/user.php

    目录 . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 对于很多CMS网站来说,它们都需要保存很多的网站META信息,最常用的最佳实践是以 ...

  4. Intrusion Analysis Learning

    目录 . 入侵分析简介 . 基于日志的入侵分析技术 . 入侵分析CASE . 入侵分析CASE . 入侵分析CASE . 入侵分析CASE 1. 入侵分析简介 Windows 清除日志的方法 wmic ...

  5. java时间库Joda-Time

    虽然在java8里面有内置的最新的时间库,但是在java8之前的版本所有的时间操作都得自己写,未免有些繁琐,如果我们不自己封装的话可以用Joda-Time这个时间库,下面写下这个库的具体用法. git ...

  6. MySQL 存储过程传参之in, out, inout 参数用法

    存储过程传参:存储过程的括号里,可以声明参数. 语法是 create procedure p([in/out/inout] 参数名  参数类型 ..) in :给参数传入值,定义的参数就得到了值 ou ...

  7. Hibernate之一对多(多对一)

    一.双向关联级联保存客户订单 1.搭建环境,项目结构如下 2.代码及配置如下(数据库里订单表不能用order,因为order是数据库关键字)(客户外键cid和订单表外键cid要在配置中写一致) pac ...

  8. swift项目中引入OC框架

  9. TCP,IP,HTTP,SOCKET区别和联系

    物理层-- 数据链路层-- 传输层--                       TCP协议 会话层-- 我 们在传输数据时,可以只使用(传输层)TCP/IP协议,但是那样的话,如 果没有应用层,便 ...

  10. [Asp.net Mvc]通过UrlHelper扩展为js,css静态文件添加版本号

    写在前面 在app中嵌入h5应用,最头疼的就是缓存的问题,比如你修改了一个样式,或者在js中添加了一个方法,发布之后,并没有更新,加载的仍是缓存里面的内容.这个时候就需要清理缓存才能解决.但又不想让w ...