zoukankan      html  css  js  c++  java
  • HDU 4759 Poker Shuffle(2013长春网络赛1001题)

    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

      1 /* ***********************************************
      2 Author        :kuangbin
      3 Created Time  :2013/9/28 星期六 11:57:13
      4 File Name     :2013长春网络赛1001.cpp
      5 ************************************************ */
      6 
      7 #pragma comment(linker, "/STACK:1024000000,1024000000")
      8 #include <stdio.h>
      9 #include <string.h>
     10 #include <iostream>
     11 #include <algorithm>
     12 #include <vector>
     13 #include <queue>
     14 #include <set>
     15 #include <map>
     16 #include <string>
     17 #include <math.h>
     18 #include <stdlib.h>
     19 #include <time.h>
     20 using namespace std;
     21 
     22 /*
     23  * 完全大数模板
     24  * 输出cin>>a
     25  * 输出a.print();
     26  * 注意这个输入不能自动去掉前导0的,可以先读入到char数组,去掉前导0,再用构造函数。
     27  */
     28 #define MAXN 9999
     29 #define MAXSIZE 1010
     30 #define DLEN 4
     31 
     32 class BigNum
     33 {
     34 public:
     35     int a[500];  //可以控制大数的位数
     36     int len;
     37 public:
     38     BigNum(){len=1;memset(a,0,sizeof(a));}  //构造函数
     39     BigNum(const int);     //将一个int类型的变量转化成大数
     40     BigNum(const char*);   //将一个字符串类型的变量转化为大数
     41     BigNum(const BigNum &); //拷贝构造函数
     42     BigNum &operator=(const BigNum &); //重载赋值运算符,大数之间进行赋值运算
     43     friend istream& operator>>(istream&,BigNum&); //重载输入运算符
     44     friend ostream& operator<<(ostream&,BigNum&); //重载输出运算符
     45 
     46     BigNum operator+(const BigNum &)const;  //重载加法运算符,两个大数之间的相加运算
     47     BigNum operator-(const BigNum &)const;  //重载减法运算符,两个大数之间的相减运算
     48     BigNum operator*(const BigNum &)const;  //重载乘法运算符,两个大数之间的相乘运算
     49     BigNum operator/(const int &)const;     //重载除法运算符,大数对一个整数进行相除运算
     50 
     51     BigNum operator^(const int &)const;     //大数的n次方运算
     52     int operator%(const int &)const;        //大数对一个int类型的变量进行取模运算
     53     bool operator>(const BigNum &T)const;   //大数和另一个大数的大小比较
     54     bool operator>(const int &t)const;      //大数和一个int类型的变量的大小比较
     55 
     56     void print();        //输出大数
     57 };
     58 BigNum::BigNum(const int b)   //将一个int类型的变量转化为大数
     59 {
     60     int c,d=b;
     61     len=0;
     62     memset(a,0,sizeof(a));
     63     while(d>MAXN)
     64     {
     65         c=d-(d/(MAXN+1))*(MAXN+1);
     66         d=d/(MAXN+1);
     67         a[len++]=c;
     68     }
     69     a[len++]=d;
     70 }
     71 BigNum::BigNum(const char *s)  //将一个字符串类型的变量转化为大数
     72 {
     73     int t,k,index,L,i;
     74     memset(a,0,sizeof(a));
     75     L=strlen(s);
     76     len=L/DLEN;
     77     if(L%DLEN)len++;
     78     index=0;
     79     for(i=L-1;i>=0;i-=DLEN)
     80     {
     81         t=0;
     82         k=i-DLEN+1;
     83         if(k<0)k=0;
     84         for(int j=k;j<=i;j++)
     85             t=t*10+s[j]-'0';
     86         a[index++]=t;
     87     }
     88 }
     89 BigNum::BigNum(const BigNum &T):len(T.len)  //拷贝构造函数
     90 {
     91     int i;
     92     memset(a,0,sizeof(a));
     93     for(i=0;i<len;i++)
     94         a[i]=T.a[i];
     95 }
     96 BigNum & BigNum::operator=(const BigNum &n)  //重载赋值运算符,大数之间赋值运算
     97 {
     98     int i;
     99     len=n.len;
    100     memset(a,0,sizeof(a));
    101     for(i=0;i<len;i++)
    102         a[i]=n.a[i];
    103     return *this;
    104 }
    105 istream& operator>>(istream &in,BigNum &b)
    106 {
    107     char ch[MAXSIZE*4];
    108     int i=-1;
    109     in>>ch;
    110     int L=strlen(ch);
    111     int count=0,sum=0;
    112     for(i=L-1;i>=0;)
    113     {
    114         sum=0;
    115         int t=1;
    116         for(int j=0;j<4&&i>=0;j++,i--,t*=10)
    117         {
    118             sum+=(ch[i]-'0')*t;
    119         }
    120         b.a[count]=sum;
    121         count++;
    122     }
    123     b.len=count++;
    124     return in;
    125 }
    126 ostream& operator<<(ostream& out,BigNum& b)  //重载输出运算符
    127 {
    128     int i;
    129     cout<<b.a[b.len-1];
    130     for(i=b.len-2;i>=0;i--)
    131     {
    132         printf("%04d",b.a[i]);
    133     }
    134     return out;
    135 }
    136 BigNum BigNum::operator+(const BigNum &T)const   //两个大数之间的相加运算
    137 {
    138     BigNum t(*this);
    139     int i,big;
    140     big=T.len>len?T.len:len;
    141     for(i=0;i<big;i++)
    142     {
    143         t.a[i]+=T.a[i];
    144         if(t.a[i]>MAXN)
    145         {
    146             t.a[i+1]++;
    147             t.a[i]-=MAXN+1;
    148         }
    149     }
    150     if(t.a[big]!=0)
    151        t.len=big+1;
    152     else t.len=big;
    153     return t;
    154 }
    155 BigNum BigNum::operator-(const BigNum &T)const  //两个大数之间的相减运算
    156 {
    157     int i,j,big;
    158     bool flag;
    159     BigNum t1,t2;
    160     if(*this>T)
    161     {
    162         t1=*this;
    163         t2=T;
    164         flag=0;
    165     }
    166     else
    167     {
    168         t1=T;
    169         t2=*this;
    170         flag=1;
    171     }
    172     big=t1.len;
    173     for(i=0;i<big;i++)
    174     {
    175         if(t1.a[i]<t2.a[i])
    176         {
    177             j=i+1;
    178             while(t1.a[j]==0)
    179                 j++;
    180             t1.a[j--]--;
    181             while(j>i)
    182                 t1.a[j--]+=MAXN;
    183             t1.a[i]+=MAXN+1-t2.a[i];
    184         }
    185         else t1.a[i]-=t2.a[i];
    186     }
    187     t1.len=big;
    188     while(t1.a[len-1]==0 && t1.len>1)
    189     {
    190         t1.len--;
    191         big--;
    192     }
    193     if(flag)
    194         t1.a[big-1]=0-t1.a[big-1];
    195     return t1;
    196 }
    197 BigNum BigNum::operator*(const BigNum &T)const  //两个大数之间的相乘
    198 {
    199     BigNum ret;
    200     int i,j,up;
    201     int temp,temp1;
    202     for(i=0;i<len;i++)
    203     {
    204         up=0;
    205         for(j=0;j<T.len;j++)
    206         {
    207             temp=a[i]*T.a[j]+ret.a[i+j]+up;
    208             if(temp>MAXN)
    209             {
    210                 temp1=temp-temp/(MAXN+1)*(MAXN+1);
    211                 up=temp/(MAXN+1);
    212                 ret.a[i+j]=temp1;
    213             }
    214             else
    215             {
    216                 up=0;
    217                 ret.a[i+j]=temp;
    218             }
    219         }
    220         if(up!=0)
    221            ret.a[i+j]=up;
    222     }
    223     ret.len=i+j;
    224     while(ret.a[ret.len-1]==0 && ret.len>1)ret.len--;
    225     return ret;
    226 }
    227 BigNum BigNum::operator/(const int &b)const  //大数对一个整数进行相除运算
    228 {
    229     BigNum ret;
    230     int i,down=0;
    231     for(i=len-1;i>=0;i--)
    232     {
    233         ret.a[i]=(a[i]+down*(MAXN+1))/b;
    234         down=a[i]+down*(MAXN+1)-ret.a[i]*b;
    235     }
    236     ret.len=len;
    237     while(ret.a[ret.len-1]==0 && ret.len>1)
    238         ret.len--;
    239     return ret;
    240 }
    241 int BigNum::operator%(const int &b)const   //大数对一个 int类型的变量进行取模
    242 {
    243     int i,d=0;
    244     for(i=len-1;i>=0;i--)
    245         d=((d*(MAXN+1))%b+a[i])%b;
    246     return d;
    247 }
    248 BigNum BigNum::operator^(const int &n)const  //大数的n次方运算
    249 {
    250     BigNum t,ret(1);
    251     int i;
    252     if(n<0)exit(-1);
    253     if(n==0)return 1;
    254     if(n==1)return *this;
    255     int m=n;
    256     while(m>1)
    257     {
    258         t=*this;
    259         for(i=1;(i<<1)<=m;i<<=1)
    260            t=t*t;
    261         m-=i;
    262         ret=ret*t;
    263         if(m==1)ret=ret*(*this);
    264     }
    265     return ret;
    266 }
    267 bool BigNum::operator>(const BigNum &T)const    //大数和另一个大数的大小比较
    268 {
    269     int ln;
    270     if(len>T.len)return true;
    271     else if(len==T.len)
    272     {
    273         ln=len-1;
    274         while(a[ln]==T.a[ln]&&ln>=0)
    275           ln--;
    276         if(ln>=0 && a[ln]>T.a[ln])
    277            return true;
    278         else
    279            return false;
    280     }
    281     else
    282        return false;
    283 }
    284 bool BigNum::operator>(const int &t)const  //大数和一个int类型的变量的大小比较
    285 {
    286     BigNum b(t);
    287     return *this>b;
    288 }
    289 void BigNum::print()   //输出大数
    290 {
    291     int i;
    292     printf("%d",a[len-1]);
    293     for(i=len-2;i>=0;i--)
    294       printf("%04d",a[i]);
    295     printf("
    ");
    296 }
    297 bool ONE(BigNum a)
    298 {
    299     if(a.len == 1 && a.a[0] == 1)return true;
    300     else return false;
    301 }
    302 BigNum A,B,X,Y;
    303 char str1[10010],str2[10010],str3[10010],str4[10010];
    304 
    305 
    306 int a[1010],b[1010],x[1010],y[1010];
    307 int c[1010];
    308 int main()
    309 {
    310     //freopen("in.txt","r",stdin);
    311     //freopen("out.txt","w",stdout);
    312     int T;
    313     int n;
    314     int iCase = 0;
    315     scanf("%d",&T);
    316     while(T--)
    317     {
    318         iCase++;
    319         scanf("%d",&n);
    320         cin>>A>>X>>B>>Y;
    321         printf("Case %d: ",iCase) ;
    322         A = A-1;
    323         X = X-1;
    324         B = B-1;
    325         Y = Y-1;
    326         for(int i = 0;i < n;i++)
    327         {
    328             if(A.a[0]%2 == 0)a[i] = 0;
    329             else a[i] = 1;
    330             if(B.a[0]%2 == 0)b[i] = 0;
    331             else b[i] = 1;
    332             if(X.a[0]%2 == 0)x[i] = 0;
    333             else x[i] = 1;
    334             if(Y.a[0]%2 == 0)y[i] = 0;
    335             else y[i] = 1;
    336             A = A/2;
    337             B = B/2;
    338             X = X/2;
    339             Y = Y/2;
    340         }
    341         bool flag = false;
    342         for(int k = 0;k <= n;k++)
    343         {
    344             x[n] = x[0];
    345             y[n] = y[0];
    346             for(int i = 0;i < n;i++)
    347             {
    348                 x[i] = x[i+1];
    349                 y[i] = y[i+1];
    350             }
    351             for(int i = 0;i < n;i++)
    352             {
    353                 if(a[i] == x[i])c[i] = 0;
    354                 else c[i] = 1;
    355             }
    356             bool fff = true;
    357             for(int i = 0;i < n;i++)
    358                 if(b[i]^c[i] != y[i])
    359                 {
    360                     fff = false;
    361                     break;
    362                 }
    363             if(fff)flag = true;
    364             if(flag)break;
    365 
    366         }
    367         if(flag)printf("Yes
    ");
    368         else printf("No
    ");
    369     }
    370     return 0;
    371 }

     再贴一下JAVA的程序。

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

     1 import java.io.*;
     2 import java.util.*;
     3 import java.math.*;
     4 public class Main {
     5     
     6     public static void main(String args[])
     7     {
     8         int T;
     9         int iCase = 0;
    10         int n;
    11         BigInteger A,X,B,Y;
    12         int []a = new int[1010];
    13         int []x = new int[1010];
    14         int []b = new int[1010];
    15         int []y = new int[1010];
    16         Scanner cin = new Scanner(System.in);
    17         T = cin.nextInt();
    18         while(T > 0)
    19         {
    20             iCase++;
    21             n = cin.nextInt();
    22             A = cin.nextBigInteger();
    23             X = cin.nextBigInteger();
    24             B = cin.nextBigInteger();
    25             Y = cin.nextBigInteger();
    26             A = A.subtract(BigInteger.ONE);
    27             X = X.subtract(BigInteger.ONE);
    28             B = B.subtract(BigInteger.ONE);
    29             Y = Y.subtract(BigInteger.ONE);
    30             for(int i = 0;i < n;i++)
    31             {
    32                 a[i] = A.mod(BigInteger.valueOf(2)).intValue();
    33                 b[i] = B.mod(BigInteger.valueOf(2)).intValue();
    34                 x[i] = X.mod(BigInteger.valueOf(2)).intValue();
    35                 y[i] = Y.mod(BigInteger.valueOf(2)).intValue();
    36                 A = A.divide(BigInteger.valueOf(2));
    37                 B = B.divide(BigInteger.valueOf(2));
    38                 X = X.divide(BigInteger.valueOf(2));
    39                 Y = Y.divide(BigInteger.valueOf(2));
    40                 //System.out.println(a[i]+" "+ x[i]+" "+ b[i]+" "+y[i]);
    41             }
    42             boolean flag = false;
    43             for(int k = 0;k <= n;k++)
    44             {
    45                 x[n] = x[0];
    46                 for(int i = 0;i < n;i++)x[i] = x[i+1];
    47                 y[n] = y[0];
    48                 for(int i = 0;i < n;i++)y[i] = y[i+1];
    49                 boolean ff = true;
    50                 for(int i = 0;i < n;i++)
    51                     if((x[i]^a[i]) != (y[i]^b[i]))
    52                     {
    53                         ff = false;
    54                         break;
    55                     }
    56                 if(ff)
    57                 {
    58                     flag = true;
    59                     break;
    60                 }
    61             }
    62             if(flag)System.out.println("Case "+iCase+": Yes");
    63             else System.out.println("Case "+iCase+": No");
    64             T--;
    65         }
    66     }
    67 
    68 }
  • 相关阅读:
    如何在Root的手机上开启ViewServer,使得HierachyViewer能够连接
    java调用monkeyrunner(亲测绝对可行)
    如何在DOS窗口复制和粘贴命令
    查看当前APP打开的是哪个Activity
    MonkeyRunner之MonkeyRecorder录制回放脚本(亲测可正常运行)
    selenium python2.7安装配置
    常用adb操作命令详解
    Spring整合strus2简单应用总结
    spring整合strus2的Hellowworld
    责任链模式-对象行为型
  • 原文地址:https://www.cnblogs.com/kuangbin/p/3346037.html
Copyright © 2011-2022 走看看