1001: Gingers and Mints

1001: Gingers and Mints
Time Limit: 1 Sec Memory Limit: 128 MB 64bit IO Format: %lld
Submitted: 240 Accepted: 54
[Submit][Status][Web Board]
Description
fcbruce owns a farmland, the farmland has n * m grids. Some of the grids are stones, rich

soil is the rest. fcbruce wanna plant gingers and mints on his farmland, and each plant

could occupy area as large as possible. If two grids share the same edge, they can be

connected to the same area. fcbruce is an odd boy, he wanna plant gingers, which odd

numbers of areas are gingers, and the rest area, mints. Now he want to know the number of

the ways he could plant.

Input
The first line of input is an integer T (T < 100), means there are T test cases.
For each test case, the first line has two integers n, m (0 < n, m < 100).
For next n lines, each line has m characters, ‘N’ for stone, ‘Y’ for rich soil that is

excellent for planting.

Output
?For each test case, print the answer mod 1000000007 in one line.

Sample Input Copy to Clipboard Successfully2
3 3
YNY
YNN
NYY
3 3
YYY
YYY
YYY

Sample Output
4
1

HINT

For the first test case, there are 3 areas for planting. We marked them as A, B and C.

fcbruce can plant gingers on A, B, C or ABC. So there are 4 ways to plant gingers and

mints.

问题描述:
fcbruce拥有一个农场,是一个N*M的网格,有一些格子是石头(N),一些是土壤(Y),在土壤内可以种庄

稼。相邻的Y可以连为一片,但是fcbruce有一个奇怪的爱好,只种奇数片。问总共有多少种方法?
分析:
这是一个标准的连通块问题,所以用bfs()算法即可(深搜太耗时)。way[][]代表上下左右四个方向,

s[][]用来存储网格,v[][]用来标记是否已经判断过。我的方法中是用一个q[]数组模拟队列(STL的

queue太耗时),你也可以直接使用STL的queue。
AC代码:

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

const int maxn=105;
char s[maxn][maxn];
int T,n,m,v[maxn][maxn],way[4][2]={{0,-1},{0,1},{-1,0},{1,0}};
struct node
{
    int x;
    int y;
};
node q[10005];

void bfs(int i,int j)
{
    memset(q,0,sizeof(q));
    int h=0,t=0;
    q[h].x=i;q[h].y=j;
    v[i][j]=1;
    h++;
    while(h-t!=0)
    {
        int x1,y1;
        for(int i=0;i<4;i++)
        {
            x1=q[t].x+way[i][0];
            y1=q[t].y+way[i][1];
            if(x1>=0 && x1<n && y1>=0 && y1<m && !v[x1][y1] && s[x1][y1]=='Y')
            {
                q[h].x=x1;
                q[h].y=y1;
                v[x1][y1]=1;
                h++;
            }
        }
        t++;
    }

}

int main()
{
   scanf("%d",&T);
   while(T--)
   {
       memset(s,0,sizeof(s));
       memset(v,0,sizeof(v));
       scanf("%d%d",&n,&m);
       for(int i=0;i<n;i++)
        scanf("%s",s[i]);
       int cnt=0;
       for(int i=0;i<n;i++)
       {
           for(int j=0;j<m;j++)
           {
               if(!v[i][j] && s[i][j]=='Y')
               {
                   bfs(i,j);
                   cnt++;
               }
           }
       }
       int sum=1;
       for(int i=1;i<=cnt-1;i++)
       {
           sum=((sum%1000000007)*2)%1000000007;
       }
       if(cnt==0)
        printf("%d\n",0);
       else
        printf("%d\n",sum);
   }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值