题目意思很简单。

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

总共2^N张牌。

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

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?

题目给的牌编号是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

 #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 = ;
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
#endif
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 ;
}

hdu 4759 大数+找规律 ***的更多相关文章

  1. hdu 5047 大数找规律

    http://acm.hdu.edu.cn/showproblem.php?pid=5047 找规律 信kuangbin,能AC #include <stdio.h> #include & ...

  2. HDU 2086 A1 = ? (找规律推导公式 + 水题)(Java版)

    Equations 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2086 ——每天在线,欢迎留言谈论. 题目大意: 有如下方程:Ai = (Ai-1 ...

  3. hdu 5106 组合数学+找规律

    http://acm.hdu.edu.cn/showproblem.php?pid=5106 给定n和r,要求算出[0,r)之间所有n-onebit数的和,n-onebit数是所有数位中1的个数. 对 ...

  4. Doom HDU - 5239 (找规律+线段树)

     题目链接: D - Doom  HDU - 5239  题目大意:首先是T组测试样例,然后n个数,m次询问,然后每一次询问给你一个区间,问你这个这段区间的加上上一次的和是多少,查询完之后,这段区间里 ...

  5. hdu 4708(暴力+找规律)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4708 思路:由于N不大,并且我们可以发现通过旋转得到的4个对角线的点的位置关系,以及所要旋转的最小步数 ...

  6. HDU 5084 HeHe --找规律

    题意: 给出矩阵M,求M*M矩阵的r行c列的数,每个查询跟前一个查询的结果有关. 解法: 观察该矩阵得知,令ans = M*M,则 ans[x][y] = (n-1-x行的每个值)*(n-1+y列的每 ...

  7. HDU 1847 (博弈 找规律) Good Luck in CET-4 Everybody!

    为了提高题解质量还是简单证明一下:3的倍数是必败状态. 如果n % 3 = 1,那么拿走1个石子:如果n % 3 = 2,那么拿走两个石子,都将转移到3的倍数的状态.所以每个必胜状态都有一个后继是必败 ...

  8. HDU 2897 (博弈 找规律) 邂逅明下

    根据博弈论的两条规则: 一个状态是必胜状态当且仅当有一个后继是必败状态 一个状态是必败状态当且仅当所有后继都是必胜状态 然后很容易发现从1开始,前p个状态是必败状态,后面q个状态是必胜状态,然后循环往 ...

  9. hdu 4455 Substrings(找规律&DP)

    Substrings Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

随机推荐

  1. [转载]Python-第三方库requests详解

    Requests 是用Python语言编写,基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库.它比 urllib 更加方便,可以节约我们大量的工作,完全满足 HTT ...

  2. centos7最小版本安装nginx+tomcat+java+mysql运行环境

    最近项目从windows搬到linux,由于项目组成员有限并且有其它紧急的任务需要处理,因而这个任务就落到我的头上了.下面记录下centos最小版本安装nginx+tomcat+mysql+java的 ...

  3. iptables之链之间的跳转

    创建一个新的链     按照管理,用户自定义的链用小写来区分它们 iptables -N newchain 可以在这个链的尾部跳转到INPUT链 iptables -A newchain -j INP ...

  4. Android SDK打包

    2015年6月18日 14:38:49 星期四 eclipse: 1. 将写好的代码上传版本库 2. 删除 /bin/* 3. eclipse->project->clean... 4. ...

  5. MySQL 5.6 my.cnf 模版

    [client] port = socket = /var/run/mysqld/mysqld.sock [mysqld_safe] thp-setting=never socket = /var/r ...

  6. 在java项目中使用AES256 CBC加密

    首先要注意一点,默认的JDK是不支持256位加密的,需要到Oracle官网下载加密增强文件(Java Cryptography Extension (JCE) Unlimited Strength J ...

  7. java 入门 第二季4

    1. 多态 继承是多态的实现基础 引用的多态 父类的引用可以指向本类的对象 父类的引用可以指向子类的对象 方法的多态 创建本类对象时,调用本类方法 2种是调用子类的方法或继承的方法 子类中添加独有的方 ...

  8. ssm控制输出sql(二)

    望时高科联通log4j # DEBUG,INFO,WARN,ERROR,FATAL LOG_LEVEL=DEBUG ---------这里对应sql的级别 log4j.rootLogger=${LOG ...

  9. Android随笔:属性

    android:padding表示给控件的周围加上补白,这样不至于让文本内容会紧靠在边缘上. android:singleLine 设置为true 表示让这个TextView 只能单行显示. andr ...

  10. bootstrap垂直下拉菜单默认展开

    HTML: <div class="col-md-3"> <nav class="navbar"> <div class=&quo ...