6 solutions

  • 1
    @ 2025-2-21 21:11:57
    #include <bits/stdc++.h>
    using namespace std;
    int movex[4]={-1, 1, 0, 0};
    int movey[4]={0, 0, -1, 1};
    int w, h;
    char chess[25][25];
    bool vistor[25][25];
    int x, y;
    int ans=1;
    
    void dfs(int x, int y)
    {
    	vistor[x][y]=true;//走过的地方不能走 
    //	cout << x << " " << y << endl;
    	for(int i = 0;i < 4; i++)
    	{
    		int ny=y+movey[i];
    		int nx=x+movex[i];
    		if(vistor[nx][ny]==false&&nx>=1&&ny>=1&&nx<=w&&ny<=h)//不越界且没走过且能走 
    		{
    			ans++;
    			dfs(nx, ny);
    		}
    	}
    }
    int main()
    {
    	
    	while (cin >> h >> w)
    	{
    		if(h==0 && w==0) return 0;//退出 
    		//重置 
    		for(int i = 1; i <= w; i++)
    		{
    			for(int j = 1; j <= h; j++)
    			{
    				vistor[i][j]=false;
    			}
    		}
    		ans=1;
    		for(int i = 1; i <= w; i++)
    		{
    			for(int j = 1; j <= h; j++)
    			{
    				cin >> chess[i][j];
    				if(chess[i][j]=='@')
    				{
    					x=i;
    					y=j;
    				}
    				if(chess[i][j]=='#')
    				{
    					vistor[i][j]=true;
    				}
    			}
    		}
    		dfs(x, y);
    		cout << ans << endl;
    		
    	}
    	
    	
    	
        return 0;
    }
    
    
    • 1
      @ 2025-1-17 13:59:18

      题目大意

      有一间长方形的房子,地上铺了红色、黑色两种颜色的正方形瓷砖。

      你站在其中一块黑色的瓷砖上,只能向相邻的黑色瓷砖移动。

      请写一个程序,计算你总共能够到达多少块黑色的瓷砖。

      每个字符表示一块瓷砖的颜色,规则如下:

      • .:黑色的瓷砖;
      • #:白色的瓷砖;
      • @:黑色的瓷砖,并且你站在这块瓷砖上。该字符在每个数据集合中唯一出现一次。

      解题代码

      #include <bits/stdc++.h>
      using namespace std;
      
      char a[105][105];
      int flag[1005][1005], cnt = 1, n, m;
      
      void dfs(int x, int y)
      {
          for (int i = 1; i <= 4; i++)
      	{
          	int dx, dy;
      		if (i == 1) dx = x + 1, dy = y;
      		else if (i == 2) dx = x - 1, dy = y;
      		else if (i == 3) dx = x, dy = y + 1;
      		else dx = x, dy = y - 1;
      		if (dx >= 1 && dy >= 1 && dx <= n && dy <= m && a[dx][dy] == '.' && !flag[dx][dy]) // 浅浅剪一下枝 
      		{
      			flag[dx][dy] = true;
      			cnt++;
      			dfs(dx,dy);
      		}
      	}
      }
      int main()
      {
      	while (1)
      	{
      		cin >> m >> n;
      		if(n == m && n == 0) return 0; // 一定要写这个,不然直接死循环 
      		int x, y;
      		for (int i = 1; i <= n; i++)
      		{
      			for (int j = 1; j <= m; j++)
      			{
      				cin >> a[i][j];
      				if (a[i][j] == '@') x = i, y = j; // 找到了黑色的瓷砖 
      				flag[i][j] = false; // flag重新变为false 
      			}
      		}
      		dfs(x, y); // 进行dfs 
      		cout << cnt << endl;  // 输出答案 
      		cnt = 1; // cnt重新变为1 
      	}
      }
      
      • -1
        @ 2025-1-16 19:45:38
        #include<bits/stdc++.h>
        
        using namespace std;
        char c[1001][1001];
        bool vis[1001][1001];
        const int dx[8]={0,0,1,-1,-1,1,-1,1};
        const int dy[8]={1,-1,0,0,-1,1,1,-1};
        int cnt=0; 
        int n,m;
        void dfs(int x,int y){
        	cnt++;//个数加1 
        	for(int i=0;i<4;i++){
        		int nx=dx[i]+x;
        		int ny=dy[i]+y;
        		if(nx<1||ny<1||nx>m||ny>n||vis[nx][ny]==1||c[nx][ny]=='#')continue;//简单标记 
        		vis[nx][ny]=1;
        		dfs(nx,ny);
        	}
        }
        int main(){
        	//类P1451. 求细胞数量,深度优先搜索 
        	while(cin>>n>>m){
        		if(n==0&&m==0)break;
        		int x,y;
        		//每次刷新所有标记类数组
        		memset(c,'0',sizeof(c)); 
        		memset(vis,0,sizeof(vis)); 
        		for(int i=1;i<=m;i++){
        			for(int j=1;j<=n;j++){
        				cin>>c[i][j];
        				if(c[i][j]=='@'){
        					x=i;
        					y=j;
        				}
        			}
        		}
        		//可连通的一次能走完 
        		vis[x][y]=1;//特别注意!不能忘起始位置! 
        		dfs(x,y);
        		cout<<cnt<<'\n';
        		cnt=0;
        	}
        	return 0;
        }
        
        • -1
          @ 2024-10-24 13:30:57

          一种新的思路: 洪水填充

          在起点进行一次洪水填充,统计标记的个数

          #include<iostream>
          #include<cstring>
          using namespace std;
          int xl[4]={0,0,1,-1};
          int yl[4]={1,-1,0,0};
          int n,m,sx,sy,sum;
          char g[25][25];
          bool vis[25][25];
          void dfs(int x,int y)//洪水填充 
          {
          	vis[x][y]=1;
          	for(int i=0;i<4;i++)
          	{
          		int xs=x+xl[i];
          		int ys=y+yl[i];
          		if(xs>0 && xs<=n && ys>0 && ys<=m && g[xs][ys]=='.' && !vis[xs][ys])
          			dfs(xs,ys);
          	}
          }
          int main()
          {
          	while(1)
          	{
          		memset(g,0,sizeof g);
          		memset(vis,0,sizeof vis);
          		sum=0;
          		cin>>m>>n;
          		if(m==0 && n==0)//是否结束
          			return 0;
          		for(int i=1;i<=n;i++)
          			for(int j=1;j<=m;j++)
          			{
          				cin>>g[i][j];
          				if(g[i][j]=='@')
          					sx=i,sy=j;
          			}
          		dfs(sx,sy);
          		for(int i=1;i<=n;i++)
          			for(int j=1;j<=m;j++)
          				sum+=vis[i][j];//统计走过的个数
          		cout<<sum<<"\n";
          	}
          	return 0;
          }
          
          • -1
            @ 2024-4-10 16:56:08

            BFS做法,可能有亿点复杂………………

            #include<bits/stdc++.h>
            using namespace std;
            struct s{
                int x,y;
            };
            queue<s> q;
            int fx[10]={0,1,0,-1},fy[10]={1,0,-1,0},ans=1;
            string arr[110];
            int main(){
                while(true){
                    int n,m,sx,sy,ans=1;
                    cin>>n>>m;
                    if(n==0 && m==0) break;
                    for(int i=0;i<m;i++){
                        cin>>arr[i];
                        for(int j=0;j<n;j++){
                            if(arr[i][j]=='@') sx=i,sy=j;
                        }
                    }
                    q.push({sx,sy});
                    while(q.size()){
                        int x=q.front().x,y=q.front().y;
                        q.pop();
                        for(int i=0;i<4;i++){
                            if(x+fx[i]>=0 && x+fx[i]<m && y+fy[i]>=0 && y+fy[i]<n && arr[x+fx[i]][y+fy[i]]=='.'){
                                ans++;
                                q.push({x+fx[i],y+fy[i]});
                                arr[x+fx[i]][y+fy[i]]='#';
                            }
                        }
                    }
                    cout<<ans<<'\n';
                }
                return 0;
            }
            
            • -1
              @ 2024-1-24 22:41:46

              AC题解(附详细解析)

              #include<bits/stdc++.h>//祖传开头 
              using namespace std;
              bool visited[25][25];//标记该地砖是否已被访问 
              char rm[25][25];//"room"的缩写,以矩阵形式存储房间概况 
              int step=1;//记录步数,以此判断是否已无路可走 
              int w0,h0;//由于w,h是函数的参数变量,所以需要w0,h0两个恒变量存储输入的w,h值 
              int dfs(int x,int y,int w,int h,int sum){//搜索函数 
              	visited[x][y]=true;//每经过一块瓷砖就进行标记,以免重复走。 
              	step++;//步数++ 
              	if(step==w0*h0*4){//约等于重复走上4遍,保证的确无路可走再return 
              		return sum;//return计算地砖的总和 
              	} 
              	if(x-1>=0 and visited[x-1][y]==0){//往下的四个条件判断分别代表上下左右,每探测一步就计数,递归 
              		sum++;
              		step++;
              		sum+=dfs(x-1,y,w,h,0);
              	}
              	if(x+1<h and visited[x+1][y]==0){
              		sum++;
              		step++;
              		sum+=dfs(x+1,y,w,h,0);
              	}
              	if(y-1>=0 and visited[x][y-1]==0){
              		sum++;
              		step++;
              		sum+=dfs(x,y-1,w,h,0);
              	}
              	if(y+1<w and visited[x][y+1]==0){
              		sum++;
              		step++;
              		sum+=dfs(x,y+1,w,h,0);
              	}
              	return sum;//再将总和return 
              }
              int main(){
              	int w,h,x,y;//w,h为题目要求变量,x,y分别代表x坐标,y坐标 
              	while(cin>>w>>h){//因为题目有多个测试样例,所以while 
              		if(w==0&&h==0){//当输入0 0时,程序结束 
              			return 0;
              		}
              		for(int i=0;i<h;i++){//双重循环输入矩阵 
              			for(int j=0;j<w;j++){
              				cin>>rm[i][j];
              				if(rm[i][j]=='@'){//记录起始点x,y坐标 
              					x=i;
              					y=j;
              					visited[i][j]=true;//起点视为已经过 
              				}
              				if(rm[i][j]=='#'){//白色地砖也视为已经过,省去了函数判断 
              					visited[i][j]=1;
              				}
              			}
              		}
              		w0=w;//使用w0,h0记录w(width)和h(height) 
              		h0=h;
              		cout<<dfs(x,y,w,h,1)<<endl;//调用函数,由于起点也是黑地砖,所以sum初始为1 
              		memset(visited,0,sizeof(visited));//记得初始化,本人亲测不初始化只有20分 
              		step=0;
              	}
              	return 0;//祖传结尾 
              } 
              //附:感谢大佬在A1215发的题解,给了我启发 
              
              • 1

              Information

              ID
              702
              Time
              1000ms
              Memory
              256MiB
              Difficulty
              7
              Tags
              # Submissions
              115
              Accepted
              29
              Uploaded By