洛谷P1141

题目描述(https://www.luogu.org/problemnew/show/P1141)

有一个仅由数字00与11组成的n \times nn×n格迷宫。若你位于一格0上,那么你可以移动到相邻44格中的某一格11上,同样若你位于一格1上,那么你可以移动到相邻44格中的某一格00上。

你的任务是:对于给定的迷宫,询问从某一格开始能移动到多少个格子(包含自身)。

输入输出格式

输入格式:
第11行为两个正整数n,mn,m。

下面nn行,每行nn个字符,字符只可能是00或者11,字符之间没有空格。

接下来mm行,每行22个用空格分隔的正整数i,ji,j,对应了迷宫中第ii行第jj列的一个格子,询问从这一格开始能移动到多少格。

输出格式:
mm行,对于每个询问输出相应答案。

输入输出样例

输入样例#1:
2 2
01
10
1 1
2 2

输出样例#1: 复制
4
4

题解:其实就是连通块问题,连通块中有n个节点,就将连通块中所有的节点赋值为n;

读入时有个小技巧,对于二维字符数组a,scanf("%s",a[i]+1)可以以1下标读入一行。
(gets,strlen等同理,如strlen(s+1)1下标字符串长度)

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
const int maxn=1005;
int n,m;
char a[maxn][maxn];
int d[maxn][maxn];
int X[4]={1,0,-1,0},Y[4]={0,1,0,-1};///增量数组少了个逗号!!!,致错
bool visit[maxn][maxn]={false};
struct node{int x,y;}Node;
bool check(int x1,int y1,int x2,int y2)///x1,y1要走的,x2,y2原来的
{
    if(x1<0||y1<0||x1>=n||y1>=n) return false;
    if(a[x1][y1]==a[x2][y2]||visit[x1][y1]==true) return false;
    return true;
}
void dfs(int x,int y)
{
    Node.x=x,Node.y=y;
    int sum=1;
    queue<node>q;
    queue<node>Q;
    q.push(Node);
    while(!q.empty())
    {
        node fron=q.front();
        q.pop();Q.push(fron);
        visit[fron.x][fron.y]=true;
        for(int i=0;i<4;i++)
        {
            int newx=fron.x+X[i];
            int newy=fron.y+Y[i];
            if(check(newx,newy,fron.x,fron.y))
            {
                //cout<<111<<endl;
                sum++;
                Node.x=newx,Node.y=newy;
                visit[newx][newy]=true;///别忘了
                q.push(Node);
            }
        }
    }
    while(!Q.empty()){node aa=Q.front();Q.pop();d[aa.x][aa.y]=sum;}///多用一个队列,将连通块所有点赋值
}
int main()
{
    cin>>n>>m;
    for(int i=0;i<n;i++) {for(int j=0;j<n;j++) {cin>>a[i][j];}getchar();}
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++) {if(visit[i][j]==false) dfs(i,j);}
    }
    while(m--)
    {
        int x,y;
        cin>>x>>y;
        cout<<d[x-1][y-1]<<endl;
        //if(visit[x-1][y-1]) cout<<1<<endl;
        //else cout<<0<<endl;
    }
    //for(int i=0;i<n;i++) for(int j=0;j<n;j++) cout<<d[i][j]<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Spidy_harker/article/details/88936512
今日推荐