1. 程式人生 > >【高斯消元】[NOIP2004]蟲食算 —— 正解

【高斯消元】[NOIP2004]蟲食算 —— 正解

題目描述:所謂蟲食算,就是原先的算式中有一部分被蟲子啃掉了,需要我們根據剩下的數字來判定被啃掉的字母。來看一個簡單的例子:

+43a9865a045008468a663344445506978
其中a號代表被蟲子啃掉的數字。
根據算式,我們很容易判斷:第一行的兩個數字分別是5和3,第二行的數字是5。
現在,我們對問題做兩個限制:
首先,我們只考慮加法的蟲食算。這裡的加法是N進位制加法,算式中三個數都有N位,允許有前導的0。
其次,蟲子把所有的數都啃光了,我們只知道哪些數字是相同的,我們將相同的數字用相同的字母表示,不同的數字用不同的字母表示。
如果這個算式是N進位制的,我們就取英文字母表午的前N個大寫字母來表示這個算式中的0到N-1這N個不同的數字:但是這N個字母並不一定順序地代表0到N-1)。
輸入資料保證N個字母分別至少出現一次。     +
BADCCBDADCCC

上面的算式是一個4進位制的算式。很顯然,我們只要讓ABCD分別代表0123,便可以讓這個式子成立了。
你的任務是,對於給定的N進位制加法算式,求出N個不同的字母分別代表的數字,使得該加法算式成立。輸入資料保證有且僅有一組解。

樣例輸入:
5
ABCED
BDACE
EBBAA

樣例輸出:
1 0 3 4 2

【資料規模】

對於30%的資料,保證有N≤10;
對於50%的資料,保證有N≤15;
對於全部的資料,保證有N≤26。

下面題解開始
如果我們直接暴搜顯然是不行的複雜度有O(nn)。。。。
那麼我們可以發現因為有n列那麼,那麼我們可以發現令第一行第i

個為xi,第二行第i個為yi, 第三行為zi

+xiyizi
然後對於每一列我們可以得到一個方程我們令di表示第i列向第i1列進位的數量di在0和1之間那麼我們對於任意一列可以發現(這裡的n表示進位制和字母數量)xi+yi+di+1=zi+ndi化簡可以得到xi+yizi=ndidi+1
那麼我們現在列出來的矩陣就是長得這個樣子(樣例的矩陣)10111101000011001001100115000015000015000015000015矩陣右邊部分的第i列表示的是我們的當前需要的di的數量,那麼現在的我們需要通過列舉不同的di來獲取不同的矩陣又因為我們的d
i
只能是0或者1同時我們的d1(也就是最高位)顯然沒有進位那麼我們需要列舉的di就有n1個那麼複雜度就是O(2n1n3)那麼顯然不能勝任本題目看到我們的這個矩陣,仔細觀察一下既然我們左邊的所有係數專案已經知道了那麼我們為什麼不把它先給用高斯約當消元法消元之後再看我們另消元之後得到的每一個係數為Ki右邊變成了Gi,j那麼我們上面的矩陣就變成了