Tuesday, 31 March 2015

                                                Maze




 Pavel loves grid mazes. A grid maze is an n × m rectangle maze where each cell is either empty, or is a wall. You can go from one cell to another only if both cells are empty and have a common side.
Pavel drew a grid maze with all empty cells forming a connected area. That is, you can go from any empty cell to any other one. Pavel doesn't like it when his maze has too little walls. He wants to turn exactly k empty cells into walls so that all the remaining cells still formed a connected area. Help him.
Input
The first line contains three integers nmk (1 ≤ n, m ≤ 5000 ≤ k < s), where n and m are the maze's height and width, correspondingly, k is the number of walls Pavel wants to add and letter s represents the number of empty cells in the original maze.
Each of the next n lines contains m characters. They describe the original maze. If a character on a line equals ".", then the corresponding cell is empty and if the character equals "#", then the cell is a wall.
Output
Print n lines containing m characters each: the new maze that fits Pavel's requirements. Mark the empty cells that you transformed into walls as "X", the other cells must be left without changes (that is, "." and "#").
It is guaranteed that a solution exists. If there are multiple solutions you can output any of them
Sample test(s)
input
3 4 2
#..#
..#.
#...
output
#.X#
X.#.
#...
input
5 4 5
#...
#.#.
.#..
...#
.#.#
output
#XXX
#X#.
X#..
...#
###################################### editorial ##########################################


Start  DFS from any free cell. As the maze is connected, this search will visit all s free cells. But we can stop the search when it visits s - k free cells. It's obvious that these s - k cells are connected to each other. Remaining k cells can be transformed into the walls.
Solutions which every move transform the cell which has the minimal number of neighbours passed pretests. However, it's wrong. Here is the counter-test:
....
.#..
..##
..##


##################################code#################################################
#include<iostream>
using namespace std;
    int n,m,k;
    int c=0;
    int s=0;
    char arr[510][510];
    #include<bits/stdc++.h>
     int   visited[510][510];
  void  dfs(int a,int b)
   {
    
                int re=s-k-1;  
            //     cout<<re<<endl;
        stack<pair<int,int> >s;
        s.push(make_pair(a,b));
        visited[a][b]=1;
         while(!s.empty())
           {
              int x=s.top().first;
              int y=s.top().second;
                  
                  s.pop();
                  int f=0;
                //   cout<<x<<" "<<y<<endl;
                  if(x+1<n && visited[x+1][y]==0 && arr[x+1][y]=='.' )
                   {
                      if(re<=0) arr[x+1][y]='X';
                      
                      visited[x+1][y]=1;
                        s.push(make_pair(x+1,y));
                        f=1;
                        re--;
                      
                   }
                  if(x-1>=0 && visited[x-1][y]==0 && arr[x-1][y]=='.' )
                   {
                     if(re<=0) arr[x-1][y]='X';
                      visited[x-1][y]=1;
                        s.push(make_pair(x-1,y));
                        f=1;
                        re--;
                      
                   }
                    if (y+1<m && visited[x][y+1]==0 && arr[x][y+1]=='.' )
                   {
                        if(re<=0) arr[x][y+1]='X';
                      visited[x][y+1]=1;
                        s.push(make_pair(x,y+1));
                        f=1;
                        re--;
                      
                   }
                    if(y-1>=0 && visited[x][y-1]==0 && arr[x][y-1]=='.' )
                   {
                     if(re<=0) arr[x][y-1]='X';
                      visited[x][y-1]=1;
                        s.push(make_pair(x,y-1));
                        f=1;
                      re--;
                   }
                //cout<<re<<endl;    
            
           }
   }
