2 solutions

  • 0
    @ 2022-4-20 20:44:34

    这个题本质上是flood fill 变形+记忆化搜索 有m个读入数据,每次bfs或者dfs必然会超时 就把之前已经搜过的点标记一下,然后这个算是01相邻的一个连通块,这个实质上就是求哪一块01连通块里面元素的个数 bfs

    #include<cstring>
    #include<queue>
    using namespace std;
    typedef pair<int,int> PAII;
    int n,m;
    const int N=1010,M=1e6+10;
    char ch[N][N];
    int f[N][N],cnt[M];
    int dx[4]={0,0,1,-1};
    int dy[4]={1,-1,0,0};
    int bfs(int x,int y,int u)
    {
    queue<PAII> q;
    q.push({x,y});
    cnt[u]=1;
    f[x][y]=u;//看看是第几层
    while(q.size())
    {
    auto t=q.front();
    q.pop();
    int a=t.first,b=t.second;
    for(int i=0;i<4;i++)
    {
    int xx=a+dx[i],yy=b+dy[i];
    if(xx<0||yy<0||xx>=n||yy>=n) continue;
    if(ch[a][b]-'0'==!(ch[xx][yy]-'0')&&f[xx][yy]==-1)
    {
    q.push({xx,yy});
    cnt[u]++;
    f[xx][yy]=u;
    }
    }
    }
    return cnt[u];
    }
    int main(){
    cin>>n>>m;
    for(int i=0;i<n;i++)
    for(int j=0;j<n;j++)
    cin>>ch[i][j];
    memset(f,-1,sizeof(f));
    for(int i=0;i<m;i++)
    {
    int a,b;
    cin>>a>>b;
    a--;
    b--;
    if(f[a][b]==-1)
    {
    int t=bfs(a,b,i);
    //cout<<t<<endl;
    cnt[i]=t;
    }
    else cnt[i]=cnt[f[a][b]];
    }
    for(int i=0;i<m;i++) cout<<cnt[i]<<endl;
    return 0;
    }
    

    dfs

    #include<cstring>
    using namespace std;
    const int N=5050;
    int res[100000],f[N][N];//答案和标记 
    char ch[N][N];
    int n,m;
    void dfs(int r,int c,int z,int l)
    {
    	if(r<0||c<0||r>=n||c>=n||f[r][c]!=-1||ch[r][c]-'0'!=z) return ;
    	f[r][c]=l;//
    	res[l]++;
    	dfs(r-1,c,!z,l);
    	dfs(r+1,c,!z,l);
    	dfs(r,c-1,!z,l);
    	dfs(r,c+1,!z,l);
    }
    int main(){
    	cin>>n>>m;
    	for(int i=0;i<n;i++)
    		for(int j=0;j<n;j++)
    			cin>>ch[i][j];
    	memset(f,-1,sizeof(f));
    	for(int i=0;i<m;i++)
    	{
    		int a,b;
    		cin>>a>>b;
    		a--;
    		b--;
    		if(f[a][b]==-1) dfs(a,b,ch[a][b]-'0',i);
    		else res[i]=res[f[a][b]];
    	}
    	for(int i=0;i<m;i++) cout<<res[i]<<endl;
    	return 0;
    }
    /*
    确实可以用dfs,但如果每一次输入都来一次dfs,那必定超时
    所以考虑把每一个点的答案都记录下来,如果没被记录就来一次dfs,可以就直接用 
    */
    

    Information

    ID
    1139
    Time
    1000ms
    Memory
    128MiB
    Difficulty
    8
    Tags
    # Submissions
    40
    Accepted
    7
    Uploaded By