2018山东省赛 H Dominoes ( 搜索 )

题目链接

题意 : 给出一个 n * m 的矩阵,用规格 1 * 2 的多米诺去填充,题目数据保证最后只有一个格子是空白的(即没有被多米诺骨牌覆盖),问你现在通过移动多米诺能够产生多少种不同的状态(空白位置作为状态依据,所以最多只有 n * m 种状态)

 

分析 :

这题看着很吓人,一般来说不会想到直接去搜索

因为要证明若走出环,能不能拓展出更多的状态

这个貌似是不存在的,若空白的地方经过重重移动回到了原点

那么必定不能产生更多的状态了,所以直接搜就行了

至于怎么证明......我没有搜到更好的题解解释,看到了再来填坑吧....

 

#include<bits/stdc++.h>
#define LL long long
#define ULL unsigned long long

#define scs(i) scanf("%s", i)
#define sci(i) scanf("%d", &i)
#define scd(i) scanf("%lf", &i)
#define scl(i) scanf("%lld", &i)
#define scIl(i) scanf("%I64d", &i)
#define scii(i, j) scanf("%d %d", &i, &j)
#define scdd(i, j) scanf("%lf %lf", &i, &j)
#define scll(i, j) scanf("%lld %lld", &i, &j)
#define scIll(i, j) scanf("%I64d %I64d", &i, &j)
#define sciii(i, j, k) scanf("%d %d %d", &i, &j, &k)
#define scddd(i, j, k) scanf("%lf %lf %lf", &i, &j, &k)
#define sclll(i, j, k) scanf("%lld %lld %lld", &i, &j, &k)
#define scIlll(i, j, k) scanf("%I64d %I64d %I64d", &i, &j, &k)

#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define lowbit(i) (i & (-i))
#define mem(i, j) memset(i, j, sizeof(i))

#define fir first
#define sec second
#define ins(i) insert(i)
#define pb(i) push_back(i)
#define pii pair<int, int>
#define mk(i, j) make_pair(i, j)
#define all(i) i.begin(), i.end()
#define pll pair<long long, long long>
using namespace std;
const int maxn = 1e4 + 10;
const int dr[] = {0, 0, -1, 1};
const int dc[] = {-1, 1, 0, 0};
int cnt = 0, n, m, k, G[15][maxn];
set<pii> s;

void PRINT()
{
    for(int i=1; i<=n; i++){
        for(int j=1; j<=m; j++){
            if(G[i][j] == -1) printf("- ");
            else printf("%d ", G[i][j]);
        }puts("");
    }puts("");
}

bool bound(int r, int c)
{ return (r<1 || c<1 || r>n || c>m); }

void DFS(int r, int c)
{
    //PRINT();

    if(s.count(mk(r, c))) return;
    else s.ins(mk(r, c));

    for(int i=0; i<4; i++){
        if(dr[i] == 0){
            int _1 = c + dc[i];
            int _2 = c + 2*dc[i];
            if(bound(r, _1)) continue;
            if(bound(r, _2)) continue;
            if(G[r][_1] == G[r][_2]){
                G[r][_2] = -1;
                G[r][c] = G[r][_1];
                DFS(r, _2);
                G[r][_2] = G[r][_1];
                G[r][c] = -1;
            }
        }else if(dc[i] == 0){
            int _1 = r + dr[i];
            int _2 = r + 2*dr[i];
            if(bound(_1, c)) continue;
            if(bound(_2, c)) continue;
            if(G[_1][c] == G[_2][c]){
                G[_2][c] = -1;
                G[r][c] = G[_1][c];
                DFS(_2, c);
                G[_2][c] = G[_1][c];
                G[r][c] = -1;
            }
        }
    }
}

int main(void)
{
    while(~sciii(n, m, k)){
        mem(G, -1);
        s.clear();
        for(int i=0; i<k; i++){
            int r1, c1;
            int r2, c2;
            scii(r1, c1);
            scii(r2, c2);
            G[r1][c1] = cnt;
            G[r2][c2] = cnt++;
        }

        int st_r, st_c, Find = 0;
        for(int i=1; i<=n; i++){
            for(int j=1; j<=m; j++)
                if(G[i][j] == -1){
                    st_r = i;
                    st_c = j;
                    Find = 1;
                    break;
                }
            if(Find) break;
        }

        DFS(st_r, st_c);

        printf("%d\n", s.size()-1);
    }
    return 0;
}
View Code

 

posted @ 2018-05-22 22:28  qwerity  阅读(163)  评论(0编辑  收藏  举报