int main()
 {
     freopen("abc.txt","r",stdin);
 
    cin>>n>>m>>k;
     
      for(int i=0;i<n;i++)
       cin>>arr[i];
        for(int i=0;i<n;i++)
          for(int j=0;j<m;j++) if(arr[i][j]=='.') s++;
       int f=0;
      for(int i=0;i<n;i++)
       {
          for(int j=0;j<m;j++)
           {
              if(arr[i][j]=='.')
              {
               dfs(i,j);
                  f=1;
                 break;
              }
                
            
           }
            if(f==1)
             break;
       }
        for(int i=0;i<n;i++)
         {
            cout<<arr[i];
             cout<<endl;
         }
       return 0;
 }




Wednesday, 25 March 2015

                               

FISHER - Fishmonger



A FishmongerA fishmonger wants to bring his goods from the port to the market. On his route he has to traverse an area with many tiny city states. Of course he has to pay a toll at each border.
Because he is a good business man, he wants to choose the route in such a way that he has to pay as little money for tolls as possible. On the other hand, he has to be at the market within a certain time, otherwise his fish start to smell.

Input

The first line contains the number of states n and available time t. The first state is the port, the last state is the market. After this line there are n lines with n numbers each, specifying for each state the travel time to the i-th state. This table is terminated with an empty line. The table of the tolls follows in the same format.
n is at least 3 and at most 50. The time available is less than 1000. All numbers are integers.
There are many test cases separated by an empty line. Input terminates with number of states and time equal 0 0.

Output

For each test case your program should print on one line the total amount of tolls followed by the actual travelling time.

Example

Sample input:
4 7
0 5 2 3
5 0 2 3
3 1 0 2
3 3 2 0

0 2 2 7
2 0 1 2
2 2 0 5
7 2 5 0

0 0

Sample output:
6 6
This corresponds to the following situation, the connections are labeled with (time, toll):

###################################editorial###################################
   in this problem we can apply bfs or dfs ..  we need to keep track of two parameter time and cost 
  at same instant .. so we use a 2d array visited[node_no][time_used]<-- this matrix contain the minimum cost needed to reach node_no with time_used if there is any attempt to revisit the same node with  same time and more cost then do not push node in to queue..

QUEUE -->>  queue contain 3 parameters [node no ]  [time ] [cost]..  


each time when reach to the last node ie nth node then check  final cost and final time and if less then  previos final cost then update final cost and final time ..




############################CODE###############################################

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int main()
 {
  // freopen("abc.txt","r",stdin);
 
  int n,t;
  while(1)
     {
      int visited[60][1010];
      cin>>n>>t;
     
       
      for(int i=0;i<n;i++)
       {
        for(int j=0;j<1010;j++)
         visited[i][j]=INT_MAX;
       }
     
      if(n==0 && t==0 )break;
      int cost[100][100];
      int time[100][100];
      for(int i=0;i<n;i++)
       {
         
         for(int j=0;j<n;j++)
          {
           
           
            cin>> time[i][j]
           
          }
       }
           for(int i=0;i<n;i++)
            {
            for(int j=0;j<n;j++)
             {
              cin>>cost[i][j]
             }
            }
       
     

      queue<pair<pair<int,int>,int> >s;// node,time,cost

      s.push(make_pair(make_pair(0,0),0));
      visited[0][0]=0; // since we can visit 1st vertix  with cost 0 and time 0
       
     
      int anst=INT_MAX,ansc=INT_MAX;
      while(!s.empty())
       {
          int start=s.front().first.first;
          int cu=s.front().second;
          int tu=s.front().first.second;
          s.pop();
           
          for(int i=0;i<n;i++)// checking all vertices adjecent to start
           {
              if(visited[i][tu+time[start][i]]>cu+cost[start][i] && i!=start && tu+time[start][i]<=t)
                   // checking if node we r going to visit have already visited with same time in minimiu       //cost or not if yes then do not visit again since already visited with   more efficient cost and less time
               {
                     
                      visited[i][tu+time[start][i]]=cu+cost[start][i];
                 s.push(make_pair(make_pair(i,tu+time[start][i]),cu+cost[start][i]));
                   
                 if(i==n-1)// if last node then update ans if possible 
                  {
                   if(ansc>cu+cost[start][i])
                    {
                      ansc=cu+cost[start][i];
                      anst=tu+time[start][i];
                    }
                  }
                 
                 
               }
           }
       
       
       
       
       }
      cout<<ansc<<" "<<anst<<endl;
    }
 

 }

