轉站通知

本站已停止更新!!想繼續收看我的新文章的話,請前往我的新Blog - Chino's

2015年11月23日 星期一

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

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

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


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

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

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

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

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

#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;
    }
}

沒有留言:

張貼留言