Skip to content

Instantly share code, notes, and snippets.

@SuryaPratapK
Created March 23, 2020 12:00
Show Gist options
  • Save SuryaPratapK/36819ab3b79581244074913521093e41 to your computer and use it in GitHub Desktop.
Save SuryaPratapK/36819ab3b79581244074913521093e41 to your computer and use it in GitHub Desktop.
// C++ program to find minimum time required to make all
// oranges rotten
#include<bits/stdc++.h>
#define R 3
#define C 5
using namespace std;
// function to check whether a cell is valid / invalid
bool isvalid(int i, int j)
{
return (i >= 0 && j >= 0 && i < R && j < C);
}
// structure for storing coordinates of the cell
struct ele {
int x, y;
};
// Function to check whether the cell is delimiter
// which is (-1, -1)
bool isdelim(ele temp)
{
return (temp.x == -1 && temp.y == -1);
}
// Function to check whether there is still a fresh
// orange remaining
bool checkall(int arr[][C])
{
for (int i=0; i<R; i++)
for (int j=0; j<C; j++)
if (arr[i][j] == 1)
return true;
return false;
}
// This function finds if it is possible to rot all oranges or not.
// If possible, then it returns minimum time required to rot all,
// otherwise returns -1
int rotOranges(int arr[][C])
{
// Create a queue of cells
queue<ele> Q;
ele temp;
int ans = 0;
// Store all the cells having rotten orange in first time frame
for (int i=0; i<R; i++)
{
for (int j=0; j<C; j++)
{
if (arr[i][j] == 2)
{
temp.x = i;
temp.y = j;
Q.push(temp);
}
}
}
// Separate these rotten oranges from the oranges which will rotten
// due the oranges in first time frame using delimiter which is (-1, -1)
temp.x = -1;
temp.y = -1;
Q.push(temp);
// Process the grid while there are rotten oranges in the Queue
while (!Q.empty())
{
// This flag is used to determine whether even a single fresh
// orange gets rotten due to rotten oranges in current time
// frame so we can increase the count of the required time.
bool flag = false;
// Process all the rotten oranges in current time frame.
while (!isdelim(Q.front()))
{
temp = Q.front();
// Check right adjacent cell that if it can be rotten
if (isvalid(temp.x+1, temp.y) && arr[temp.x+1][temp.y] == 1)
{
// if this is the first orange to get rotten, increase
// count and set the flag.
if (!flag) ans++, flag = true;
// Make the orange rotten
arr[temp.x+1][temp.y] = 2;
// push the adjacent orange to Queue
temp.x++;
Q.push(temp);
temp.x--; // Move back to current cell
}
// Check left adjacent cell that if it can be rotten
if (isvalid(temp.x-1, temp.y) && arr[temp.x-1][temp.y] == 1) {
if (!flag) ans++, flag = true;
arr[temp.x-1][temp.y] = 2;
temp.x--;
Q.push(temp); // push this cell to Queue
temp.x++;
}
// Check top adjacent cell that if it can be rotten
if (isvalid(temp.x, temp.y+1) && arr[temp.x][temp.y+1] == 1) {
if (!flag) ans++, flag = true;
arr[temp.x][temp.y+1] = 2;
temp.y++;
Q.push(temp); // Push this cell to Queue
temp.y--;
}
// Check bottom adjacent cell if it can be rotten
if (isvalid(temp.x, temp.y-1) && arr[temp.x][temp.y-1] == 1) {
if (!flag) ans++, flag = true;
arr[temp.x][temp.y-1] = 2;
temp.y--;
Q.push(temp); // push this cell to Queue
}
Q.pop();
}
// Pop the delimiter
Q.pop();
// If oranges were rotten in current frame than separate the
// rotten oranges using delimiter for the next frame for processing.
if (!Q.empty()) {
temp.x = -1;
temp.y = -1;
Q.push(temp);
}
// If Queue was empty than no rotten oranges left to process so exit
}
// Return -1 if all arranges could not rot, otherwise -1.
return (checkall(arr))? -1: ans;
}
// Drive program
int main()
{
int arr[][C] = { {2, 1, 0, 2, 1},
{1, 0, 1, 2, 1},
{1, 0, 0, 2, 1}};
int ans = rotOranges(arr);
if (ans == -1)
cout << "All oranges cannot rotn";
else
cout << "Time required for all oranges to rot => " << ans << endl;
return 0;
}
@Spetsnaz-Dev
Copy link

