藍橋杯 真題 六角幻方(dfs 剪枝)

2021-09-19 23:01:45 字數 1744 閱讀 9925

把 1 2 3 ... 19 共19個整數排列成六角形狀,如下:

* * *

* * * *

* * * * *

* * * * 

* * *

要求每個直線上的數字之和必須相等。共有15條直線哦!

再給點線索吧!我們預先填好了2個數字,第一行的頭兩個數字是:15 13,參見圖【p1.png】,黃色一行為所求。

請你填寫出中間一行的5個數字。數字間用空格分開。

這是一行用空格分開的整數,請通過瀏覽器提交答案,不要填寫任何多餘的內容(比如說明性的文字等)

解題報告:

好久沒寫搜尋了,,當個練習。

不難發現每一行的值的和應該是38,所以我們已經有了三個已知數字了。

根據對稱性把這三個數放在每一行的開始,相當於有了三個已知行的行首,然後按行dfs,同時判斷是否湊夠了38,如果超了38那就直接return就行,這一點可以用附初始值為比較大的值(這裡用了100000)來實現。如果還沒填滿這一行但是和已經大於38了  或者  都填滿了並且還不是38,那就return。這應該是最優秀的剪枝了,是每一步都會有剪枝。當然如果不這樣剪枝,而是直接: 每一行都填滿了再判斷是否等於38,也可以。

最終答案:

10 12 16

13 4 2 19

15 8 5 7 3

14 6 1 17

9 11 18

ac**:

#include#include#include#include#include#include#include#include#include#include#define f first

#define s second

#define ll long long

#define pb push_back

#define pm make_pair

using namespace std;

typedef pairpii;

const int max = 2e5 + 5;

int a[55][55],all[55] = ;

int up[55] = ;

bool vis[55],ok[55][55];

bool cc()

bool check()

void dfs(int x,int y)

printf("\n");

} return;

} if(check() == 0) return;

if(ok[x][y])

for(int i = 1; i<=19; i++)

} vis[i] = 1;

all[x] += i;

a[x][y] = i;

dfs(x,y+1);

a[x][y] = 100000;

vis[i] = 0;

all[x] -= i;

} }int main()

a[1][1]=10;a[2][1]=13;a[3][1]=15;

ok[1][1]=1;ok[2][1]=1;ok[3][1]=1;

vis[10]=1;vis[13]=1;vis[15]=1;

dfs(1,1);

return 0 ;

}//19:00-19:20

/*10 12 16

13 4 2 19

15 8 5 7 3

14 6 1 17

9 11 18

*/

藍橋杯 六角幻方

把 1 2 3 19 共19個整數排列成六角形狀,如下 要求每個直線上的數字之和必須相等。共有15條直線哦!再給點線索吧!我們預先填好了2個數字,第一行的頭兩個數字是 15 13,參見圖 p1.png 黃色一行為所求。請你填寫出中間一行的5個數字。數字間用空格分開。這是一行用空格分開的整數,請通過瀏...

六角幻方 藍橋試題

把 1 2 3 19 共19個整數排列成六角形狀,如下 要求每個直線上的數字之和必須相等。共有15條直線哦!再給點線索吧!我們預先填好了2個數字,第一行的頭兩個數字是 15 13,參見圖 p1.png 黃色一行為所求。請你填寫出中間一行的5個數字。數字間用空格分開。參 9 6 5 2 16 incl...

六角幻方 題解

把 1 2 3 19 共19個整數排列成六角形狀,如下 要求每個直線上的數字之和必須相等。共有15條直線哦!再給點線索吧!我們預先填好了2個數字,第一行的頭兩個數字是 15 13,參見圖 p1.png 黃色一行為所求。請你填寫出中間一行的5個數字。數字間用空格分開。這是一行用空格分開的整數,請通過瀏...