HDU 5965 扫雷(dfs)题解

题意:给你一个3*n的格子,中间那行表明的是周围8格(当然左右都没有)的炸弹数量,上下两行都可以放炸弹,问你有几种可能,对mod取模

思路:显然(不),当i - 1和i - 2确定时,那么i的个数一定确定,显然,只要第一列确定,后面全确定了,那么就3种可能,只要遍历到最后,最后一个符合num[n] = pre[n - 1] + pre[n]那么就说明这样排可行。复杂度O(3*n)。

#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
typedef long long ll;
using namespace std;
const int maxn = 10000 + 10;
const int seed = 131;
const ll MOD = 100000007;
const int INF = 0x3f3f3f3f;
int t, n;
char a[maxn];
int num[maxn];
ll ans;
void dfs(int id, int pre, int prepre, ll p){
    if(id == n + 1){
        if(num[id - 1] == pre + prepre) ans += p;
        return;
    }
    if(id == 1){
        dfs(id + 1, 0, 0, 1);
        if(num[id] >= 1) dfs(id + 1, 1, 0, 2);
        if(num[id] >= 2) dfs(id + 1, 2, 0, 1);
    }
    else{
        int now = num[id - 1] - prepre - pre;
        if(now < 0 || now > 2) return;
        ll pp;
        if(now == 1) pp = p * 2LL % MOD;
        else pp = p;
        dfs(id + 1, now, pre, pp);
    }
}
int main(){
    scanf("%d", &t);
    while(t--){
        scanf("%s", a);
        n = 0;
        while(a[n] != '\0'){
            num[n + 1] = a[n] - '0';
            n++;
        }
        ans = 0;
        dfs(1, 0, 0, 1);
        printf("%lld\n", ans);
    }
    return 0;
}

 

posted @ 2018-12-02 23:11  KirinSB  阅读(230)  评论(0编辑  收藏  举报