原題傳送門
不愧是 2009 noip tg t4 ,連續打了4天的**,吸了口氧才通過。
前置知識:
對於一道數獨題,我們可以先預處理出每一行0的個數,然後從個數最少的行開始做,這樣可以節省大量的時間(因為這些格仔可以填的數字少)。
對於本題,我一開始的思路是:仿照前置知識預處理,分數進行打表,存在 poi
nt
point
poin
t 陣列裡面,用下列的三個函式進行填數之後的標記處理(這裡我令 ai,
j,ka_
ai,j,k
為第 (i,
j)
(i,j)
(i,j
) 的格仔能否填數字 k
kk ), dfs 填表時按照行去處理,部分**如下:
//分數打表自動略去
//b陣列是我用來存放數獨的陣列
//以下是預處理**
struct
node
sum[maxn]
;void
getshun()
sort
(sum+
1,sum+9+
1,cmp);}
//獲知應該搜尋的行,將其存在sum結構體中
void
getc()
}}//獲取每乙個點所在的九宮格,nx,ny陣列表示每乙個宮格左上角與右下角的座標,0為左上角,1為右下角
void
deal
(int x,
int y)
//做標記
void
redeal
(int x,
int y)
//恢復現場
//對於每個關鍵陣列和變數的意義在全部**中會詳細給出,想知道的讀者可以先看全部**再返回
結果樣例測完後就發現,這種方法極其不穩定,很容易在 dfs 時序列(這行還沒搜尋完就到下一行),所以我們要想乙個更穩定的方法。
實際上,如果吸口氧前面的預處理已經足夠優秀了,關鍵是如何決定搜尋順序。
行如果不穩定,那麼按列搜???好像差不多
等等,好像除了行和列,還有點吧!!!
所以我決定按點搜。
我在**中新開了乙個陣列(結構體) dfs
rdfsr
dfsr
,用來存放搜點的順序,其中 tmp
tmptm
p 是零點的數量(對上面**中的 get
cgetc
getc
無影響),處理時還是按照 sum
sumsu
m 陣列進行處理,從最少的行開始依次存0點,然後進行搜尋。這樣,吸口氧就能過去了。
注意本題細節問題很多,並且很容易因為按行搜而困住(如果您按行搜過了那您就太厲害了, orz )
全部**如下:
#
include
using
namespace std;
const
int maxn=9+
5;int a[maxn]
[maxn]
[maxn]
,b[maxn]
[maxn]
,c[maxn]
[maxn]
;//b:存放數獨的陣列 a:a[i][j][k]表示(i,j)能否填數字k,c:c[i][j]表明(i,j)所在的宮格
int nx[maxn][2
]=,,
,,,,
,,,}
;int ny[maxn][2
]=,,
,,,,
,,,}
;//nx,ny:nx,ny陣列表示每乙個宮格左上角與右下角的座標,0為左上角,1為右下角
int point[maxn]
[maxn]=,
,,,,
,,,,
};//point:分數的打表
int ans=-1
,tmp;
//ans為答案,初始值為-1可以方便後續答案的統計,tmp是0點的個數
struct
node
sum[maxn]
;//sum:處理行的順序,x=第x行,num=該行0點個數
struct
node2
dfsr[maxn*
100]
;//dfsr:處理0點的搜尋順序
bool
cmp(
const node& fir,
const node& sec)
//對sum陣列按照0點個數公升序排序
void
getshun()
sort
(sum+
1,sum+9+
1,cmp);}
//處理sum陣列
void
getzero()
}}return;}
//處理dfsr陣列
void
getc()
}}//處理c陣列
void
deal
(int x,
int y)
//做標記
void
redeal
(int x,
int y)
//恢復現場
intmax
(int fir,
int sec)
void
getanswer()
ans=
max(ans,getans);}
//獲取ans
void
dfs(
int k)
for(
int i=
1;i<=
9;i++)}
}//按點搜尋,k為第k個0點
intmain()
dfs(1)
;printf
("%d\n"
,ans)
;return0;
}
題解 P1074 靶形數獨
看完所有的題解之後發現沒有人用二進位制,我就知道我的機會來了 手動滑稽 x y 相當於x pow 2,y lowbit x 找到x的二進位制中最小的1的位置1 1 10 1 0 0 0 0 沒有了關於這一題,line,rool,cell三個陣列 均初始化為111111111 二進位制 分別用來存這一...
題解 P1074 靶形數獨
來一篇通俗點的dlx的題解。有關dlx的講解 針對本題的一些細節詳見注釋。code include include includeusing namespace std const int maxn 81 4 5 const int maxnode 9 9 9 4 4 5 const int slo...
P1074 靶形數獨
小城和小華都是熱愛數學的好學生,最近,他們不約而同地迷上了數獨遊戲,好勝的他們想用數獨來一比高低。但普通的數獨對他們來說都過於簡單了,於是他們向 z 博士請教,z 博士拿出了他最近發明的 靶形數獨 作為這兩個孩子比試的題目。靶形數獨的方格同普通數獨一樣,在 999 格寬 999 格高的大九宮格中有 ...