At line 61, what if we make a queue of tuple with 3 int values, first being time-stamp, second for x-coordinate and y for y-coordinate. Do we still need to push the delimeter to separate the oranges from current time-frame? because now we will have time frame in the first value of queue tuple.

@ASHISH-GITHUB2495
Copy link

JUST USE BSF ....

int t;
cin >> t;
while (t--)
{
	int r, c;
	cin >> r >> c;

	int arr[r][c];

	for (int i = 0; i < r; i++)
	{
		for (int j = 0; j < c; j++)
			cin >> arr[i][j];
	}


	queue <pair<pair<int, int>, int>> q;



	int dx[4] = {0, 0, -1, 1};
	int dy[4] = { -1, 1, 0, 0};

	int vis[r][c];
	for (int i = 0; i < r; i++)
		for (int j = 0; j < c; j++)
			vis[i][j] = 0;



	for (int i = 0; i < r; i++)
		for (int j = 0; j < c; j++)
			if (arr[i][j] == 2)
				q.push({{i, j}, 0}) , vis[i][j] = 1;


	int timeUnivers = -1;


	while (!q.empty())
	{

		auto f = q.front();
		int x = f.first.first;
		int y = f.first.second;
		int time = f.second;


		for (int i = 0; i < 4; i++)
		{
			int xi = x + dx[i] , yi = y + dy[i];

			if ((xi >= 0 && xi < r) && (yi >= 0 && yi < c) && vis[xi][yi] == 0)
			{

				if (arr[xi][yi] == 1)
				{
					arr[xi][yi] = 2;
					vis[xi][yi] = 1;
					q.push({{xi, yi}, time + 1});
					timeUnivers = time + 1;
				}
				else
				{
					vis[xi][yi] = 1;
				}


			}


		}
		q.pop();



	}




	bool f = true;
	for (int i = 0; i < r; i++)
	{	for (int j = 0; j < c; j++)
		{	if (arr[i][j] == 1)
			{
				cout << "-1" << endl;
				f = false;
				break;
			}
		}
		if (!f)
			break;
	}



	if (f)
		cout << timeUnivers << endl;







}

@surendra172001
Copy link

Bruteforce solution works as well.

#include<bits/stdc++.h>
using namespace std;

// } Driver Code Ends

class Solution
{
public:
//Function to find minimum time required to rot all oranges.

int mx[4] = {-1, 0, 1, 0};
int my[4] = {0, 1, 0, -1};

inline bool validPos(int x, int y, int n, int m) {
    return (x >= 0 && x < n && y >= 0 && y < m);
}
    
    
struct NodeBfs
{
    int i, j, t;
    NodeBfs(int i, int j, int t) : i(i), j(j), t(t) {}
};

int orangesRotting(vector<vector<int>>& grid) {
    
    int n = grid.size();
    int m = grid[0].size();
    
    queue<NodeBfs> q;
    
    
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < m; j++) {
            if(grid[i][j] == 2) {
                q.push(NodeBfs(i, j, 0));
            }
        }
    }
    
    int maxTime = 0;
    
    while (!q.empty())
    {
        NodeBfs curr = q.front();
        q.pop();

        int x = curr.i;
        int y = curr.j;

        maxTime = curr.t;

        for (int p = 0; p < 4; p++)
        {
            int nx = x + mx[p];
            int ny = y + my[p];
            if (validPos(nx, ny, n, m) && grid[nx][ny] == 1)
            {
                grid[nx][ny] = 2;
                q.push(NodeBfs(nx, ny, curr.t + 1));
            }
        }
    }
    
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < m; j++) {
            if(grid[i][j] == 1) {
                return -1;
            }
        }
    }
    
    return maxTime;
}


