luogu P1074 靶形數獨

2021-10-03 14:36:17 字數 2726 閱讀 3271

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

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

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

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

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

輸入格式:

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

輸出格式:

輸出共 11 行。輸出可以得到的靶形數獨的最高分數。如果這個數獨無解,則輸出整數 -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
【資料範圍】

40%的資料,數獨中非 00 數的個數不少於 3030 。

80%的資料,數獨中非 00 數的個數不少於 2626 。

100%的資料,數獨中非 00 數的個數不少於 2424 。

noip 2009 提高組 第四題

這題主要是要快速地判斷出是否是數獨,這裡我設定了3個陣列,usedx[n][i]用於判斷第n列的i是否出現過,usedy[n][i]判斷第n行的i是否出現過,block[y][x][i]判斷某個3*3的小方塊中i是否出現過。前面兩個陣列應該很好理解,這裡就說一下block陣列的判斷過程。因為這些方塊都是相鄰的,所以我們只需要除上乙個數,使得它們都為同乙個值,就能確定唯一的陣列來儲存它們,這裡通過block[(y-1)/3][(x-1)/3][i]完成

1 #include"

iostream"2

using

namespace

std;

3int map[11][11],usedx[11][11],usedy[11][11],block[5][5][10],max1 = -1

,sum;

4void

show()

10 cout<

12}13void dfs(int y,int

x)21 sum -= (map[i][i] + map[10 - i][10 - i] + map[10 - i][i] + map[i][10 - i])* (i + 5

);22

}23 sum += (map[5][5] * 10

);24

if(max1 < sum)

27return;28

}29if(x == 10)

33if(map[y][x])

37for(int i = 9;i >= 1;i--)49}

50}51int

main()60}

61}62for(int i = 0;i <= 10;i++)

68 dfs(1,1

);69 cout<

70return0;

71 }

Luogu P1074 靶形數獨

include using namespace std struct consult row 0 struct consult row 0 dic row 0 10 查詢第幾行有幾個0 int origin 10 10 輸入的數獨 bool row 10 10 column 10 10 box 10...

luogu P1074 靶形數獨

比較基礎的搜尋剪枝題。幾個優化就可以過了 用lowbit代替查詢可以填的數 用並集來維護什麼數不能填 優先考慮 最小可能性的位置 講道理我用堆維護還t了。然後就可以在 m n是數獨大小,m是可以填的種類數量 解決 實際測試中,遠遠不到這個上界 include using namespace std ...

luoguP1074 靶形數獨(搜尋)

傳送門 75分,太菜,不會優化了,吐了。幾點優化。1.先搜尋容易確定的位置 2.從中心往周圍搜 3.列舉數字的時候倒序列舉 4.如果沒有列舉到的數字都是最優情況的話也不能比當前ans大就剪枝 5.位運算 include include include define max x,y x y x y d...