zoukankan      html  css  js  c++  java
  • hdu 4759 大数+找规律 ***

    题目意思很简单。

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

    总共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

      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     #ifndef ONLINE_JUDGE
    316     freopen("1.in","r",stdin);
    317     #endif
    318     scanf("%d",&T);
    319     while(T--)
    320     {
    321         iCase++;
    322         scanf("%d",&n);
    323         cin>>A>>X>>B>>Y;
    324         printf("Case %d: ",iCase) ;
    325         A = A-1;
    326         X = X-1;
    327         B = B-1;
    328         Y = Y-1;
    329         for(int i = 0;i < n;i++)
    330         {
    331             if(A.a[0]%2 == 0)a[i] = 0;
    332             else a[i] = 1;
    333             if(B.a[0]%2 == 0)b[i] = 0;
    334             else b[i] = 1;
    335             if(X.a[0]%2 == 0)x[i] = 0;
    336             else x[i] = 1;
    337             if(Y.a[0]%2 == 0)y[i] = 0;
    338             else y[i] = 1;
    339             A = A/2;
    340             B = B/2;
    341             X = X/2;
    342             Y = Y/2;
    343         }
    344         bool flag = false;
    345         for(int k = 0;k <= n;k++)
    346         {
    347             x[n] = x[0];
    348             y[n] = y[0];
    349             for(int i = 0;i < n;i++)
    350             {
    351                 x[i] = x[i+1];
    352                 y[i] = y[i+1];
    353             }
    354             for(int i = 0;i < n;i++)
    355             {
    356                 if(a[i] == x[i])c[i] = 0;
    357                 else c[i] = 1;
    358             }
    359             bool fff = true;
    360             for(int i = 0;i < n;i++)
    361                 if(b[i]^c[i] != y[i])
    362                 {
    363                     fff = false;
    364                     break;
    365                 }
    366             if(fff)flag = true;
    367             if(flag)break;
    368 
    369         }
    370         if(flag)printf("Yes
    ");
    371         else printf("No
    ");
    372     }
    373     return 0;
    374 }
  • 相关阅读:
    P3723 【[AH2017/HNOI2017]礼物】
    P4555 【[国家集训队]最长双回文串】
    manacher学习笔记
    多项式学习笔记
    题解 CF1097F 【Alex and a TV Show】
    docker数据卷容器
    python基础学习
    docker监控之cadvisor
    docker监控系统
    ssh配置详解及公私钥批量分发
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4780173.html
Copyright © 2011-2022 走看看