// // BRUTE FORCE
// int orangesRotting(vector<vector<int>>& grid) {
//     int n = grid.size();
//     int m = grid[0].size();
    
//     int t = 0;
    
//     while(true) {
        
//         int cnt = 0;
//         for(int i = 0; i < n; i++) {
//             for(int j = 0; j < m; j++) {
//                 if(grid[i][j] == 2) {
//                     for(int p = 0; p < 4; p++) {
//                         int nx = i+mx[p];
//                         int ny = j+my[p];
//                         if(validPos(nx, ny, n, m) && grid[nx][ny] == 1) {
//                             grid[nx][ny] = -1;
//                             cnt += 1;
//                         }
//                     }
//                 }
//             }
//         }
        
//         for(int i = 0; i < n; i++) {
//             for(int j = 0; j < m; j++) {
//                 grid[i][j] = (grid[i][j] == -1 ? 2 : grid[i][j]);
//             }
//         }
        
//         if(cnt == 0) {
//             break;
//         }
        
//         t += 1;
//     }
    
//     // for(int i = 0; i < n; i++) {
//     //     for(int j = 0; j < m; j++) {
//     //         cout << grid[i][j] << " ";
//     //     }
//     //     cout << endl;
//     // }
    
//     for(int i = 0; i < n; i++) {
//         for(int j = 0; j < m; j++) {
//             if(grid[i][j] == 1) {
//                 return -1;
//             }
//         }
//     }
    
//     return t;
// }

};

// { Driver Code Starts.
int main(){
int tc;
cin >> tc;
while(tc--){
int n, m;
cin >> n >> m;
vector<vector>grid(n, vector(m, -1));
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
cin >> grid[i][j];
}
}
Solution obj;
int ans = obj.orangesRotting(grid);
cout << ans << "\n";
}
return 0;
} // } Driver Code Ends

@Hari0077
Copy link

Hari0077 commented Jul 6, 2021

class Solution
{
class Orange{
int timeframe;
int x,y;
Orange(int timeframe,int x,int y)
{
this.timeframe = timeframe;
this.x = x;
this.y = y;
}
}
//Function to find minimum time required to rot all oranges.
boolean isvalid(int i, int j,int r,int c)
{
return (i >= 0 && j >= 0 && i < r && j < c);
}

boolean checkall(int arr[][],int r,int c) 
{ 
	for (int i=0; i<r; i++) 
	{
    	for (int j=0; j<c; j++) 
    	{
    		if (arr[i][j] == 1) 
    			return true; 
    	}
	}
	return false; 
}
public int orangesRotting(int[][] grid)
{
    // Code here
    // using bfs...
    Queue<Orange> queue = new LinkedList<>();
    // cal row and col
    int r = grid.length;
    int c = grid[0].length;
    
    // traverse through the 2D array and if rotten -->2
    // orange is present add timeframe,x,y
    for(int i=0;i<r;i++)
    {
        for(int j=0;j<c;j++)
        {
            if(grid[i][j] == 2)
            {
                int x = i;
                int y = j;
            //    System.out.println("The 2 is"+x);
            //    System.out.println("The 2s y"+y);
                int timeframe = 0;
                Orange temp = new Orange(timeframe,x,y);
                queue.add(temp);
            }
        }
    }
    int ans = 0;
    while(!queue.isEmpty())
    {
        // take first element from queue
        Orange element = queue.peek();
     //   System.out.println("The elements x is"+ element.x);
     //   System.out.println("The elements y is"+ element.y);
        
                    // check for right adjacent
        if(isvalid(element.x,element.y+1,r,c) && grid[element.x][element.y+1] == 1)
        {
            grid[element.x][element.y+1] = 2;
           // System.out.println(element.x);
           // System.out.println(element.y+1);
            queue.add(new Orange(element.timeframe+1,element.x,element.y+1));
            
            
        }
        
        // check for left adjacent
        
        if(isvalid(element.x,element.y-1,r,c) && grid[element.x][element.y-1] == 1)
        {
            grid[element.x][element.y-1] = 2;
           // System.out.println(element.x);
           // System.out.println(element.y-1);
            queue.add(new Orange(element.timeframe+1,element.x,element.y-1));
        }
        
        // check for top adjacent
        
        if(isvalid(element.x-1,element.y,r,c) && grid[element.x-1][element.y] == 1)
        {
            grid[element.x-1][element.y] = 2;
           // System.out.println(element.x-1);
           // System.out.println(element.y);
            queue.add(new Orange(element.timeframe+1,element.x-1,element.y));
        }
        
        // check for down adjacent
        
        if(isvalid(element.x+1,element.y,r,c) && grid[element.x+1][element.y] == 1)
        {
            grid[element.x+1][element.y] = 2;
           // System.out.println(element.x+1);
           // System.out.println(element.y);
            queue.add(new Orange(element.timeframe+1,element.x+1,element.y));
        }
        

        
    
    
        
        ans = element.timeframe;
        queue.remove();
    }
    
    ans = checkall(grid,r,c)?-1:ans;
    
    return ans;
}

}