Monday, 23 March 2015

question statement -- find whether a   graph is a tree or not .. or  check graph contain any cycle or not.



 #######################editorial################################################
      we can check this by using recursive dfs.
     if any node is currently in the recursion stack and  from some node it is trying to visit again than it must form cycle.

recursion stack -  recursion stack contain those vertices which are currently in recursion since some child of that node is still remain to visit .
  ex--
  if node a is connected with node b and node c than in recursive dfs once b is found  to a  it call dfs with b
  node c which is connected with a still remain to visit so node a is in recursion stack so that after completion of dfs by node b it start dfs with c(which is also connected with a )..


  for this problem we maintain a hashing array res_stack[] whic contain which node is present in recursion stack or which is not..

note--   

parent node alwese present in recursion stack so in case of undirected graph  for parrent node it not form cycle . so take special care for parent node ..

######################  problems######################################
http://www.spoj.com/problems/PT07Y/



###############################  code ######################################

#include<iostream>
using namespace std;
#include<bits/stdc++.h>
int visited[100001];
 list<int> li[10001];
 int rec_stack[1000001];
 int par[100001];
int dfs(int start)
 {

              list<int>:: iterator it;
              for(it=li[start].begin();it!=li[start].end();it++)
               {
                  
                         if(visited[*it]==0 )
                    {
                        visited[*it]=1;
                        par[*it]=start;
                         rec_stack[*it]=1;
                         dfs(*it);
                       
                       
                    }
                   else if(visited[*it]==1 && rec_stack[*it]==1 && par[start]!=*it )
                    {
                       
                        if(rec_stack[*it]==1)
                         return 1;
                    }
               }
               rec_stack[start]=1;// now  since all node adjecent to node start are covered so remove it                                                         // from   recursion stack
               return 0;
       
 }
int main()
 {
     int n;
    

      cin>>n;
       
         int m;
         cin>>m;
           for(int i=0;i<m;i++)
            {
                int a,b;
                 cin>>a>>b;
                 li[a].push_back(b);
                 li[b].push_back(a);
               
            }
            for(int i=1;i<=n;i++)
             {
               if(visited[i]==0)
                {
                    visited[i]=1;
                     rec_stack[i]=1;
                    
                int k=dfs(i);
                if(k==1)
                {
                    cout<<"NO"<<endl;
                    return 0;
                }
                }   
             }
             cout<<"YES"<<endl;
             return 0;
 }


 

Sunday, 22 March 2015

Problem Statement
Markov takes out his Snakes and Ladders game and stares at the board, and wonders: If he had absolute control on the die, and could get it to generate any number (in the range 1-6) he desired, what would be the least number of rolls of the die in which he'd be able to reach the destination square (Square Number 100) after having started at the base square (Square Number 1)?
Rules
  1. Markov has total control over the die and the face which shows up every time he tosses it. You need to help him figure out the minimum number of moves in which he can reach the target square (100) after starting at the base (Square 1).
  2. A die roll which would cause the player to land up at a square greater than 100, goes wasted, and the player remains at his original square. Such as a case when the player is at Square Number 99, rolls the die, and ends up with a 5.
  3. If a person reaches a square which is the base of a ladder, (s)he has to climb up that ladder, and he cannot come down on it. If a person reaches a square which has the mouth of the snake, (s)he has to go down the snake and come out through the tail - there is no way to climb down a ladder or to go up through a snake.
