NOIP 2009 靶形數獨

2022-05-31 09:30:18 字數 3422 閱讀 8388

小城和小華都是熱愛數學的好學生,最近,他們不約而同地迷上了數獨遊戲,好勝的他們想用數獨來一比高低。但普通的數獨對他們來說都過於簡單了,於是他們向 z 博士請教,z 博士拿出了他最近發明的「靶形數獨」,作為這兩個孩子比試的題目。

靶形數獨的方格同普通數獨一樣,在 9格寬× 9 格高的大九宮格中有 9 個 3 格寬× 3 格高的小九宮格(用粗黑色線隔開的)。在這個大九宮格中,有一些數字是已知的,根據這些數字,利用邏輯推理,在其他的空格上填入 1 到 9 的數字。每個數字在每個小九宮格內不能重複出現,每個數字在每行、每列也不能重複出現。但靶形數獨有一點和普通數獨不同,即每乙個方格都有乙個分值,而且如同乙個靶子一樣,離中心越近則分值越高。(如圖)

上圖具體的分值分布是:最裡面一格(黃色區域)為 10分,黃色區域外面的一圈(紅色區域)每個格仔為 9分,再外面一圈(藍色區域)每個格仔為 8 分,藍色區域外面一圈(棕色區域)每個格仔為 7分,最外面一圈(白色區域)每個格仔為 6分,如上圖所示。比賽的要求是:每個人必須完成乙個給定的數獨(每個給定數獨可能有不同的填法),而且要爭取更高的總分數。而這個總分數即每個方格上的分值和完成這個數獨時填在相應格上的數字的乘積的總和

總分數即每個方格上的分值和完成這個數獨時填在相應格上的數字的乘積的總和。如圖,在以下的這個已經填完數字的靶形數獨遊戲中,總分數為 2829。遊戲規定,將以總分數的高低決出勝負。

由於求勝心切,小城找到了善於程式設計的你,讓你幫他求出,對於給定的靶形數獨,能夠得到的最高分數。

輸入格式:

一共 9行。每行 9個整數(每個數都在 0−9 的範圍內),表示乙個尚未填滿的數獨方格,未填的空格用「 0 」表示。每兩個數字之間用乙個空格隔開。

輸出格式:

輸出共 1行。輸出可以得到的靶形數獨的最高分數。如果這個數獨無解,則輸出整數 −1 。

樣例輸入樣例1: 

7 0 0 9 0 0 0 0 1 

1 0 0 0 0 5 9 0 0

0 0 0 2 0 0 0 8 0

0 0 5 0 2 0 0 0 3

0 0 0 0 0 0 6 4 8

4 1 3 0 0 0 0 0 0

0 0 7 0 0 2 0 9 0

2 0 1 0 6 0 8 0 4

0 8 0 5 0 4 0 1 2

輸出樣例1: 

2829
輸入樣例2:
0 0 0 7 0 2 4 5 3 

9 0 0 0 0 8 0 0 0

7 4 0 0 0 5 0 1 0

1 9 5 0 8 0 0 0 0

0 7 0 0 0 0 0 2 5

0 3 0 5 7 9 1 0 8

0 0 0 6 0 1 0 0 0

0 6 0 9 0 0 0 0 1

0 0 0 0 0 0 0 0 6

輸出樣例2: 

2852
狀態的儲存

數獨類問題比較難的是狀態的儲存,所以我們需要寫一些陣列去儲存狀態。

bool a[10][10]; //a[i][j]判斷i行有沒有j這個數;

bool b[10][10]; //b[i][j]判斷i列有沒有j這個數 ;

bool c[10][10]; //c[i][j]判斷第i個九宮格是否有j這個數;

本題特殊性

對於本題特殊帶有的權值,我們可以用一種極其簡單的方法去解決打表!!

int score[10][10],,,

,,,,

,,,};int gong[10][10],,,

,,,,

,,,};

這樣簡化完程式的複雜性,下面我們要做的就是優化時間;

優化時間

想一下我們平時是如何玩數獨的(雖然我沒有玩過)

我們一定會先去找數已經填很多的地方去填,因為那個位置可以填的數少,選擇的少;

在搜尋中,這樣做可以減少搜尋樹的分支,從而提高效率;

所以我們可以記錄每一行 0 的個數,然後 sort 再儲存搜尋 0 的次序;

最後dfs 更新 ans;即可

code

下面是**實現

1 #include2 #include3 #include4 #include5

using

namespace

std;

6bool a[10][10]; //

a[i][j]判斷i行有沒有j這個數

7bool b[10][10]; //

b[i][j]判斷i列有沒有j這個數

8bool c[10][10]; //

c[i][j]判斷第i個九宮格是否有j這個數910

int score[10][10

],12 ,

13 ,

14 ,

15 ,

16 ,

17 ,

18 ,

19 ,

20 ,

21};

2223

int gong[10][10

],25 ,

26 ,

27 ,

28 ,

29 ,

30 ,

31 ,

32 ,

33 ,

34};

35int map[10][10],s[100][5

]; 36

37int

ans,cnt,w;

38struct

nodezero[10

];41

42bool

cmp(node a,node b)

4546

void dfs(int dep,int

sum)

51for(int i=1;i<=9;i++)61}

62}6364

intmain()

6579

else83}

84 sort(zero+1,zero+10

,cmp);//排序

85for(int i=1;i<=9;i++)92}

93}94 dfs(1

,w);

95if(ans!=0) printf("%d"

,ans);

96else printf("-1"

);97

return0;

98 }

還有什麼不透徹可以隨時詢問。

NOIP2009 靶形數獨

爆搜沒什麼好說的。剪枝思路 一開始將每個點可能取的值的數量統計出,排序,從小到大搜 然後貪心可行性 就是剩下的地方都填9,得分10 不過在vj上測85。日。加了卡時,2e7次之內跳出,總算過了。include include include include include include inclu...

NOIP 2009 靶形數獨

題目描述 小城和小華都是熱愛數學的好學生,最近,他們不約而同地迷上了數獨遊戲,好勝的他們想用數獨來一比高低。但普通的數獨對他們來說都過於簡單了,於是他們向 z 博士請教,z 博士拿出了他最近發明的 靶形數獨 作為這兩個孩子比試的題目。靶形數獨的方格同普通數獨一樣,在 9 格寬 9 格高的大九宮格中有...

noip2009 靶形數獨

靶形數獨 小城和小華都是熱愛數學的好學生,最近,他們不約而同地迷上了數獨遊戲,好勝的他 們想用數獨來一比高低。但普通的數獨對他們來說都過於簡單了,於是他們向 z 博士請教,z 博士拿出了他最近發明的 靶形數獨 作為這兩個孩子比試的題目。靶形數獨的方格同普通數獨一樣,在 9 格寬 9 格高的大九宮格中...