@Seelam-Ramesh-Reddy
Copy link

class Solution {
    public int orangesRotting(int[][] grid) {
    if(grid ==null || grid.length==0) return 0;
    int rows=grid.length;
    int cols=grid[0].length;
    Queue<int[]> queue=new LinkedList<>();
    int count_fresh=0;
        for(int i=0;i<grid.length;i++){
            for(int j=0;j<grid[0].length;j++){
                if(grid[i][j] == 2){
                   queue.offer(new int[]{i,j});
                }
                if(grid[i][j] !=0){
                    count_fresh++;
                }
            }
        }
        
        if(count_fresh==0){
            return 0;
        }
        
        int countMin=0, cnt=0;
        int dx[]={0,0, 1, -1}, dy[]={1, -1, 0 , 0};
        
        while(!queue.isEmpty()){
            int size=queue.size();
            cnt+=size;
            
            for(int i=0;i<size;i++){
                int[] point=queue.poll();
                for(int j=0;j<4;j++){
                    int x=point[0]+dx[j];
                    int y=point[1]+dy[j];
                    if(x<0 || y<0 || x>=rows || y>=cols || grid[x][y]==0 || grid[x][y]==2) continue;
                    
                    grid[x][y]=2;
                    queue.offer(new int[]{x,y});
                }
            }
            if(queue.size() !=0){
                countMin++;
            }
        } 
        return count_fresh==cnt ? countMin : -1;
    }
}

@Yash-pal-singh
Copy link

public int orangesRotting(int[][] grid)
{
int r=grid.length;
int c=grid[0].length;
int count=0;
int countFresh=0;
int[][] target=grid;
Queueq=new LinkedList<>();
for(int i=0;i<r;++i)
{
for(int j=0;j<c;++j)
{
if(target[i][j]==2)
{
q.add(new Pair(i,j));
}
if(target[i][j]==1)
{
countFresh++;
}
}
}
int[] x={-1,1,0,0};
int[] y={0,0,-1,1};
while(!q.isEmpty())
{
int size=q.size();
for(int i=0;i<size;++i)
{
Pair node=q.remove();
for(int p=0;p<4;++p)
{
int nx=x[p]+node.first;
int ny=y[p]+node.second;
if(nx>=0&&ny>=0&&nx<r&&ny<c&&target[nx][ny]==1)
{
countFresh--;
target[nx][ny]=2;
q.add(new Pair(nx,ny));
}
}
}
if(q.size()!=0)
{
count++;
}
}

    return countFresh==0?count:-1;
}

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment