2016 ccpc 合肥 HDU5965 扫雷

扫雷

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 985    Accepted Submission(s): 154


Problem Description
扫雷游戏是晨晨和小璐特别喜欢的智力游戏,她俩最近沉迷其中无法自拔。
该游戏的界面是一个矩阵,矩阵中有些格子中有一个地雷,其余格子中没有地雷。 游戏中,格子可能处于己知和未知的状态。如果一个己知的格子中没有地雷,那么该 格子上会写有一个一位数,表示与这个格子八连通相邻的格子中地雷总的数量。
现在,晨晨和小璐在一个3行N列(均从1开始用连续正整数编号)的矩阵中进 行游戏,在这个矩阵中,第2行的格子全部是己知的,并且其中均没有地雷;而另外 两行中是未知的,并且其中的地雷总数量也是未知的。
晨晨和小璐想知道,第1行和第3行有多少种合法的埋放地雷的方案。
 

Input
包含多组测试数据,第一行一个正整数T,表示数据组数。
每组数据由一行仅由数字组成的长度为N的非空字符串组成,表示矩阵有3行N 列,字符串的第i个数字字符表示矩阵中第2行第i个格子中的数字。
保证字符串长度N <= 10000,数据组数<= 100。
 

Output
每行仅一个数字,表示安放地雷的方案数mod100,000,007的结果。
 

Sample Input
  
  
2 22 000
 

Sample Output
  
  
6 1

题目大意:


如题。


思路:


一开始想着如果我们固定第一列放 0  或者 1 或者   2  个雷的话,那么我们就能知道第二列雷的数量,然后我们就能知道第三列雷的数量。

可是我 突然一想,万一这个雷这样放不合适怎么办?  然后就卡住了。。。。就卡住了。。。

后来就想着对于这些雷的状态进行  dp  吧。 我就假设  dp [ i ] [ k ] 是 第 i 列放 k 颗雷 的方案数。

那么我们的状态转移方程如何写那?

dp [ i + 1 ] [ k ] = dp [ i -1 ] [ t ] + dp [ i -2 ] [ v ] ;

并且 k + t + v = 第 i 列的那个数字。

t k v 都要小于 等于 2     已经验证 这种思想是错误的。

因为 状态重复计算了。


AC代码L

#include<bits/stdc++.h>
using namespace  std;
char ss[10005];
int dp[10005];
int a[10005];
int main()
{
    int n;
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%s",ss);
        n=strlen(ss);
        for(int i=0;i<n;i++)
        {
            a[i+1]=ss[i]-'0';
        }
        dp[0]=0;
        int work;
        int tt;
        long long int ans=1;
        long long int fans=0;
        for(int i=0;i<=2&&i<=a[1];i++)
        {
            dp[1]=i;
            work=0;
            ans=1;
            for(int j=2;j<=n;j++)
            {
                tt=a[j-1]-(dp[j-1]+dp[j-2]);
                if(tt<0||tt+dp[j-1]>a[j]||tt>2)
                {
                    work=1;
                    break;
                }
                dp[j]=tt;
            }
            if(!work&&dp[n-1]+dp[n]==a[n])
            {
                for(int j=1;j<=n;j++)
                {
                    if(dp[j]==1)
                    {
                        ans*=2;
                    }
                    ans%=100000007;
                }
                fans+=ans;
                fans%=100000007;
            }
        }
        cout<<fans<<endl;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值