【Gray格雷碼】

來源:互聯網
上載者:User

Gray碼(轉自M67大牛)

Gray碼
     假如我有4個潛在的GF,我需要決定最終到底和誰在一起。一個簡單的辦法就是,依次和每個MM交往一段時間,最後選擇給我帶來的“滿意度”最大的MM。但看了dd牛的理論後,事情開始變得複雜了:我可以選擇和多個MM在一起。這樣,需要考核的狀態變成了2^4=16種(當然包括0000這一狀態,因為我有可能是玻璃)。現在的問題就是,我應該用什麼順序來遍曆這16種狀態呢?
     傳統的做法是,用位元的順序來遍曆所有可能的組合。也就是說,我需要以0000->0001->0010->0011->0100->...->1111這樣的順序對每種狀態進行測試。這個順序很不科學,很多時候狀態的轉移都很耗時。比如從0111到1000時我需要暫時甩掉當前所有的3個MM,然後去把第4個MM。同時改變所有MM與我的關係是一件何等巨大的工程啊。因此,我希望知道,是否有一種方法可以使得,從沒有MM這一狀態出發,每次只改變我和一個MM的關係(追或者甩),15次操作後恰好遍曆完所有可能的組合(最終狀態不一定是1111)。大家自己先試一試看行不行。
     解決這個問題的方法很巧妙。我們來說明,假如我們已經知道了n=2時的合法遍曆順序,我們如何得到n=3的遍曆順序。顯然,n=2的遍曆順序如下:

00
01
11
10

     你可能已經想到了如何把上面的遍曆順序擴充到n=3的情況。n=3時一共有8種狀態,其中前面4個把n=2的遍曆順序照搬下來,然後把它們對稱翻折下去並在最前面加上1作為後面4個狀態:

000
001
011
010   ↑
--------
110   ↓
111
101
100

     用這種方法得到的遍曆順序顯然符合要求。首先,上面8個狀態恰好是n=3時的所有8種組合,因為它們是在n=2的全部四種組合的基礎上考慮選不選第3個元素所得到的。然後我們看到,後面一半的狀態應該和前面一半一樣滿足“相鄰狀態間僅一位不同”的限制,而“鏡面”處則是最前面那一位元不同。再次翻折三階遍曆順序,我們就得到了剛才的問題的答案:

0000
0001
0011
0010
0110
0111
0101
0100
1100
1101
1111
1110
1010
1011
1001
1000

     這種遍曆順序作為一種編碼方式存在,叫做Gray碼(寫個中文讓蜘蛛來抓:格雷碼)。它的應用範圍很廣。比如,n階的Gray碼相當於在n維立方體上的Hamilton迴路,因為沿著立方體上的邊走一步,n維座標中只會有一個值改變。再比如,Gray碼和Hanoi塔問題等價。Gray碼改變的是第幾個數,Hanoi塔就該移動哪個盤子。比如,3階的Gray碼每次改變的元素所在位置依次為1-2-1-3-1-2-1,這正好是3階Hanoi塔每次移動盤子編號。如果我們可以快速求出Gray碼的第n個數是多少,我們就可以輸出任意步數後Hanoi塔的移動步驟。現在我告訴你,Gray碼的第n個數(從0算起)是n
xor (n shr 1),你能想出來這是為什麼嗎?先自己想想吧。

     下面我們把位元和Gray碼都寫在下面,可以看到左邊的數異或自身右移的結果就等於右邊的數。

位元   Gray碼
   000       000
   001       001
   010       011
   011       010
   100       110
   101       111
   110       101
   111       100

     從位元的角度看,“鏡像”位置上的數即是對原數進行not運算後的結果。比如,第3個數010和倒數第3個數101的每一位都正好相反。假設這兩個數分別為x和y,那麼x xor (x shr 1)和y xor (y shr 1)的結果只有一點不同:後者的首位是1,前者的首位是0。而這正好是Gray碼的產生方法。這就說明了,Gray碼的第n個數確實是n xor (n shr
1)。

     今年四月份mashuo給我看了這道題,是二維意義上的Gray碼。題目大意是說,把0到2^(n+m)-1的數寫成2^n
* 2^m的矩陣,使得位置相鄰兩數的二進位表示只有一位之差。答案其實很簡單,所有數都是由m位的Gray碼和n位Gray碼拼接而成,需要用左移操作和or運算完成。完整的代碼如下:
var
   x,y,m,n,u:longint;
begin
   readln(m,n);
   for x:=0 to 1 shl m-1 do begin
       u:=(x xor (x shr 1)) shl n; //輸出數的左邊是一個m位的Gray碼
       for y:=0 to 1 shl n-1 do
         write(u or (y xor (y shr 1)),' '); //並上一個n位Gray碼
       writeln;
   end;
end.

PS:

一般的,普通二進位碼與格雷碼可以按以下方法互相轉換:

二進位碼->格雷碼(編碼):從最右邊一位起,依次將每一位與左邊一位異或(XOR),作為對應格雷碼該位的值,最左邊一位不變(相當於左邊是0);

格雷碼->二進位碼(解碼):從左邊第二位起,將每位與左邊一位解碼後的值異或,作為該位解碼後的值(最左邊一位依然不變)。

ZOJ 2531是典型的Gray碼http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1533

int toGray(int x){//轉化為格雷碼    return x^(x>>1);}int toBinary(int x){//格雷碼轉化為二進位    int y = x;    while(x>>=1){        y ^= x;    }    return y;}int main(){    int n,m;    while(scanf("%d%d",&n,&m)&&(n+m)){        int i,j;        int beg = toBinary(m);        for(i=beg;i<n;i++){            printf("%d ",toGray(i));        }        for(i=0;i<beg;i++){            printf("%d ",toGray(i));        }        puts("");    }    return 0;}

POJ 1832http://poj.org/problem?id=1832 需要用到大整數

import java.io.*;import java.math.*;import java.util.*;public class Main{static BigInteger[] base = new BigInteger[130];static void  init(){int i,j;base[0] = BigInteger.ONE;for(i=1;i<128;i++){base[i] = base[i-1].multiply(BigInteger.valueOf(2));}}public static void main(String args[]){init();int t;Scanner cin = new Scanner(System.in);t = cin.nextInt();int[] a = new int[130];int[] b = new int[130];while((t--)!=0){int i,j;int n = cin.nextInt();a[0] = cin.nextInt();for(i=1;i<n;i++){a[i] = cin.nextInt();a[i] = a[i]^a[i-1];}b[0] = cin.nextInt();for(i=1;i<n;i++){b[i] = cin.nextInt();b[i] = b[i]^b[i-1];}BigInteger aa = BigInteger.valueOf(0);BigInteger bb = BigInteger.valueOf(0);for(i=0;i<n;i++){aa = aa.add(base[i].multiply(BigInteger.valueOf(a[n-i-1])));bb = bb.add(base[i].multiply(BigInteger.valueOf(b[n-i-1])));}BigInteger ans = bb.subtract(aa).abs();System.out.println(ans);}}}

  











聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.