连环锁 格雷码知识+大数
题目抽象:某个格雷码到另一个格雷码最少需要的转换步数。
思路:直接求出对应得十进制,相减取绝对值。
当n=2时变换的序列为00,01,11,10
当n=3时变换的序列为000,001,011,010,110,111,101,100
……
仔细观察发现这正是格雷码,相邻两个状态只有一位不同(实际上题目描述已经说了这个条件)!
十进制数 |
自然二进制数 |
格雷码 |
0 |
0000 |
0000 |
1 |
0001 |
0001 |
2 |
0010 |
0011 |
3 |
0011 |
0010 |
4 |
0100 |
0110 |
5 |
0101 |
0111 |
6 |
0110 |
0101 |
7 |
0111 |
0100 |
8 |
1000 |
1100 |
9 |
1001 |
1101 |
10 |
1010 |
1111 |
11 |
1011 |
1110 |
12 |
1100 |
1010 |
13 |
1101 |
1011 |
14 |
1110 |
1001 |
15 |
1111 |
1000 |
ps:
一般的,普通二进制码与格雷码可以按以下方法互相转换:
二进制码->格雷码(编码):从最右边一位起,依次将每一位与左边一位异或(XOR),作为对应格雷码该位的值,最左边一位不变(相当于左边是0);
格雷码->二进制码(解码):从左边第二位起,将每位与左边一位解码后的值异或,作为该位解码后的值(最左边一位依然不变)。
1 import java.io.*; 2 import java.math.*; 3 import java.util.*; 4 5 class Main 6 { 7 public static int MS=128; 8 public static BigInteger[] base=new BigInteger[MS]; 9 public static void init() 10 { 11 base[0]=BigInteger.ONE; 12 for(int i=1;i<128;i++) 13 base[i]=base[i-1].multiply(BigInteger.valueOf(2)); 14 } 15 public static void main(String[] args) 16 { 17 Scanner cin=new Scanner(new BufferedInputStream(System.in)); 18 init(); 19 int T=cin.nextInt(); 20 int n; 21 int[] a=new int[MS]; 22 int[] b=new int[MS]; 23 while(T-->0) 24 { 25 n=cin.nextInt(); 26 for(int i=0;i<n;i++) 27 { 28 a[i]=cin.nextInt(); 29 if(i!=0) 30 a[i]=a[i-1]^a[i]; 31 } 32 for(int i=0;i<n;i++) 33 { 34 b[i]=cin.nextInt(); 35 if(i!=0) 36 b[i]=b[i-1]^b[i]; 37 } 38 BigInteger s=BigInteger.ZERO; 39 BigInteger t=BigInteger.ZERO; 40 for(int i=0;i<n;i++) 41 { 42 if(a[n-1-i]!=0) 43 s=s.add(base[i]); 44 if(b[n-1-i]!=0) 45 t=t.add(base[i]); 46 } 47 System.out.println(t.max(s).subtract(t.min(s))); 48 } 49 cin.close(); 50 } 51 }
什么?我的程序有问题,快拿键盘给我!