Tuesday, February 12, 2013

February 2013 Bronze Problem 3: Perimeter

Result: 1/10 *xxxxxxxxx

I found out that this solution is flawed because it doesn't "fill the holes" correctly. It fails when there are two adjacent hole cells.

perimeter.cpp

#include <iostream>
#include <fstream>
 
#define loopi(x) loop_start(i,x,0)
#define loopj(x) loop_start(j,x,0)
#define loop_start(i, x,s) for(int i = (s); i < (x); ++i)
#define loop_rev(a,x,stop) for(int a = (x); a >= (stop); --a)
 
using namespace std;

typedef unsigned short ushort;

#define GRIDSIZE 100
bool grid[GRIDSIZE][GRIDSIZE] = { { false } };

char adjacent_occupied(int x, int y){
 char ret = 0;
 if(x > 1){
  if(grid[x - 1][y]) ++ret;
 }
 if(x + 1 < GRIDSIZE){
  if(grid[x + 1][y]) ++ret;
 }
 if(y > 1){
  if(grid[x][y - 1]) ++ret;
 }
 if(y + 1 < GRIDSIZE){
  if(grid[x][y + 1]) ++ret;
 }
 return ret;
}

// optimized version of above for checking for a return of 4
bool adjacent_all_occupied(int x, int y){
 if(x <= 1 || x + 1 >= GRIDSIZE || y <= 1 || y + 1 >= GRIDSIZE) return false;
 return grid[x - 1][y] && grid[x + 1][y] && grid[x][y - 1] && grid[x][y + 1];
}

int main() {
 ofstream fout ("perimeter.out");
 ifstream fin ("perimeter.in");
 // get input
 int N;
 fin >> N;
 loopi(N){
  char x, y;
  fin >> x >> y;
  grid[x-1][y-1] = true;
 }
 // process
 ushort edges = 0;
 // fill holes
 loopi(GRIDSIZE)
  loopj(GRIDSIZE){
   if(!grid[i][j] && adjacent_all_occupied(i, j))
    grid[i][j] = true;
  }
 // count edges
 loopi(GRIDSIZE)
  loopj(GRIDSIZE)
   if(grid[i][j])
    edges += 4 - adjacent_occupied(i,j);
 // output
 fout << edges << endl;
 // cleanup
 fin.close();
 fout.close();
 return 0;
}

No comments:

Post a Comment