Poker Shuffle

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 95    Accepted Submission(s): 24

Problem Description
Jason is not only an ACMer, but also a poker nerd. He is able to do a perfect shuffle. In a perfect shuffle, the deck containing K cards, where K is an even number, is split into equal halves of K/2 cards which are then pushed together in a certain way so as to make them perfectly interweave. Suppose the order of the cards is (1, 2, 3, 4, …, K-3, K-2, K-1, K). After a perfect shuffle, the order of the cards will be (1, 3, …, K-3, K-1, 2, 4, …, K-2, K) or (2, 4, …, K-2, K, 1, 3, …, K-3, K-1). 
Suppose K=2^N and the order of the cards is (1, 2, 3, …, K-2, K-1, K) in the beginning, is it possible that the A-th card is X and the B-th card is Y after several perfect shuffles?
 
Input
Input to this problem will begin with a line containing a single integer T indicating the number of datasets.
Each case contains five integer, N, A, X, B, Y. 1 <= N <= 1000, 1 <= A, B, X, Y <= 2^N.
 
Output
For each input case, output “Yes” if it is possible that the A-th card is X and the B-th card is Y after several perfect shuffles, otherwise “No”.
 
Sample Input
3
1 1 1 2 2
2 1 2 4 3
2 1 1 4 2
 
Sample Output
Case 1: Yes
Case 2: Yes
Case 3: No
 
Source
 
Recommend
liuyiding
 

题目意思很简单。

就是洗牌,抽出奇数和偶数,要么奇数放前面,要么偶数放前面。

总共2^N张牌。

需要问的是,给了A X B Y  问经过若干洗牌后,第A个位置是X,第B个位置是Y 是不是可能的。

题目给的牌编号是1开始的,先转换成0开始。

一开始位置是0~2^N-1.  对应的牌是0~2^N-1

首先来看每次洗牌的过程。

对于第一种洗牌:将奇数放前面,偶数放后面。其实每个位置数的变化就是相当于循环右移一位,然后高位异或1.

对于第二种洗牌:讲偶数放前面,奇数放后面。其实每个位置数的变化就是相当于循环右移一位,然后高位异或0.

所以经过若干次洗牌,可以看成是循环右移了K位,然后异或上一个数。

所以对于题目的查询:

首先将A X B Y都减一。  然后枚举X,Y循环右移了K位以后,能不能同时异或上相同的数得到A,B

需要大数,然后转化成二进制就可以解决了。

