NOIP 2004 蟲食算 深搜 剪枝

2021-10-07 23:23:27 字數 2756 閱讀 2735

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

43#9865#045

+8468#6633

44445509678

其中 # 號代表被蟲子啃掉的數字。根據算式,我們很容易判斷:第一行的兩個數字分別是 5 和 3,第二行的數字是 5。

現在,我們對問題做兩個限制:

首先,我們只考慮加法的蟲食算。這裡的加法是 n 進製加法,算式中三個數都有 n 位,允許有前導的 0。

其次,蟲子把所有的數都啃光了,我們只知道哪些數字是相同的,我們將相同的數字用相同的字母表示,不同的數字用不同的字母表示。如果這個算式是 n 進製的,我們就取英文本母表的前 n 個大寫字母來表示這個算式中的 0 到 n - 1 這 n 個不同的數字:但是這 n 個字母並不一定順序地代表 0 到 n-1。輸入資料保證 n 個字母分別至少出現一次。

badc

+cbda

dccc

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

輸入的第一行是乙個整數 n,代表進製數。

第二到第四行,每行有乙個由大寫字母組成的字串,分別代表兩個加數以及和。這 33 個字串左右兩端都沒有空格,從左到右依次代表從高位到低位,並且恰好有 n 位。

輸出一行 n 個用空格隔開的整數,分別代表 a,b,… 代表的數字。

輸入輸出樣例

輸入

5

abced

bdace

ebbaa

輸出

103

42

說明/提示

資料規模與約定

對於 30% 的資料,保證 n≤10;

對於 50% 的資料,保證 n≤15;

對於 100% 的資料,保證 1≤n≤26。

p1092 蟲食算 luogu

聽說這道題的正解是高斯消元,但我不會,所以這裡提供一種深搜+剪枝的方法。

難點1:n進製加法。接觸可能較少,一般接觸的都是十進位制,所以說一些加減過程可能會比十進位制稍困難,不過也挺簡單,把十進位制的滿十進一改為滿n進一,總的來說就是把所有十換成n即可。

難點2:怎麼剪枝?通過分析,可以分析出:1.如果後面的沒進製的話那麼會有:(加數1的第k位 + 加數二的第k位) mod n = 和的第k位。2.如果後面的進製了也會有:加數(加數1的第k位 + 加數二的第k位 + 1) mod n = 和的第k位。所以我們只需判斷如果有一位k,加數(加數1的第k位 + 加數二的第k位) mod n 與加數(加數1的第k位 + 加數二的第k位 + 1) mod n 都不等於和的第k位,那麼這樣的情況是不合法的,只需剪掉這樣的情況即可。

這裡給出剪枝**:

boolpd(

)return

true

;}

難點3:怎麼判斷答案合不合法?這乙個步驟不難,當已將搜尋完了n個字母後,將每乙個加數與和求出,判斷是否相等即可。

給出**,略過:

bool

check()

return ans1 + ans2 == ans3;

}

簡單理一下,現將字元轉化成數字儲存下來,再用乙個陣列儲存,以方便深搜,與處理好後開始深搜,按照字母個數深搜,在中間設乙個剪枝,減去不合適的,讓後列舉字元,判斷是否出現過,如果沒出現過便向下搜,直到搜到有答案,並且答案正確為止。

#include

#include

#include

using

namespace std;

const

int maxn =30;

int n,num;

int a[maxn]

,b[maxn]

,c[maxn]

,vis[maxn]

,ne[maxn]

,ans[maxn]

;char s1[maxn]

,s2[maxn]

,s3[maxn]

;void

get(

int x)

}bool

check()

return ans1 + ans2 == ans3;

}boolpd(

)return

true;}

void

dfs(

int x)

return;}

if(!pd

())return

;for

(int i = n -

1;i >=

0;i --)}

return;}

intmain()

for(

int i = n;i >=

1;i --

)memset

(ans,-1

,sizeof

(ans));

for(

int i = n;i >=

0;i --

) vis[i]=0

;dfs(1

);//開搜

return0;

}

NOIP2004 蟲食算 搜尋

問題描述 所謂蟲食算,就是原先的算式中有一部分被蟲子啃掉了,需要我們根據剩下的數字來判定被啃掉的字母。來看乙個簡單的例子 43 9865 045 8468 6633 44445506978 其中 號代表被蟲子啃掉的數字。根據算式,我們很容易判斷 第一行的兩個數字分別是5和3,第二行的數字是5。現在,...

noip2004蟲食算 搜尋

首先這題標算據說是高斯消元,但標籤已經是搜尋了。身為蒟蒻當然只會打搜尋。而我的搜尋又打的很翔,從右到左dfs搜過來,暴枚這一列三個數的情況,然後進製。注意列舉從大到小枚,因為第一位 最左邊 不會進製,所以從右到左時從大到小會更好,不然會被卡tle乙個點。luogu judger enable o2 ...

NOIP2004 蟲食算C 預處理剪枝

總時間限制 1000ms 記憶體限制 65536kb 題目 描述所謂蟲食算,就是原先的算式中有一部分被蟲子啃掉了,需要我們根據剩下的數字來判定被啃掉的字母。來看乙個簡單的例子 43 98650 45 8468 6633 44445506978 其中 號代表被蟲子啃掉的數字。根據算式,我們很容易判斷 ...