Input Format
The first line contains the number of tests, T. T testcases follow.
For each testcase, there are 3 lines.
The first line contains the number of ladders and snakes, separated by a comma.
The second is a list of comma separated pairs indicating the starting and ending squares of the ladders. The first point is the square from which a player can ascend and the second point is his final position.
The third is a list of comma separated pairs indicating the starting and ending (mouth and tail) squares of the snakes. the first point is the position of the mouth of the snake and the second one is the tail.
Multiple comma separated pairs of snakes and ladders are separated by a single space.
Constraints
The board is always of the size 10 x 10
1 <= T <= 10
1 <= Number of Snakes <= 15
1 <= Number of Ladders <= 15
Squares are always numbered 1 to 100 and the order can be seen in the image above.
Output Format
For each of the T test cases, output one integer each on a new line, which is the least number of moves (or rolls of the die) in which the player can reach the target square (Square Number 100) after starting at the base (Square Number 1). This corresponds to the ideal sequence of faces which show up when the die is rolled.
Sample Input
3
3,7
32,62 42,68 12,98
95,13 97,25 93,37 79,27 75,19 49,47 67,17
5,8
32,62 44,66 22,58 34,60 2,90
85,7 63,31 87,13 75,11 89,33 57,5 71,15 55,25
4,9
8,52 6,80 26,42 2,72
51,19 39,11 37,29 81,3 59,5 79,23 53,7 43,33 77,21
Sample Output
3
3
5


############################# editorial#######################################
  we need to apply dfs starting from the cell no 1.. treat entire 2d array as a single 1d array (ie 1d array of size 100 ).. now from each position we can move to either i+1,i+2... i+6 th position..    if there is no snack or ladder at position i+1,i+2.. then simply push that block in stack with level+1(if i+k th (k=1 to 6)block have not visited with level <current level +1 ).(where level is the  step to rach ith block ). else if there is a ladder in the i+k (k=1 to 6)block then we have to push that new block which is connected  with the ladder at other end with level+1.. finally if i+k(k=1 to 6) th block contain snack then we have to go lower but if we have already covered that node (tail end of snack ) whit level <current level+1  then do not push than node in the stack.. for checking that keep a maxlev[i] array which contain best soln to reach ith block. ...




##################################code#########################################
include<iostream>
using namespace std;
#include<bits/stdc++.h>
#include<stack>
int hs[1001];/// contain hashing of snack present at index i of not
int hl[1001];//  contain hashing of  ladders  present at index i of not

int vm[1001];// contain min step required to reach ith block;
int main()
 {
     
  //freopen("abc.txt","r",stdin);
  
  int t;
    cin>>t;
 
     while(t--)
      {
       
        for(int i=0;i<102;i++)// reset hash
         {
          hs[i]=0;
          hl[i]=0;
         }
       char cc;
        int l,s;
         cin>>l>>cc>>s;
          for(int i=0;i<l;i++)
           {
            int st,en;
            char  c;
            cin>>st>>c>>en;
              hl[st]=en;//  hashing ladder 
           }
         for(int i=0;i<s;i++)
          {
             int st,en;
            char  c;
            cin>>st>>c>>en;
            hs[st]=en;//hashing snack
          }
           for(int i=0;i<110;i++)  vm[i]=INT_MAX;//mak max step initi
          
   stack<pair<int,int> > sta; contain node no and no of step to reach there
        sta.push(make_pair(1,0)); //push start at lev=1
          vm[1]=0;
          int ans=INT_MAX;
          while(!sta.empty())
           {
            int current=sta.top().first;
            int lev=sta.top().second;
            sta.pop();
             
            
              for(int i=1;i<=6;i++)
               {
                if(current+i==100   && ans>lev+1)  // if reach at 100 block with less step
                {
                 ans=lev+1;
                 
                 break;
                }
                else if(current+i>=100) 
                {
                 break;
                }
                   // if no snack and ladder then 
               else if(hs[current+i]==0  && hl[current+i]==0  && vm[current+i]>lev+1)// if this new  node is not visited earlier with less staps then only push it 
                {
                 sta.push(make_pair(current+i,lev+1));
                 vm[current+i]=lev+1;
                }
                  // if there is a snack in the current+i th block
                else if(hs[current+i]!=0  && vm[hs[current+i]]>lev+1)// if this new  node is not visited earlier with less staps then only push it 

                 {
                  //cout<<"pussing back "<<endl;
                  sta.push(make_pair(hs[current+i],lev+1));
                  vm[hs[current+i]]=lev+1;
                 }

// if there is a ladder in the current +i block 
                 else if( hl[current+i]!=0  &&  vm[hl[current+i]]>lev+1)
                  {
                   sta.push(make_pair(hl[current+i],lev+1));
                   vm[hl[current+i]]=lev+1;
                  }
                   
               }
            
           }
          cout<<ans<<endl;
      }
      
      return 0;
    
 }


