这是一个很好的题目,来自2013长春网赛。

题目的意思是给你2^N张扑克牌,每次洗牌前分别把从下开始数为奇数和偶数的牌分别拿出来放在一堆,两堆可以任意一个放在上面。

现在问你是否存在一种情况使得经过若干次洗牌后,第A张牌的编号为x,且同时第B张牌的编号为y。(初始状态从低到顶编号从1递增)

题目的解法是用二进制来模拟洗牌的过程,然后发现洗牌的规律为右移+异或操作,然后就可以解决了。

但其实本题最最难以想到的是,题目给你的牌的编号是从1开始的,然而为了方便地使用二进制,我们需要从0开始编号。

首先对于每一个牌,我们都先把其编号减一,相当于从0开始编号,这样对于读入的四个数,我们都将其减一就可以了。

然后我们需要在洗牌的过程中找出洗牌的规律。

是这样的,首先我们把奇数牌和偶数拍分别放成两堆,这样原来i为奇数的牌在奇数堆中间的编号就变为了(i/2),同理编号i为偶数的牌在偶数牌堆中的编号也是(i/2)。

由于要考虑两种牌分别放在上面的情况,我们先考虑奇数的牌放在上面的情况。

假设我们把所有的牌现有的位置用一个二进制表示,如果奇数的牌放在上面,那么偶数牌的最终编号就是偶数牌在偶数堆中间的编号,而奇数牌的编号需要把最高位由0变为1。

细细想来,把这用规律表示,这个规律就是如果奇数牌放下上面,那么现在牌的标号就是原来编号循环右移了一位

好,下面讨论偶数牌放在上面的情况,其实是一样的,只是我们只在偶数牌的编号前面最高位由0变为1而已。

同样我们也用规律表示出来,那就是现在牌的编号为原来编号循环右移一位,并且改变最高位。

综合上面两种说法,如果是奇数牌放在上面,那么所有牌的编号就是循环右移一位,然后最高位异或0;如果是偶数牌放在上面,那么所有牌的编号就是循环右移一位,然后最高位异或1.

现在回到题目,如果x能够通过n次洗牌序号变为A,那么x一定右移了n位,并且每一个数位都与0或1做了异或操作

由于每次洗牌两张牌都是做的同一个运算,也就是说x牌异或了1,那么y牌也一定异或了1。

那么我们只要枚举到底洗了多少次牌,然后看看对于每一位,x到A,y到B能否通过异或同一个值得到,如果所有的位数都是通过异或同一个值得到的,那么显然就存在这样的一个方案;否则,那就不存在这样的方案了。

下面还剩下最后一个问题,那就是我们到底应该判断多少位数呢?

最多只要n位,因为右移超过n位的话就是一个循环了,右移不会改变数位之间的对应关系。

 

第一次做这种二进制的题目,感觉题目的思路挺难想到的,虽然最终还是在内牛满面中A掉此题,但是如果比赛的时候出了这种类似的题目,依然无法保证能够A出来啊。。  T_T

 #include <iostream>
#include <cstdio>
#include <cstring>
#define maxn 1111
using namespace std; int a[maxn],b[maxn],x[maxn],y[maxn],f[maxn],n,k;
char s[maxn];
bool ans; void input(int t[])
{
scanf("%s",s+);
int N=strlen(s+),cur=,tep;
memset(f,,sizeof f);
for (int i=; i<=N; i++) f[i]=s[N+-i]-'';
f[]--;
for (int i=; f[i]<; ) f[i]+=,f[++i]--;
while (N>=)
{
tep=;
t[++cur]=(f[]&);
for (int i=N; i>; i--)
{
f[i]+=*tep;
tep=(f[i]&);
f[i]>>=;
}
if (f[N]==) N--;
}
} int main()
{
int T;
scanf("%d",&T);
for (int cas=; cas<=T; cas++)
{
scanf("%d",&n);
memset(a,,sizeof a);
memset(x,,sizeof x);
memset(b,,sizeof b);
memset(y,,sizeof y);
input(a),input(x),input(b),input(y);
for (int i=; i<=n; i++)//右移了多少位
{
ans=true;
for (int j=; j<=n; j++)//当前第j位进行比较
{
k=j-i;//低位在前,所以右移相当于减
if (k<) k+=n;
if ((a[k]==x[j])^(b[k]==y[j]))
{
ans=false;
break;
}
}
if (ans) break;//找到了存在情况
}
printf("Case %d: ",cas);
if (ans) printf("Yes\n");
else printf("No\n");
}
return ;
}

