Monday, August 23, 2010

ACM: 114 - Simulation Wizardry

相對輕鬆一點的有趣Simulation題目,就是要仔細把文字敘述看清楚,了解遊戲規則。我覺得最重要的應該是這句話:

"A ball ''hits'' an obstacle during a timestep when it would otherwise move on top of the bumper or wall grid point. A hit causes the ball to ``rebound'' by turning right (clockwise) 90 degrees, without ever moving on top of the obstacle and without changing position (only the direction changes as a result of a rebound)."

即是球撞到障礙物(牆或bumper),都會留在原位不動,只改變下一步的方向。

其他就是照著遊戲規則simulation了。Runtime 0.044,Ranking進前100,開心開心。

CODE

#include <stdio.h>

#define MAX 50

#define GAME 0
#define VALUE 1
#define COST 2

#define RIGHT 0
#define UP 1
#define LEFT 2
#define DOWN 3

int m, n, g[3][MAX+1][MAX+1];

int pinball(int x, int y, int dir, int life);
void nextmove(int x, int y, int dir, int *arr);
int chgdir(int dir);

int main(){
  int i, j, t;
  int x, y, v1, v2, sum;
  
  scanf("%d %d", &m, &n);
  scanf("%d", &t); /*cost of hitting the wall*/
  
  /*initialize the pinball game & set walls*/
  for(i=1; i<=m; i++){
    g[GAME][1][i] = g[GAME][n][i] = 1;
    g[VALUE][1][i] = g[VALUE][n][i] = 0;
    g[COST][1][i] = g[COST][n][i] = t;
  }
  for(i=2; i<n; i++){
    for(j=1; j<=m; j++){
      if( j==1 || j==m ){
        g[GAME][i][j] = 1;
        g[VALUE][i][j] = 0;
        g[COST][i][j] = t;
      }
      else
        g[GAME][i][j] = g[VALUE][i][j] = g[COST][i][j] = 0;
    }/*j*/
  }/*i*/
  
  /*read bumpers*/
  scanf("%d", &t); /*number of bumpers*/
  for(i=0; i<t; i++){
    scanf("%d %d %d %d", &x, &y, &v1, &v2);
    
    g[GAME][x][y] = 1;
    g[VALUE][x][y] = v1;
    g[COST][x][y] = v2;
  }/*i*/
  
  /*read balls*/
  sum = t = 0;
  while( scanf("%d %d %d %d", &x, &y, &v1, &v2) != EOF ){
    t = pinball(x, y, v1, v2);
    sum += t;
    printf("%d\n", t);
  }/*while*/
  
  printf("%d\n", sum);
  exit(0);
}

int pinball(int x, int y, int dir, int life){
  int v, move[2];
  
  v = 0;
  while( life > 1 ){
    nextmove(x, y, dir, move);
    if( g[GAME][ move[0] ][ move[1] ] == 1 ){   
      life -= g[COST][ move[0] ][ move[1] ];
      v += g[VALUE][ move[0] ][ move[1] ];
      dir = chgdir(dir);
    }
    else{
      x = move[0];
      y = move[1];
    }
    
    life--;
  }/*while life > 1*/
  
  return v;
}

void nextmove(int x, int y, int dir, int *arr){
  arr[0] = x;
  arr[1] = y;
  
  switch (dir) {
    case RIGHT:
      arr[0]++;
      break;
    case UP:
      arr[1]++;
      break;
    case LEFT:
      arr[0]--;
      break;
    case DOWN:
      arr[1]--;
      break;
    default: break;
  }
}

int chgdir(int dir){
  if( dir == RIGHT )
    dir = DOWN;
  else
    dir--;
    
  return dir;
}

No comments:

Post a Comment