HDU 5965 扫雷 By Assassin
来源:互联网 发布:杭州淘宝小镇 编辑:程序博客网 时间:2024/06/06 01:43
扫雷
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
讲真没想到我这么水。。。这个铁牌题目都坑死在了这里。。。而且我xjbg出了一种麻烦的方法。。。
方法一:
思路:我们其实可以发现,只要确定了第一列的状态,就可以确定所有后面的状态了。。。那么这个怎么做,首先是枚举初始状态,也就3种情况,但是也可能和第一个数有关。之后枚举,每次求出正常的状态,用dp[i]记录i位置列应该有几个。那么每次我们计算一下,碰到1就×2取膜就好。,注意1位的时候特判一下。还有一个别用string。。。用char。。。
代码
#include<bits/stdc++.h>#define input freopen("input.txt","r",stdin)using namespace std; long long a[10005],dp[10005];char s[10005];int main(){ input; int t,n,len,i,j,k; long long ans; while(scanf("%d",&t)!=EOF){ while(t--){ scanf("%s",s); len=strlen(s); for(i=0;i<len;i++){ a[i+1]=s[i]-'0'; } if(len==1){ if(s[0]=='0'||s[0]=='2') cout<<1<<endl; else if(s[0]=='1') cout<<2<<endl; else cout<<0<<endl; continue; } dp[0]=0; ans=0; for(k=0;k<=a[1];k++){ if(k>2) break; memset(dp,0,sizeof(dp)); dp[1]=k; int flag=1; for(i=2;i<=len;i++){ dp[i]=a[i-1]-dp[i-1]-dp[i-2]; if(dp[i]<0||dp[i]>2) { flag=0; break; } } if(flag==1){ for(i=1;i<=len;i++){ if(a[i]!=dp[i-1]+dp[i]+dp[i+1]){ flag=0; break; } } } if(!flag) continue; long long key=1; for(i=1;i<=len;i++){ if(dp[i]==1){ key=(key*2)%100000007; } } ans+=key; } cout<<ans%100000007<<endl; } } return 0; }
方法二:
思路:就简直不是方法,麻烦版本的dp,你敢想我用了三维!大概的转移状态dp[i][j][k]代表第i个位置,当前准备使用j个,这个需要遍历,在后面必须用k个。注意这不算是严格的动规,因为第三维其实只是相当于一个调用的接口,指后一个如果用k个,向前找必须对应后面必须是可的位置。
所以这个需要遍j和k,每次首先判断这样的求
的下一个值是否合法(只能是0-2)然后转移,[[
代表第0个位置,选择0个下一个接0-2都可以。
#include <bits/stdc++.h>using namespace std;int a[10005];long long dp[10005][3][3];char s[10005];int main(){ //freopen("input.txt","r",stdin); int t,i,j,k,len; scanf("%d",&t); while(t--){ scanf("%s",s); len=strlen(s); for(i=0;i<len;i++){ a[i+1]=s[i]-'0'; } memset(dp,0,sizeof(dp)); dp[0][0][0]=1; dp[0][0][1]=1; dp[0][0][2]=1; for(i=1;i<=len;i++){ for(j=0;j<=2;j++){ if(a[i]-j>=0&&a[i]-j<=2){ dp[i][j][a[i]-j]=dp[i-1][0][j]; if(j==1) { dp[i][j][a[i]-j]*=2; if(dp[i][j][a[i]-j]>=100000007) dp[i][j][a[i]-j]-=100000007; } } if(a[i]-j-1>=0&&a[i]-j-1<=2){ dp[i][j][a[i]-j-1]=(dp[i-1][1][j]); if(j==1){ dp[i][j][a[i]-j-1]*=2; if(dp[i][j][a[i]-j-1]>=100000007) dp[i][j][a[i]-j-1]-=100000007; } } if(a[i]-j-2>=0&&a[i]-j-2<=2){ dp[i][j][a[i]-j-2]=dp[i-1][2][j]; if(j==1){ dp[i][j][a[i]-j-2]*=2; if(dp[i][j][a[i]-j-2]>=100000007) dp[i][j][a[i]-j-2]-=100000007; } } } } long long ans=0; for(j=0;j<=2;j++){ ans+=dp[len][j][0]; } cout<<ans%100000007<<endl; } return 0;}
- HDU 5965 扫雷 By Assassin
- HDU 2955 Robberies by Assassin
- HDU 2571 命运 by Assassin
- HDU 2159 FATE by Assassin
- HDU 1506 City Game by Assassin
- HDU 1069 Monkey and Banana by Assassin
- HDU 2487 Ugly Windows By Assassin
- HDU 2489 Minimal Ratio Tree By Assassin
- HDU 1054 Strategic Game By Assassin
- HDU 5927 Auxiliary Set By Assassin
- HDU 2686 Matrix By Assassin 多线程dp
- HDU 3001 Travelling By Assassin 3进制状压
- HDU 1171 Big Event in HDU by Assassin
- HDU 1506 Largest Rectangle in a Histogram by Assassin
- HDU 1203 I NEED A OFFER! by Assassin
- HDU 2209 翻纸牌游戏 By Assassin 模拟
- HDU 2054 A == B ? By Assassin 模拟
- HDU 1166敌兵布阵 By Assassin 线段树
- 欧拉计划20
- Java语言JDBC数据库连接操作
- Xilinx ISE 开发过程中生成的各种文件(一)
- C++const总结
- arm linux移植lcd
- HDU 5965 扫雷 By Assassin
- Linux指令格式及选项详解一
- [Java]生成随机数
- nrf52832 之 gpio配置方法
- [Builderror]pointer to incomplete class type is not allowed
- 操作系统学习(WEEK6-WEEK12)
- 玲玲学院1054 - String cut 乱搞字符串
- opencv 距离变换
- css实现一级下拉菜单