#include <iostream>
#include <vector>
#include <queue>
#include <filesystem>
#include <stdio.h>
#include <string>
#include <stack>
using namespace std;
void print(vector<vector<string>>& grid)
{
for(const auto& g:grid)
{
for(const auto& i:g)
{
cout << i << " ";
}
cout << endl;
}
}
void dfs(vector<vector<string>>&grid,int i, int j)
{
if(i < 0 || i >= grid.size() || j < 0 || j >= grid[0].size() || grid[i][j] == "0")
return ;
grid[i][j] = "0";
dfs(grid,i-1,j);
dfs(grid,i+1,j);
dfs(grid,i,j-1);
dfs(grid,i,j+1);
return;
}
vector<pair<int,int>>dirs{{0,-1},{0,1},{1,0},{-1,0}};
class DSU{
vector<int>parent_;
public:
DSU(int N)
{
parent_.resize(N);
for(int i = 0; i < N; ++i)
{
parent_[i] = i;
}
}
int find(int x)
{
if(parent_[x] != x)parent_[x] = find(parent_[x]);
return parent_[x];
}
void Union(int x, int y)
{
parent_[find(x)] = find(y);
}
};
void bfs(vector<vector<string>>& grid, int i ,int j)
{
queue<pair<int,int>>q;
q.push({i,j});
while(!q.empty())
{
auto cur = q.front();
q.pop();
int x = cur.first,y = cur.second;
if(x < 0 || x >= grid.size() || y < 0 || y >= grid[0].size() || grid[x][y] == "0")continue;
grid[x][y] = "0";
for(auto dir:dirs)
{
q.push({x+dir.first,y+dir.second});
}
}
}
void dfs_stack(vector<vector<string>>&grid,int i,int j)
{
stack<pair<int,int>>st;
st.push({i,j});
while(!st.empty())
{
auto cur = st.top();
st.pop();
int x = cur.first, y = cur.second;
if(x < 0 || x >= grid.size() || y < 0 || y >= grid[0].size() || grid[x][y] == "0")continue;
grid[x][y] = "0";
for(auto p:dirs)
{
st.push({x + p.first,y+p.second});
}
}
}
int numIslands(vector<vector<string>>&grid)
{
int m = grid.size(), n = grid[0].size(),res = 0;
DSU dsu(m*n);
for(int i = 0; i < m ;++i)
{
for(int j = 0; j < n; ++j)
{
if(grid[i][j] == "1")
{
++res;
dfs_stack(grid,i,j);
// bfs(grid,i,j);
// dfs(grid,i,j);
// DSU
// for(const pair<int,int>p:dirs)
// {
// int x = i + p.first, y = j + p.second;
// if(x >= 0 && y >= 0 && x < m && y < n && grid[x][y] == "1")
// {
// if(dsu.find(x*n+y)!=dsu.find(i*n+j)) --res;
// dsu.Union(x*n+y,i*n+j);
// }
// }
}
}
}
return res;
}
void dfs(vector<vector<string>>&grid,int i,int j, vector<int>&area)
{
if(i < 0 || i >=grid.size()||j < 0 || j >= grid[0].size()|| grid[i][j] == "0")return;
grid[i][j] = "0";
++area[0];
dfs(grid,i-1,j,area);
dfs(grid,i+1,j,area);
dfs(grid,i,j-1,area);
dfs(grid,i,j+1,area);
return ;
}
int maxAreaOfIsland(vector<vector<string>>& grid)
{
int m = grid.size(), n = grid[0].size();
int res = 0;
vector<int>area(1);
for(int i = 0;i < m; ++i)
{
for(int j = 0; j < n; ++j)
{
if(grid[i][j] == "1")
{
area[0] = 0;
dfs(grid,i,j,area);
res = max(res,area[0]);
}
}
}
return res;
}
int dfs0(vector<vector<string>>&grid,int i, int j)
{
if(i <0 || i >= grid.size() || j < 0 || j >= grid[0].size() || grid[i][j] == "0")return 1;
if(grid[i][j] == ".")return 0;
grid[i][j] = ".";
return dfs0(grid,i-1,j)+dfs0(grid,i+1,j)+dfs0(grid,i,j-1)+dfs0(grid,i,j+1);
}
int islandPerimeter(vector<vector<string>>&grid)
{
int m = grid.size(), n = grid[0].size();
for(int i = 0;i < m; ++i)
{
for(int j = 0;j < n ;++j)
{
if(grid[i][j] == "1")
{
return dfs0(grid,i,j);
}
}
}
}
bool dfs(vector<vector<string>>&grid,int i, int j, int m,int n)
{
if(i < 0 || j < 0 || i >= m || j >= n) return false;
if(grid[i][j] == "0")return true;
grid[i][j] = "0";
return dfs(grid,i+1,j,m,n) &&dfs(grid,i-1,j,m,n) && dfs(grid,i,j-1,m,n) && dfs(grid,i,j+1,m,n);
}
int closeIsland(vector<vector<string>>&grid)
{
int res = 0, m = grid.size(), n = grid[0].size();
for(int i = 0; i < m; ++i)
{
for(int j = 0;j < n ; ++j)
{
if(grid[i][j] == "1" && dfs(grid,i,j,m,n)) ++res;
}
}
return res;
}
int main()
{
// vector<vector<string>>grid{{"1","1","1","1","0"},{"1","1","0","1","0"},{"1","1","0","0","0"},{"0","0","0","0","0"}};
// vector<vector<string>>grid{{"1","1","0","0","0"},{"1","1","0","0","0"},{"0","0","1","0","0"},{"0","0","0","1","1"}};
// vector<vector<string>>grid{{"0","1","0","0"},{"1","1","1","0"},{"0","1","0","0"},{"1","1","0","0"}};
vector<vector<string>>grid{{"1","1","0","1","1"},{"1","0","1","0","1"},{"1","0","0","0","1"}};
print(grid);
// LeetCode200
// cout << numIslands(grid)<<endl;
// LeetCode695
// cout << maxAreaOfIsland(grid)<<endl;
//LeetCode463
// cout << islandPerimeter(grid)<<endl;
// LeetCode1254
cout << closeIsland(grid) <<endl;
return 0;
}