循环右移X,Y,然后判断A ^ X 是不是等于 B ^ Y

 /* ***********************************************
Author :kuangbin
Created Time :2013/9/28 星期六 11:57:13
File Name :2013长春网络赛\1001.cpp
************************************************ */ #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std; /*
* 完全大数模板
* 输出cin>>a
* 输出a.print();
* 注意这个输入不能自动去掉前导0的,可以先读入到char数组,去掉前导0,再用构造函数。
*/
#define MAXN 9999
#define MAXSIZE 1010
#define DLEN 4 class BigNum
{
public:
int a[]; //可以控制大数的位数
int len;
public:
BigNum(){len=;memset(a,,sizeof(a));} //构造函数
BigNum(const int); //将一个int类型的变量转化成大数
BigNum(const char*); //将一个字符串类型的变量转化为大数
BigNum(const BigNum &); //拷贝构造函数
BigNum &operator=(const BigNum &); //重载赋值运算符,大数之间进行赋值运算
friend istream& operator>>(istream&,BigNum&); //重载输入运算符
friend ostream& operator<<(ostream&,BigNum&); //重载输出运算符 BigNum operator+(const BigNum &)const; //重载加法运算符,两个大数之间的相加运算
BigNum operator-(const BigNum &)const; //重载减法运算符,两个大数之间的相减运算
BigNum operator*(const BigNum &)const; //重载乘法运算符,两个大数之间的相乘运算
BigNum operator/(const int &)const; //重载除法运算符,大数对一个整数进行相除运算 BigNum operator^(const int &)const; //大数的n次方运算
int operator%(const int &)const; //大数对一个int类型的变量进行取模运算
bool operator>(const BigNum &T)const; //大数和另一个大数的大小比较
bool operator>(const int &t)const; //大数和一个int类型的变量的大小比较 void print(); //输出大数
};
BigNum::BigNum(const int b) //将一个int类型的变量转化为大数
{
int c,d=b;
len=;
memset(a,,sizeof(a));
while(d>MAXN)
{
c=d-(d/(MAXN+))*(MAXN+);
d=d/(MAXN+);
a[len++]=c;
}
a[len++]=d;
}
BigNum::BigNum(const char *s) //将一个字符串类型的变量转化为大数
{
int t,k,index,L,i;
memset(a,,sizeof(a));
L=strlen(s);
len=L/DLEN;
if(L%DLEN)len++;
index=;
for(i=L-;i>=;i-=DLEN)
{
t=;
k=i-DLEN+;
if(k<)k=;
for(int j=k;j<=i;j++)
t=t*+s[j]-'';
a[index++]=t;
}
}
BigNum::BigNum(const BigNum &T):len(T.len) //拷贝构造函数
{
int i;
memset(a,,sizeof(a));
for(i=;i<len;i++)
a[i]=T.a[i];
}
BigNum & BigNum::operator=(const BigNum &n) //重载赋值运算符,大数之间赋值运算
{
int i;
len=n.len;
memset(a,,sizeof(a));
for(i=;i<len;i++)
a[i]=n.a[i];
return *this;
}
istream& operator>>(istream &in,BigNum &b)
{
char ch[MAXSIZE*];
int i=-;
in>>ch;
int L=strlen(ch);
int count=,sum=;
for(i=L-;i>=;)
{
sum=;
int t=;
for(int j=;j<&&i>=;j++,i--,t*=)
{
sum+=(ch[i]-'')*t;
}
b.a[count]=sum;
count++;
}
b.len=count++;
return in;
}
ostream& operator<<(ostream& out,BigNum& b) //重载输出运算符
{
int i;
cout<<b.a[b.len-];
for(i=b.len-;i>=;i--)
{
printf("%04d",b.a[i]);
}
return out;
}
BigNum BigNum::operator+(const BigNum &T)const //两个大数之间的相加运算
{
BigNum t(*this);
int i,big;
big=T.len>len?T.len:len;
for(i=;i<big;i++)
{
t.a[i]+=T.a[i];
if(t.a[i]>MAXN)
{
t.a[i+]++;
t.a[i]-=MAXN+;
}
}
if(t.a[big]!=)
t.len=big+;
else t.len=big;
return t;
}
BigNum BigNum::operator-(const BigNum &T)const //两个大数之间的相减运算
{
int i,j,big;
bool flag;
BigNum t1,t2;
if(*this>T)
{
t1=*this;
t2=T;
flag=;
}
else
{
t1=T;
t2=*this;
flag=;
}
big=t1.len;
for(i=;i<big;i++)
{
if(t1.a[i]<t2.a[i])
{
j=i+;
while(t1.a[j]==)
j++;
t1.a[j--]--;
while(j>i)
t1.a[j--]+=MAXN;
t1.a[i]+=MAXN+-t2.a[i];
}
else t1.a[i]-=t2.a[i];
}
t1.len=big;
while(t1.a[len-]== && t1.len>)
{
t1.len--;
big--;
}
if(flag)
t1.a[big-]=-t1.a[big-];
return t1;
}
BigNum BigNum::operator*(const BigNum &T)const //两个大数之间的相乘
{
BigNum ret;
int i,j,up;
int temp,temp1;
for(i=;i<len;i++)
{
up=;
for(j=;j<T.len;j++)
{
temp=a[i]*T.a[j]+ret.a[i+j]+up;
if(temp>MAXN)
{
temp1=temp-temp/(MAXN+)*(MAXN+);
up=temp/(MAXN+);
ret.a[i+j]=temp1;
}
else
{
up=;
ret.a[i+j]=temp;
}
}
if(up!=)
ret.a[i+j]=up;
}
ret.len=i+j;
while(ret.a[ret.len-]== && ret.len>)ret.len--;
return ret;
}
BigNum BigNum::operator/(const int &b)const //大数对一个整数进行相除运算
{
BigNum ret;
int i,down=;
for(i=len-;i>=;i--)
{
ret.a[i]=(a[i]+down*(MAXN+))/b;
down=a[i]+down*(MAXN+)-ret.a[i]*b;
}
ret.len=len;
while(ret.a[ret.len-]== && ret.len>)
ret.len--;
return ret;
}
int BigNum::operator%(const int &b)const //大数对一个 int类型的变量进行取模
{
int i,d=;
for(i=len-;i>=;i--)
d=((d*(MAXN+))%b+a[i])%b;
return d;
}
BigNum BigNum::operator^(const int &n)const //大数的n次方运算
{
BigNum t,ret();
int i;
if(n<)exit(-);
if(n==)return ;
if(n==)return *this;
int m=n;
while(m>)
{
t=*this;
for(i=;(i<<)<=m;i<<=)
t=t*t;
m-=i;
ret=ret*t;
if(m==)ret=ret*(*this);
}
return ret;
}
bool BigNum::operator>(const BigNum &T)const //大数和另一个大数的大小比较
{
int ln;
if(len>T.len)return true;
else if(len==T.len)
{
ln=len-;
while(a[ln]==T.a[ln]&&ln>=)
ln--;
if(ln>= && a[ln]>T.a[ln])
return true;
else
return false;
}
else
return false;
}
bool BigNum::operator>(const int &t)const //大数和一个int类型的变量的大小比较
{
BigNum b(t);
return *this>b;
}
void BigNum::print() //输出大数
{
int i;
printf("%d",a[len-]);
for(i=len-;i>=;i--)
printf("%04d",a[i]);
printf("\n");
}
bool ONE(BigNum a)
{
if(a.len == && a.a[] == )return true;
else return false;
}
BigNum A,B,X,Y;
char str1[],str2[],str3[],str4[]; int a[],b[],x[],y[];
int c[];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T;
int n;
int iCase = ;
scanf("%d",&T);
while(T--)
{
iCase++;
scanf("%d",&n);
cin>>A>>X>>B>>Y;
printf("Case %d: ",iCase) ;
A = A-;
X = X-;
B = B-;
Y = Y-;
for(int i = ;i < n;i++)
{
if(A.a[]% == )a[i] = ;
else a[i] = ;
if(B.a[]% == )b[i] = ;
else b[i] = ;
if(X.a[]% == )x[i] = ;
else x[i] = ;
if(Y.a[]% == )y[i] = ;
else y[i] = ;
A = A/;
B = B/;
X = X/;
Y = Y/;
}
bool flag = false;
for(int k = ;k <= n;k++)
{
x[n] = x[];
y[n] = y[];
for(int i = ;i < n;i++)
{
x[i] = x[i+];
y[i] = y[i+];
}
for(int i = ;i < n;i++)
{
if(a[i] == x[i])c[i] = ;
else c[i] = ;
}
bool fff = true;
for(int i = ;i < n;i++)
if(b[i]^c[i] != y[i])
{
fff = false;
break;
}
if(fff)flag = true;
if(flag)break; }
if(flag)printf("Yes\n");
else printf("No\n");
}
return ;
}

