zoukankan      html  css  js  c++  java
  • HDU 5965 扫雷

    扫雷游戏是晨晨和小璐特别喜欢的智力游戏,她俩最近沉迷其中无法自拔。 

    该游戏的界面是一个矩阵,矩阵中有些格子中有一个地雷,其余格子中没有地雷。 游戏中,格子可能处于己知和未知的状态。如果一个己知的格子中没有地雷,那么该 格子上会写有一个一位数,表示与这个格子八连通相邻的格子中地雷总的数量。 
    现在,晨晨和小璐在一个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,则不合法,方案数置0;所以,枚举第一列的三种情况(0,1,2),将三种情况的方案数相加即可。
    代码:
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<map>
    #include<set>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<ctime>
    #define fuck(x) cout<<#x<<" = "<<x<<endl;
    #define ls (t<<1)
    #define rs ((t<<1)+1)
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int maxn = 100086;
    const int inf = 2.1e9;
    const ll Inf = 999999999999999999;
    const int mod = 100000007;
    const double eps = 1e-6;
    const double pi = acos(-1);
    char s[maxn];
    int num[maxn];
    int rec[maxn];
    int main()
    {
    //    ios::sync_with_stdio(false);
    //    freopen("in.txt","r",stdin);
    
        int T;
        scanf("%d",&T);
        while(T--){
            scanf("%s",s+1);
            int n=strlen(s+1);
            for(int i=1;i<=n;i++){
                num[i]=s[i]-48;
            }
            ll ans = 1ll,cnt = 0;
            bool flag ;
            for(int i=0;i<=2;i++){
                rec[1]=i;ans = 1ll;
                flag = false;
                for(int j=2;j<=n+1;j++){
                    if(rec[j-1]==1){ans*=2ll;ans%=mod;}
                    rec[j] = num[j-1]-rec[j-1]-rec[j-2];
                    if(rec[j]<0||rec[j]>2){flag=true;break;}
                }
    
    //            for(int j=1;j<=n+1;j++){
    //                cout<<rec[j]<<" ";
    //            }
    //            cout<<endl;
    
                if(flag){continue;}
                if(num[n]!=rec[n]+rec[n-1]){continue;}
                cnt+=ans;cnt%=mod;
            }
            printf("%lld
    ",cnt);
        }
        return 0;
    }


  • 相关阅读:
    函数及习题
    数组和集合
    数组和集合实例
    普通集合和泛型集合的区别,哈希表和字典表的区别,队列和堆栈的区别以及堆和栈的区别。
    c#时间表示
    c#正则表达式
    js正则实例
    习题实例
    c#数据类型
    简单控件
  • 原文地址:https://www.cnblogs.com/ZGQblogs/p/9888595.html
Copyright © 2011-2022 走看看