ZOJ.1009.Enigma

 


#include 
< stdio.h >
#include 
< memory.h >

int  LookUpTable[ 26 * 3 ];
void  inverse(  int  size,  int  src[] )
{
    
static int tmp[26],i;
    
for ( i = 0; i < size ; i++  ) {
        tmp[src[i]] 
= i;
    }

    memcpy(src,tmp,
sizeof(int)*size);
}


void  multiply(  int  size,  int  src0[],  int  src1[],  int  dst[] )
{
    
int i;
    
for ( i = 0 ; i < size; i++ ) {
        dst[i] 
= src1[src0[i]];
    }

}


void  rotate(  int  size , int  rotor[],  int  offset[],  int   *  start)
{
    
int idx,i;
    
// Rotate r1^{-1}
    start[0= (start[0+ size - 1% size;
    idx 
= start[0];
    
for ( i = 0 ; i < size ; i++ ) {
        rotor[i] 
= LookUpTable[i + offset[idx] + size ];
        idx 
= LookUpTable[idx + 1];
    }

}


//  Denote the rotor0, rotor1, rotor2 as r0, r1, r2.

int  main()
{
    
int size,i,j,cnt;
    
int enigmaCnt = 1;
    
int rotor[5][26];
    
char string[26][1001];
    
int flags[26];
    
int listLen;
    
int start,cur;
    
int curChar;
    
int starter[3];
    
int offset[3][26];
    
bool bChange;
    
int counter0,counter1;
    
int sizeSquare;
    
int *pTable;
    
do {
        scanf( 
"%d "&size );
        
if ( !size ) {
            
break;
        }

        
if ( enigmaCnt != 1 ) {
            printf(
" ");
        }


        pTable 
= LookUpTable;
        
for ( j = 0 ; j< 3 ; j++ ) {
            gets(
string[0]);
            
for ( i = 0 ; i < size ; i++ ){
                rotor[j][i] 
=  string[0][i]-'A';
                offset[j][rotor[j][i]] 
= i - rotor[j][i]; 
                
// Init lookup table here.
                *pTable++ = i;
            }

            
// Let l = r0*r1*r2
            
// l^{-1} = r2^{-1}*r1^{-1}*r0^{-1}
            inverse(size,rotor[j]);
        }

        
// r3 = r2^{-1}*r1^{-1}
        multiply(size,rotor[2],rotor[1],rotor[3]);

        scanf( 
"%d "&cnt );
        printf( 
"Enigma %d: ",enigmaCnt++);
        
for ( i = 0; i < cnt - 1; i++ ) {
            
// Init input and linked list.
            gets(string[i]);
            flags[i] 
= i + 1;
        }

        gets(
string[i]);
        flags[i] 
= -1;
        listLen 
= cnt;

        
// Init stage.
        start = curChar = cur = 0;
        bChange 
= false;
        starter[
0= starter[1= starter[2= 0;
        sizeSquare 
= size*size;
        counter0 
= counter1 = 0;

        
do{
            
int last = cur;
            
int thisLen = listLen;
            cur 
= start;
            
// Compute l^{-1} for current stage
            
// r2 changed. 
            if ( 0 == counter1 && curChar ) {
                bChange 
= true;
                rotate(size,rotor[
2],offset[2],starter + 2);
            }


            
// r1 changed.
            if ( 0 == counter0 && curChar  ) {
                bChange 
= true;
                rotate(size,rotor[
1],offset[1],starter + 1);
            }

            
            
if ( bChange ) {
                bChange 
= false;
                multiply(size,rotor[
2],rotor[1],rotor[3]);
            }


            multiply(size,rotor[
3],rotor[0],rotor[4]);

            
for ( i = 0 ; i < thisLen; i ++ ) {
                
// When current string is processed, delete it from list.

 

                 if  (  '
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值