TIOJ::1264 . 保加利亞的色彩繽紛

http://tioj.ck.tp.edu.tw/problems/1264

怪怪規律題。給你一個棋盤,問你把某些格子塗黑,讓所有格子都符合四個相鄰的格子恰有一個被塗黑,總共有幾種方法(不可能就是0)。

完全想不通,手邊又沒有紙筆,有一天一定要買個手寫板或是搞個方便在電腦上用的計算紙…。
可以看CBD的作法,可是我看了別人的code,CBD的作法好像也不是最完整的,還有更漂亮的規律,總之決定幾個格子之後,其他格子的塗法就確定了,先亂爆搜後發現解好像只會有0,1,2,4四種。

然後,既然解這麼少種,爆搜檢個枝基本上應該會過,所以就爆搜,然後就AC了XDD。

越來越覺得與其花很多時間找規律不如先寫爆搜喇分,比賽才會高分,找證明和規律是數學家的事情,資訊就應該要爆搜嘛~~~~(不過剪枝也是要找規律啦XD)

規律大概就是,前兩格是黑的這個一定不可以是黑的、上面那一格要是不符合規定那就不用搜下去了之類的,最後要檢查最後一排有沒有符合規定

其實看這題數字詭異的範圍(0<k<32),我覺得原題本來就是要給人爆搜的嘛~~~。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <bits/stdc++.h>
#define F(n) Fi(i,n)
#define Fi(i,n) Fl(i,0,n)
#define Fl(i,l,n) for(int i=l;i<n;i++)
using namespace std;
const int N = 501, M = 33;
int n,k,ans;
bool D[N][M];
bool check(int x,int y){
if(x<0||y<0||x>=n||y>=k)return true;
int tmp = 0;
if(x>0)tmp += D[x-1][y];
if(y>0)tmp += D[x][y-1];
if(x<n-1)tmp += D[x+1][y];
if(y<k-1)tmp += D[x][y+1];
return tmp == 1;
}
int DFS(int x,int y){
if(x==n){
F(k)if(!check(x-1,i))return 0;
return ans++;
}
if(y==k){
// cout<<"DD "<<x<<endl;
return DFS(x+1,0);
}
if(check(x-1,y))DFS(x,y+1);
D[x][y] = true;
if(check(x-1,y)&&(y<2||!D[x][y-2]))DFS(x,y+1);
D[x][y] = false;
return 0;
}
main(){
ios_base::sync_with_stdio(false);
cin.tie(0);
while(cin>>n>>k){
ans = 0;
DFS(0,0);
cout<<ans<<endl;
}
}