Saturday, 21 March 2015

HACKERRANK   --

Even Tree


You are given a tree (a simple connected graph with no cycles). You have to remove as many edges from the tree as possible to obtain a forest with the condition that : Each connected component of the forest should contain an even number of vertices.
To accomplish this, you will remove some edges from the tree. Find out the number of removed edges.
Input Format 
The first line of input contains two integers N and M. N is the number of vertices and M is the number of edges. 
The next M lines contain two integers ui and vi which specifies an edge of the tree. (1-based index)
Output Format 
Print the answer, a single integer.
Constraints 
2 <= N <= 100.
Note: The tree in the input will be such that it can always be decomposed into components containing even number of nodes.
Sample Input
10 9
2 1
3 1
4 3
5 2
6 1
7 2
8 6
9 8
10 8
Sample Output
2
Explanation  
On removing edges (1, 3) and (1, 6), we can get the desired result.
Original tree:

Decomposed tree:


       ########### editorial###############
 in this problem we need to count no of different pair of disconnected components we can form   such that both disconnected component must contain even no of nodes ..(pair because adding even no in any no do not change its nature (even ,or odd));;;
##########  code #####################


#include<iostream>
using namespace std;
#include<bits/stdc++.h>
list<int >li[500];
int has[500][500];
int vis[10001];
int c=0;
void  bfs(int a,int b)///  count no of nodes after disconnecting grah byy
                            //deleting edge b/w node aand node b
 {
  queue<int>q;
  q.push(a);
  vis[a]=1;
  int start;
   int cou=0;
   while(!q.empty())
    {
    start=q.front();
    q.pop();
     cou++;
   
     list<int>:: iterator it;
     for(it=li[start].begin();it!=li[start].end();it++)
      {
      if(vis[*it]==0 && *it!=b)
      {
      vis[*it]=1;
      q.push(*it);
      }
     
      }
    }
    int cou1=0;
    start=b;
    q.push(b);
    vis[b]=1;
    while(!q.empty())
     {
       start=q.front();
       q.pop();
       cou1++;
       
       list<int> ::iterator it;
        for(it=li[start].begin();it!=li[start].end();it++)
         {
          if(vis[*it]==0  && *it!=a )
          {
 vis[*it]=1;
 q.push(*it);
           
          }
         }
     }
     
if(cou1%2==0 && cou%2==0) c++;  // if both dissconected                                                                        //components  contain even                                                                // no  of nodes then increase
                                                        // count 
                                                           
                                                           
                                                                         
 }
int main()
 {
  int n,m;
  cin>>n>>m;
   for(int i=1;i<=m;i++)
    {
     int a,b;
      cin>>a>>b;
       li[a].push_back(b);
       li[b].push_back(a);
       has[a][b]=1;// has contain is there any edge b/w aandb;
        has[b][a]=1;
    }
    
    for(int i=1;i<=n;i++)
     {
      for(int j=1;j<=n;j++)
       {
         if(i!=j && has[i][j]  && has[j][i])// means there is a                                                                                   edge is b/w i,j
          {
            for(int i=0;i<=n;i++) vis[i]=0;
           has[i][j]=0;//unhash 
           has[j][i]=0;// unhash
              bfs(i,j);
              
          }
       }
     }
     cout<<c<<endl;
 
 }