Barn Repair : USACO, Greedy algorithms
by Abhijeet Kashnia
It is beginning to take huge amounts of time to solve these problems, simply because I refuse to read the writeup/tutorials from USACO and also the problem statement properly, and am not as disciplined as I need to be to cover the corner cases in the first cut itself.
Must approach the problem step by step, it is almost always easier than it seems once I start writing the conditions in code.
Must consider what happens if the input is not in sorted order and if the loop breaking conditions are comprehensive.
I was very sloppy when it came to implementation, and refused to observe carefully the boundary conditions. Maybe it is because I write this in the middle of the night.
Another factor that concerns me is the length of this code. Time taken to write code is related to its length, and it needs to get much shorter to be useful.
I think writing the complete logic in detail on paper might be a good exercise, just to see if the IDE is making me too lazy.
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;
public class barn1
{
static boolean[] stallStatus ;
static int[] occupiedPositions;
static boolean[] answer;
static int maxBoards=0, stalls=0, countCows=0;
public static void main(String[] args) throws NumberFormatException, IOException
{
// READ INPUTS
BufferedReader reader = new BufferedReader(new FileReader(new File("barn1.in")));
StringTokenizer tokenizer = new StringTokenizer(reader.readLine());
// INITIALIZE VARIABLES
maxBoards = Integer.parseInt(tokenizer.nextToken());
stalls = Integer.parseInt(tokenizer.nextToken());
countCows = Integer.parseInt(tokenizer.nextToken());
answer= new boolean[stalls+1];
Arrays.fill(answer, false);
occupiedPositions = new int[countCows];
// STORE POSITIONS OCCUPIED BY COWS
for(int i=0;i<countCows;i++) {
int position=Integer.parseInt(reader.readLine());
occupiedPositions[i]=position;
answer[position]=true;
}
Arrays.sort(occupiedPositions);
// Select the board which has longest section that does not need to be covered.
// First, assume that the complete space is one board.
// Guess, we need to keep track of all boards, and search only within all boards.
// ith position is for ith board
int[] boardBegin = new int[maxBoards+1];
int[] boardEnd = new int[maxBoards+1];
int boardCreated=0;
boardBegin[boardCreated]=occupiedPositions[0];
boardEnd[boardCreated]=occupiedPositions[countCows-1];
// iterate over space between each board, using answer array.
// this should be run length encoding type code to find the longest unoccupied length.
boardCreated++;
int selectedBoardIndex=0;
while(boardCreated<maxBoards) { // DO THIS UNTIL WE HAVE BROKEN TO DESIRED COUNT
// Finding the longest run in all boards.
int longestRun=0, thisRun=0, startPosition=0;
for(int boardIndex=0;boardIndex<=boardCreated;boardIndex++) { // IN RANGE MENTIONED
for(int k=boardBegin[boardIndex]; k<boardEnd[boardIndex];) {
if(!answer[k]) {
thisRun++;
if(thisRun>longestRun) {
longestRun=thisRun;
selectedBoardIndex=boardIndex;
startPosition=k-thisRun+1;
}
}
else {
thisRun=0;
}
k=k+1;
}
}
// System.out.println("Longest run is : " + longestRun + " from,to :" + (startPosition-1) + " " + (startPosition + longestRun));
// Breaking the board.
boardEnd[boardCreated] = boardEnd[selectedBoardIndex];
boardEnd[selectedBoardIndex]=startPosition-1;
boardBegin[boardCreated]=startPosition + longestRun;
sort(boardBegin, boardEnd, boardCreated);
printBoards(boardBegin, boardEnd, boardCreated);
boardCreated++;
int counter=0;
for(int boardIndex=0;boardIndex<boardCreated;boardIndex++) {
for(int k=boardBegin[boardIndex]; k<=boardEnd[boardIndex]; k++) {
// if(answer[k]) {
counter++;
// }
}
}
if(counter==countCows) {
break;
}
}
// CALCULATING STALLS BLOCKED
int counter=0;
for(int boardIndex=0;boardIndex<boardCreated;boardIndex++) {
for(int k=boardBegin[boardIndex]; k<=boardEnd[boardIndex]; k++) {
// if(answer[k]) {
counter++;
// }
}
}
// System.out.println(counter);
PrintWriter out = new PrintWriter(new File("barn1.out"));
out.println(counter);
out.close();
System.exit(0);
}
private static void sort(int[] boardBegin, int[] boardEnd, int boardCreated)
{
for(int i=0;i<=boardCreated;i++) {
for(int j=i+1;j<=boardCreated;j++) {
if(boardBegin[j]<boardBegin[i]) {
int temp = boardBegin[i];
boardBegin[i]=boardBegin[j];
boardBegin[j]=temp;
temp = boardEnd[i];
boardEnd[i]=boardEnd[j];
boardEnd[j]=temp;
}
}
}
}
private static void printBoards(int[] boardBegin, int[] boardEnd, int boardCreated)
{
for(int i=0;i<=boardCreated;i++) {
System.out.print("(" + boardBegin[i] + "," + boardEnd[i] + ")");
}
System.out.println();
}
}