再贴一下JAVA的程序。

JAVA写大数很方便啊。。。。

 import java.io.*;
import java.util.*;
import java.math.*;
public class Main { public static void main(String args[])
{
int T;
int iCase = 0;
int n;
BigInteger A,X,B,Y;
int []a = new int[1010];
int []x = new int[1010];
int []b = new int[1010];
int []y = new int[1010];
Scanner cin = new Scanner(System.in);
T = cin.nextInt();
while(T > 0)
{
iCase++;
n = cin.nextInt();
A = cin.nextBigInteger();
X = cin.nextBigInteger();
B = cin.nextBigInteger();
Y = cin.nextBigInteger();
A = A.subtract(BigInteger.ONE);
X = X.subtract(BigInteger.ONE);
B = B.subtract(BigInteger.ONE);
Y = Y.subtract(BigInteger.ONE);
for(int i = 0;i < n;i++)
{
a[i] = A.mod(BigInteger.valueOf(2)).intValue();
b[i] = B.mod(BigInteger.valueOf(2)).intValue();
x[i] = X.mod(BigInteger.valueOf(2)).intValue();
y[i] = Y.mod(BigInteger.valueOf(2)).intValue();
A = A.divide(BigInteger.valueOf(2));
B = B.divide(BigInteger.valueOf(2));
X = X.divide(BigInteger.valueOf(2));
Y = Y.divide(BigInteger.valueOf(2));
//System.out.println(a[i]+" "+ x[i]+" "+ b[i]+" "+y[i]);
}
boolean flag = false;
for(int k = 0;k <= n;k++)
{
x[n] = x[0];
for(int i = 0;i < n;i++)x[i] = x[i+1];
y[n] = y[0];
for(int i = 0;i < n;i++)y[i] = y[i+1];
boolean ff = true;
for(int i = 0;i < n;i++)
if((x[i]^a[i]) != (y[i]^b[i]))
{
ff = false;
break;
}
if(ff)
{
flag = true;
break;
}
}
if(flag)System.out.println("Case "+iCase+": Yes");
else System.out.println("Case "+iCase+": No");
T--;
}
} }

