Comments

Sunday, May 6, 2012

Algorithm Tutorials - Part 1 : Ad-Hoc Problems

Posted by on Sunday, May 6, 2012 Read our previous post
I will start with the very basic of Algorithms.

Before moving on to the different algorithms, let's first see what does an algorithm actually mean?



Definition


A process or set of rules to be followed in calculations or other problem-solving operations, esp. by a computer.  


Aho, Hopcroft and Ullman, had stated in their book on algorithms, named, "The Design and Analysis of Computer Algorithms" that "Perhaps the most important principle for the good algorithm designer is to refuse to be content."



There are only 16 types of Programming Contest Problems available, viz. :

1. Ad-Hoc
2. Greedy
3. Computational Geometry
4. Dynamic Programming
5. BigNums
6. Two-Dimensional
7. Eulerian Path
8. Minimum Spanning Tree
9. Knapsack
10. Network Flow
11. Flood Fill
12. Shortest Path
13. Approximate Search
14. Complete Search
15. Recursive Search Techniques
16. Heuristic Search


I will cover all of the above topics, one-by-one.

First, we will start up with the very basic one, i.e. the Ad-Hoc Problems.

Ad-Hoc Problems


There are some problems, whose algorithms do not fall into well studied solutions of standard categories.

Ad-Hoc falls in one of them. Each and every Ad-Hoc problem is unique, different from other problems, and no general solution or technique exist to solve them.

Well, it is good to come across such problems, as your brain will be shaped in a way to crack a problem in many different ways. The solutions might require a complete new user-made data structure, or some sort of special combinations, or unusual set of loops or conditions.

While solving Ad-Hoc problems, you are required to read the problem very carefully, and produce a solution which satisfies all the constraints and conditions mentioned in the Problem Statement.

Though, each and every problem requires a new solution, it is mandatory to keep in mind that Time and Space trade-offs are still maintained. For that, you need to optimize your code, and come up with an efficient solution.


Now, Let us take a look at the following example :


Problem Statement  (Reference Link : http://ace.delos.com/)








Broken Necklace


You have a necklace of N red, white, or blue beads (3<=N<=350) some of which are red, others blue, and others white, arranged at random. Here are two examples for n=29:
The beads considered first and second in the text that follows have been marked in the picture.

The configuration in Figure A may be represented as a string of b's and r's, where b represents a blue bead and r represents a red one, as follows: brbrrrbbbrrrrrbrrbbrbbbbrrrrb .

Suppose you are to break the necklace at some point, lay it out straight, and then collect beads of the same color from one end until you reach a bead of a different color, and do the same for the other end (which might not be of the same color as the beads collected before this).

Determine the point where the necklace should be broken so that the most number of beads can be collected.

Example

For example, for the necklace in Figure A, 8 beads can be collected, with the breaking point either between bead 9 and bead 10 or else between bead 24 and bead 25.

In some necklaces, white beads had been included as shown in Figure B above. When collecting beads, a white bead that is encountered may be treated as either red or blue and then painted with the desired color. The string that represents this configuration will include the three symbols r, b and w.

Write a program to determine the largest number of beads that can be collected from a supplied necklace.

PROGRAM NAME: beads

INPUT FORMAT

Line 1:N, the number of beads
Line 2:a string of N characters, each of which is r, b, or w

SAMPLE INPUT (file beads.in)

29
wwwbbrwrbrbrrbrbrwrwwrbwrwrrb

OUTPUT FORMAT

A single line containing the maximum of number of beads that can be collected from the supplied necklace.

SAMPLE OUTPUT (file beads.out)

11

OUTPUT EXPLANATION

Consider two copies of the beads (kind of like being able to runaround the ends). The string of 11 is marked.
wwwbbrwrbrbrrbrbrwrwwrbwrwrrb wwwbbrwrbrbrrbrbrwrwwrbwrwrrb
****** *****
<-- assignments 5 x r 6 x b
rrrrrb bbbbb
<-- 11 total



Solution :

The Problem is very simple. There is not much explanation required to understand the logic behind this problem. You need to find the maximum number of beads that can be collected, as per the given conditions.

In this problem, the necklace size is small enough (350) that we might as well just try breaking the necklace at each point and see how many beads can be collected. This will take approximately O(n^2) time, but n is small enough that it won't matter.

I have used a simple Brute-Force approach.

A Brute-Force approach is nothing but trying and testing all the possible solutions, i.e. all the possible permutations and combinations, and find the desired solution. This method is a bit slower, and takes more time to solve.

Java Code :


/*
ID: prattsi1
LANG: JAVA
TASK: beads
 */

package com.usaco.training.section.one.one;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Scanner;

public class beads {

   public static void main(String[] args) throws FileNotFoundException {


      Scanner sc = new Scanner(new File("C:/Users/PRASAM ENTERPRISE/workspace
/USACO/Training/com/usaco/training/section/one/one/beads.in"));

       PrintWriter out = new PrintWriter(new File ("C:/Users/PRASAM ENTERPRISE
/workspace/USACO/Training/com/usaco/training/section/one/one/beads.out"));

       final int N = Integer.parseInt(sc.nextLine());

       String necklaceBeads = sc.nextLine();
 
       int maxBeads = 0;
 
       for (int i = 0; i < N; i++) {
 
           int count = 0;

           String straightNecklaceBeads = necklaceBeads.substring(i + 1)
 
                   + necklaceBeads.substring(0, i + 1);

            char colorCheck = ' ';
            for (int j = 0; j < straightNecklaceBeads.length(); j++) {
                if (straightNecklaceBeads.charAt(j) == 'w')
                    count++;
                else if (colorCheck == ' ') {
                    colorCheck = straightNecklaceBeads.charAt(j);
                    count++;
                } else {
                     if (straightNecklaceBeads.charAt(j) == colorCheck)
                        count++;
                     else 
                       break;
               }
            }

            colorCheck = ' ';
            
             for (int j = (straightNecklaceBeads.length() - 1); j >= 0; j--) {
                if (straightNecklaceBeads.charAt(j) == 'w')
                    count++;
                else if (colorCheck == ' ') {
                    colorCheck = straightNecklaceBeads.charAt(j);
                    count++;
                } else {
                    if (straightNecklaceBeads.charAt(j) == colorCheck) 
                        count++;
                    else        
                       break;
               }
            }
            maxBeads = Math.max(maxBeads, count);
        }

          if (maxBeads > N)
           maxBeads = N;
           out.println(maxBeads);
           out.close();
           System.exit(0);
       }
}



P.S. You may have a better and an efficient solution than mine. So, please share it with others, too.

Note : 

I will post a video related to this article, very soon, which will contain the detailed explanation of Ad-Hoc Problems, Broken Necklace complete Explanation of the Code, and the logic behind the Problem, and some more Ad-Hoc Examples.

© 2010 Code 2 Learn