HDU4759_Poker Shuffle的更多相关文章

  1. Spark Shuffle原理、Shuffle操作问题解决和参数调优

    摘要: 1 shuffle原理 1.1 mapreduce的shuffle原理 1.1.1 map task端操作 1.1.2 reduce task端操作 1.2 spark现在的SortShuff ...

  2. Collections.shuffle

    1.Collections.shuffler 最近有个需求是生成十万级至百万级的所有随机数,最简单的思路是一个个生成,生成新的时候排重,但是这样时间复杂度是o(n^2),网上看了几个博客的解决方法都不 ...

  3. [LeetCode] Shuffle an Array 数组洗牌

    Shuffle a set of numbers without duplicates. Example: // Init an array with set 1, 2, and 3. int[] n ...

  4. mapReduce的shuffle过程

    http://www.jianshu.com/p/c97ff0ab5f49 总结shuffle 过程: map端的shuffle: (1)map端产生数据,放入内存buffer中: (2)buffer ...

  5. spark shuffle 相关细节整理

    1.Shuffle Write 和Shuffle Read具体发生在哪里 2.哪里用到了Partitioner 3.何为mapSideCombine 4.何时进行排序 之前已经看过spark shuf ...

  6. Hadoop学习笔记—10.Shuffle过程那点事儿

    一.回顾Reduce阶段三大步骤 在第四篇博文<初识MapReduce>中,我们认识了MapReduce的八大步骤,其中在Reduce阶段总共三个步骤,如下图所示: 其中,Step2.1就 ...

  7. 由乱序播放说开了去-数组的打乱算法Fisher–Yates Shuffle

    之前用HTML5的Audio API写了个音乐频谱效果,再之后又加了个播放列表就成了个简单的播放器,其中弄了个功能是'Shuffle'也就是一般播放器都有的列表打乱功能,或者理解为随机播放. 但我觉得 ...

  8. 【面试】shuffle函数的实现

    一.前言 有位同学面试的时候被问到shuffle函数的实现,他之后问我,我知道这个函数怎么用,知道是对数组(或集合)中的元素按随机顺序重新排列.但是没有深入研究这个是怎么实现的.现在直接进入JDK源码 ...

  9. MapReduce Shuffle过程

    MapReduce Shuffle 过程详解 一.MapReduce Shuffle过程 1. Map Shuffle过程 2. Reduce Shuffle过程 二.Map Shuffle过程 1. ...

随机推荐

  1. 20155321 2016-2017-2 《Java程序设计》第九周学习总结

    20155321 2016-2017-2 <Java程序设计>第九周学习总结 教材学习内容总结 JDBC简介 厂商在实现JDBC驱动程序时,依方式可将驱动程序分为四种类型: JDBC-OD ...

  2. 21045234黄斐《java程序设计》第四周

    教材学习内容总结 第六章部分 - 继承与多态 何谓继承 继承面向对象中,子类继承父类,避免重复的行为定义.一般来说,父类的父类也称父类,且同一个子类只允许拥有一个父类,而同一个父类则可以拥有多个子类. ...

  3. 一个命令安装lnmp

    安装LNMP执行:wget -c http://soft.vpser.net/lnmp/lnmp1.3-full.tar.gz && tar zxf lnmp1.3-full.tar. ...

  4. 百度地图api 常用 例子

    功能一:获取map地图窗口的可视区域: var map = new BMap.Map("allmap");            // 创建Map实例 map.centerAndZ ...

  5. virsh常用维护命令

    virsh常用命令 一些常用命令参数 [root@kvm-server ~]# virsh --help                                     #查看命令帮忙 [ro ...

  6. pg执行计划

  7. T-SQL语句基础

    连接服务器 - 去哪个仓库找目标数据库 - 找仓库中的目标区域查找目标表 - 找货柜找数据(以行为基础单位) - 在货柜上找到目标的物品 基础T-Sql语句1.SQL语句的注释 2.创建数据库crea ...

  8. Maven学习(十四)-----Maven 构建配置文件

    Maven 构建配置文件 什么是构建配置文件? 生成配置文件是一组可以用来设置或覆盖 Maven 构建配置值的默认值.使用生成配置文件,你可以针对不同的环境,如:生产V/S开发环境自定义构建. 配置文 ...

  9. nuget必备插件(待续)

    DevLib.ExtensionMethods Extend Z.ExtensionMethods

  10. Python科学计算库灬numpy

    Numpy NumPy是一个功能强大的Python库,主要用于对多维数组执行计算.Numpy许多底层函数实际上是用C编写的,因此它的矩阵向量计算速度是原生Python中无法比拟的. numpy属性 维 ...