HDU 4759 Poker Shuffle(2013长春网络赛1001题)的更多相关文章

  1. HDU 4768 Flyer (2013长春网络赛1010题,二分)

    Flyer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  2. HDU 4762 Cut the Cake (2013长春网络赛1004题,公式题)

    Cut the Cake Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  3. HDU 4738 Caocao's Bridges (2013杭州网络赛1001题,连通图,求桥)

    Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  4. HDU 4816 Bathysphere (2013长春现场赛D题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4816 2013长春区域赛的D题. 很简单的几何题,就是给了一条折线. 然后一个矩形窗去截取一部分,求最 ...

  5. HDU 4747 Mex (2013杭州网络赛1010题,线段树)

    Mex Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submis ...

  6. HDU 4821 String(2013长春现场赛I题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4821 字符串题. 现场使用字符串HASH乱搞的. 枚举开头! #include <stdio.h ...

  7. HDU 4763 Theme Section (2013长春网络赛1005,KMP)

    Theme Section Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot ...

  8. HDU 4764 Stone (2013长春网络赛,水博弈)

    Stone Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  9. HDU 4751 Divide Groups (2013南京网络赛1004题,判断二分图)

    Divide Groups Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot ...

随机推荐

  1. java学习第04天(语句、函数、数组)

    (3)循环结构 格式: for(初始化表达式,循环条件表达式,循环后的操作变大时){ 执行语句,循环体: } 注: a. for循环里面的连个表达式运行的顺序,初始化表达式只读一次,判断循环条件,为真 ...

  2. 第7月第20天 epoll

    1. ) { struct sockaddr in_addr; socklen_t in_len; int infd; char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; ...

  3. js星星评分插件

    下载:https://files.cnblogs.com/files/wordblog/%E6%98%9F%E6%98%9F%E6%8F%92%E4%BB%B6.rar

  4. 总结---Python中的面向对象!

    面向对象这种编程的范式每个语言都是通用的,这里总结一下python的面向对象语法,主要包含以下几个方面! 1 基本语法 # 定义类 class Person(object): n = 10 # 类变量 ...

  5. DVWA的Xss跨站总结

    Xss跨站总结 初级防护的代码 Poc:<script>alert(1)</script> 上图防护的代码 为输入的结果就为输出的结果 中级防护的代码 Poc:<scri ...

  6. 09 Go 1.9 Release Notes

    Go 1.9 Release Notes Introduction to Go 1.9 Changes to the language Ports ppc64x requires POWER8 Fre ...

  7. MySQL root密码忘记后更优雅的解决方法

    MySQL root密码忘记后更优雅的解决方法 https://www.jb51.net/article/143453.htm /usr/bin/mysqld_safe --defaults-file ...

  8. Window8.1下oracle数据库报:ora-12170 操作超时

    PLSQL 链接本机:oracle11g 服务名:orcl   一直链接不上,等了大概3分钟, 提示:ora-12170操作超时: 重启了数据库 问题还是无法解决;上网搜了一下,发现报ora-1217 ...

  9. HighCharts、EChart图表X轴纵向显示

    HighCharts 回调javascript函数来格式化标签,值通过this.value获得,this的其他属性还包括axis, chart, isFirst and isLast. 默认为: fu ...

  10. 再议mysql 主从配置

    1.创建用户: grant replication slave,replication client on *.* to repl@'192.168.1.%' IDENTIFIED By 'p4ssw ...