Hdu 5965 扫雷

Hdu 5965 扫雷(dfs)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5965
在这里插入图片描述
解题思路:用num数组记录样例给出的数字,用dp数组记录每位的地雷数量,通过给出的第一位数字来枚举第一位可能的地雷数,然后第二位的地雷数就能确定了,一定是num[0]-dp[0],(0为第一位的下标),因为扫雷标记的数字只会是8方向的格子,但是第一位影响的到的只有自己这格子和右边这个格子,那么第一位的地雷数确定了,第二位的地雷数也就能确定了,(枚举中会出现不合法的情况,即地雷数不在0到2直接,直接跳出就行,最后一位也要判断一下地雷数对不对),之后的每一位就受到前两位的影响,就是前两位确定了地雷数,在拿前一位的num值减去就是地雷数,如果推到底了都没问题,就开始计数(用初值为1的res表示),而每一位的地雷摆放,只有当他数量为一的时候能有两种可能,即上或者下,(遇到1的情况res*2%mod即可(注意:mod为1e8+7)),算完res,给sum加上res在取模即可。
代码如下:

#include <bits/stdc++.h>
using namespace std;
#define MAXN 10005
char c[MAXN];
int num[MAXN];
typedef long long ll;
const ll mod=1e8+7;
ll dp[MAXN],sum;
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%s",c);
        int n=strlen(c);
        for(int i=0;i<n;i++){
            num[i]=c[i]-'0';
        }
        sum=0;
        for(int i=0;i<=num[0]&&i<=2;i++){//枚举dp[0]的可能性
            dp[0]=i;
            dp[1]=num[0]-dp[0];//第一位的地雷数会等于数字和第0位地雷数之差,因为第零位数字剩下的只能在第一位
            if(dp[1]>2||dp[1]<0)continue;//判断合不合法,地雷数一定在0到2之间
            bool flag=true;
            for(int j=2;j<n;j++){
                dp[j]=num[j-1]-dp[j-1]-dp[j-2];
                if(dp[j]>2||dp[j]<0){//不可能的地雷数
                    flag=false;
                    break;
                }
            }
            if(dp[n-2]+dp[n-1]!=num[n-1]){//最后的地雷数不对,那就不是答案
                flag=false;
            }
            if(flag){
                ll res=1;
                for(int j=0;j<n;j++){
                    if(dp[j]==1)res=(res*2)%mod;//只有地雷数为1时才有摆放的可能,0和2都只有固定位置
                }
                sum=(sum+res)%mod;
            }
        }
        printf("%lld\n",sum);
    }
    return 0;
}
发布了35 篇原创文章 · 获赞 3 · 访问量 887

猜你喜欢

转载自blog.csdn.net/weixin_43823753/article/details/104618012