扫雷
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 145 Accepted Submission(s): 40
Problem Description
扫雷游戏是晨晨和小璐特别喜欢的智力游戏,她俩最近沉迷其中无法自拔。
该游戏的界面是一个矩阵,矩阵中有些格子中有一个地雷,其余格子中没有地雷。 游戏中,格子可能处于己知和未知的状态。如果一个己知的格子中没有地雷,那么该 格子上会写有一个一位数,表示与这个格子八连通相邻的格子中地雷总的数量。
现在,晨晨和小璐在一个3行N列(均从1开始用连续正整数编号)的矩阵中进 行游戏,在这个矩阵中,第2行的格子全部是己知的,并且其中均没有地雷;而另外 两行中是未知的,并且其中的地雷总数量也是未知的。
晨晨和小璐想知道,第1行和第3行有多少种合法的埋放地雷的方案。
该游戏的界面是一个矩阵,矩阵中有些格子中有一个地雷,其余格子中没有地雷。 游戏中,格子可能处于己知和未知的状态。如果一个己知的格子中没有地雷,那么该 格子上会写有一个一位数,表示与这个格子八连通相邻的格子中地雷总的数量。
现在,晨晨和小璐在一个3行N列(均从1开始用连续正整数编号)的矩阵中进 行游戏,在这个矩阵中,第2行的格子全部是己知的,并且其中均没有地雷;而另外 两行中是未知的,并且其中的地雷总数量也是未知的。
晨晨和小璐想知道,第1行和第3行有多少种合法的埋放地雷的方案。
Input
包含多组测试数据,第一行一个正整数T,表示数据组数。
每组数据由一行仅由数字组成的长度为N的非空字符串组成,表示矩阵有3行N 列,字符串的第i个数字字符表示矩阵中第2行第i个格子中的数字。
保证字符串长度N <= 10000,数据组数<= 100。
每组数据由一行仅由数字组成的长度为N的非空字符串组成,表示矩阵有3行N 列,字符串的第i个数字字符表示矩阵中第2行第i个格子中的数字。
保证字符串长度N <= 10000,数据组数<= 100。
Output
每行仅一个数字,表示安放地雷的方案数mod100,000,007的结果。
Sample Input
2 22 000
Sample Output
6 1
我参加了合肥站的ICPC,就因为这一题我卡了3个小时,其实我们早就做出来了,只因为,,,,
哎!今天交了二十多发,我有点不敢相信答案能折磨坑,,,,,也是我们太弱,题意的坑点读不懂,,,,有点伤心,这是我们第一次打比赛。
说一下思路吧!
我们就是吧每一列的雷看成一组,就是数字上下雷加起来的个数是吧,举个例子
比如
22这组
第一个二上下雷数可以为0,1,2那对应的第二个是2,1,0;
雷 无
2 2
无 雷
那就是第一列为雷数为1,第二列为1了
我们这样想后有会发现
当雷数为0,2时只有一种情况,而为1时有两种情况,,,,,,
我们用数组b[]来存上下雷数a[]存给出的数字
我们先假设b[0] = 0;
这样我们有会发现b[i] = a[i-1]-b[i-1]-b[i-2];这样一个规律
只要看看是不是b[]数组都在0-2之间就可以
然后b[0] = 1 =2的情况
当然这样是不够的我们还发现我们可以验证其正确性b[len-1]+b[len-2] != a[len-1](用最后一组数验证正确性)
代码
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;const int M = 1e8+7;
long long a[10005], b[10005];
long long len;void zushu(char ch[])
{long long i;for ( i = 0;i < len; i++ ){a[i] = ch[i]-'0';}
}long long jisuan()
{long long i, j;long long sum = 0;for ( j = 0; j < 3; j++ ){b[1] = j;b[0] = a[0]-j;if( b[0] < 0||b[0] > 2 )continue;int ok = 1;for ( i = 2; i < len; i++ ){b[i] = a[i-1]-b[i-1]-b[i-2];if (b[i] < 0||b[i] > 2 ){ok = 0;break;}}if ( b[len-1]+b[len-2] != a[len-1] )ok = 0;if ( ok == 1 ){long long s = 1;for ( i = 0; i < len; i++ ){if ( b[i] == 1 )s = s*2%M;}sum = (sum+s)%M;}}return sum;
}int main()
{long long T;char ch[100005];scanf ( "%d", &T );while ( T-- ){scanf ( "%s", ch );len = strlen(ch);zushu(ch);if ( len == 1 ){if( a[0] == 1 )printf ( "2\n" );else if( a[0] == 2||a[0] == 0) //我们躺在了这里,有点可惜,我们当时认为不可能输出不规范的数没想到,没想到输入一个数还有0,1,2以外的数printf ( "1\n" ); //注释起来的就是我们当时的代码,在这里我们只能呵呵了。elseprintf ( "0\n" );}// if ( len == 1 ) // {// if( a[0] == 1 )// printf ( "2\n" );// else// printf ( "1\n" );// }else{long long sum = jisuan();printf ( "%lld\n", sum );}}
}
代码菜鸟,如有错误,请多包涵!!!
如有帮助记得支持我一下,谢谢!!!