Problem p01125 (C++) — buggy submission, verdict: Runtime Error

#pragma warning(disable : 4996)
#include <map>
#include <stdio.h>
#include <vector>

typedef unsigned int DWORD; // DWORD

// ２次元ベクトルクラス
class Vector2 {

public:
  Vector2() { x = y = 0; }

  Vector2(int _x, int _y) {

    x = _x;
    y = _y;
  }

  int x;
  int y;

  Vector2 operator+(Vector2 &_Arg) {

    Vector2 ret;

    ret.x = x + _Arg.x;
    ret.y = y + _Arg.y;

    return ret;
  }

  void operator+=(Vector2 &_Arg) {

    x += _Arg.x;
    y += _Arg.y;
  }

  Vector2 operator*(int &_Arg) {

    Vector2 ret(x * _Arg, y * _Arg);

    return ret;
  }

  void operator*=(int &_Arg) {

    x *= _Arg;
    y *= _Arg;
  }

  bool operator==(Vector2 &_Arg) { return (x == _Arg.x && y == _Arg.y); }

  bool operator!=(Vector2 &_Arg) { return (x != _Arg.x || y != _Arg.y); }

  static Vector2 Normalize(Vector2 _Vec) {

    Vector2 ret;

    if (_Vec.x > 0)
      ret.x = 1;
    else if (_Vec.x < 0)
      ret.x = -1;
    else
      ret.x = 0;

    if (_Vec.y > 0)
      ret.y = 1;
    else if (_Vec.y < 0)
      ret.y = -1;
    else
      ret.y = 0;

    return ret;

  } // 正規化
};

// ワールド情報クラス
class World {

public:
  World() {

    for (int i = 0; i < Width; i++) {

      for (int j = 0; j < Height; j++) {

        m_ItemFlag[i][j] = false;
      }
    }

  } // コンストラクタ

  bool IsInArea(Vector2 _Pos) {

    return (_Pos.x >= 0 && _Pos.x < Width && _Pos.y >= 0 && _Pos.y < Height);

  } // 範囲内か？

  bool IsInArea(int _x, int _y) {

    return (_x >= 0 && _x < Width && _y >= 0 && _y < Height);

  } // 範囲内か？

  void SetItem(Vector2 _Pos) {

    if (IsInArea(_Pos))
      m_ItemFlag[_Pos.x][_Pos.y] = true;

  } // アイテムをセット

  void SetItem(DWORD _x, DWORD _y) {

    if (IsInArea(_x, _y))
      m_ItemFlag[_x][_y] = true;

  } // アイテムをセット

  bool GetItem(Vector2 _Pos) {

    if (IsInArea(_Pos) && m_ItemFlag[_Pos.x][_Pos.y]) {

      m_ItemFlag[_Pos.x][_Pos.y] = false;
      return true;
    }

    return false;

  } // 指定した座標にあるアイテムを取得
  bool GetItem(DWORD _x, DWORD _y) {

    if (IsInArea(_x, _y) && m_ItemFlag[_x][_y]) {

      m_ItemFlag[_x][_y] = false;
      return true;
    }

    return false;

  } // 指定した座標にあるアイテムを取得

  DWORD GetItemsPosToPos(Vector2 _Start, Vector2 _MoveVec) {

    DWORD ret = 0;

    Vector2 LoopEnd(0, 0);

    while (_MoveVec != LoopEnd) {

      Vector2 Move = Vector2::Normalize(_MoveVec);

      if (GetItem(_Start + Move))
        ret++;

      if (_MoveVec.x > 0)
        _MoveVec.x--;
      else if (_MoveVec.x < 0)
        _MoveVec.x++;
      if (_MoveVec.y > 0)
        _MoveVec.y--;
      else if (_MoveVec.y < 0)
        _MoveVec.y++;
      _Start += Move;
    }

    return ret;

  } //_Startから_MoveVec移動した場合に取得できる

  enum {

    Width = 21, // 幅
    Height = 21 // 高さ

  };

  DWORD GetItemNum() {

    DWORD ret = 0;

    for (int i = 0; i < Width; i++) {

      for (int j = 0; j < Height; j++) {

        if (m_ItemFlag[i][j])
          ret++;
      }
    }

    return ret;

  } // ワールド上に落ちている残りアイテム数を取得

private:
  bool m_ItemFlag[Width][Height]; // アイテムフラグ
};

int main() {

  std::map<char, Vector2> MoveMap; // 移動方向
  std::vector<bool> ClearFlag;     // クリアフラグ
  MoveMap['N'] = Vector2(0, 1);
  MoveMap['E'] = Vector2(1, 0);
  MoveMap['S'] = Vector2(0, -1);
  MoveMap['W'] = Vector2(-1, 0);

  while (true) {

    DWORD n;
    World w;
    scanf("%d", &n);

    if (n == 0)
      break;

    for (DWORD i = 0; i < n; i++) {

      Vector2 ItemPos;
      scanf("%d %d", &ItemPos.x, &ItemPos.y);
      w.SetItem(ItemPos);
    }

    DWORD m;
    scanf("%d", &m);

    Vector2 Position(10, 10);

    for (DWORD i = 0; i < m; i++) {

      char c, Dummy;
      int v;
      scanf("%c%c %d", &Dummy, &c, &v);

      Vector2 MoveVec = MoveMap[c] * v;

      w.GetItemsPosToPos(Position, MoveVec);
      Position += MoveVec;
    }

    ClearFlag.push_back(w.GetItemNum() == 0);
  }

  for (DWORD i = 0; i < ClearFlag.size(); i++) {

    if (ClearFlag[i])
      printf("Yes\\n");
    else
      printf("No\\n");
  }

  return 0;
}

Error: WA

Fixed submission:

#pragma warning(disable : 4996)
#include <map>
#include <stdio.h>
#include <vector>

typedef unsigned int DWORD; // DWORD

// ２次元ベクトルクラス
class Vector2 {

public:
  Vector2() { x = y = 0; }

  Vector2(int _x, int _y) {

    x = _x;
    y = _y;
  }

  int x;
  int y;

  Vector2 operator+(Vector2 &_Arg) {

    Vector2 ret;

    ret.x = x + _Arg.x;
    ret.y = y + _Arg.y;

    return ret;
  }

  void operator+=(Vector2 &_Arg) {

    x += _Arg.x;
    y += _Arg.y;
  }

  Vector2 operator*(int &_Arg) {

    Vector2 ret(x * _Arg, y * _Arg);

    return ret;
  }

  void operator*=(int &_Arg) {

    x *= _Arg;
    y *= _Arg;
  }

  bool operator==(Vector2 &_Arg) { return (x == _Arg.x && y == _Arg.y); }

  bool operator!=(Vector2 &_Arg) { return (x != _Arg.x || y != _Arg.y); }

  static Vector2 Normalize(Vector2 _Vec) {

    Vector2 ret;

    if (_Vec.x > 0)
      ret.x = 1;
    else if (_Vec.x < 0)
      ret.x = -1;
    else
      ret.x = 0;

    if (_Vec.y > 0)
      ret.y = 1;
    else if (_Vec.y < 0)
      ret.y = -1;
    else
      ret.y = 0;

    return ret;

  } // 正規化
};

// ワールド情報クラス
class World {

public:
  World() {

    for (int i = 0; i < Width; i++) {

      for (int j = 0; j < Height; j++) {

        m_ItemFlag[i][j] = false;
      }
    }

  } // コンストラクタ

  bool IsInArea(Vector2 _Pos) {

    return (_Pos.x >= 0 && _Pos.x < Width && _Pos.y >= 0 && _Pos.y < Height);

  } // 範囲内か？

  bool IsInArea(int _x, int _y) {

    return (_x >= 0 && _x < Width && _y >= 0 && _y < Height);

  } // 範囲内か？

  void SetItem(Vector2 _Pos) {

    m_ItemFlag[_Pos.x][_Pos.y] = true;

  } // アイテムをセット

  void SetItem(DWORD _x, DWORD _y) {

    m_ItemFlag[_x][_y] = true;

  } // アイテムをセット

  bool GetItem(Vector2 _Pos) {

    if (IsInArea(_Pos) && m_ItemFlag[_Pos.x][_Pos.y]) {

      m_ItemFlag[_Pos.x][_Pos.y] = false;
      return true;
    }

    return false;

  } // 指定した座標にあるアイテムを取得
  bool GetItem(DWORD _x, DWORD _y) {

    if (IsInArea(_x, _y) && m_ItemFlag[_x][_y]) {

      m_ItemFlag[_x][_y] = false;
      return true;
    }

    return false;

  } // 指定した座標にあるアイテムを取得

  DWORD GetItemsPosToPos(Vector2 _Start, Vector2 _MoveVec) {

    DWORD ret = 0;

    Vector2 LoopEnd(0, 0);

    while (_MoveVec != LoopEnd) {

      Vector2 Move = Vector2::Normalize(_MoveVec);

      if (GetItem(_Start + Move))
        ret++;

      if (_MoveVec.x > 0)
        _MoveVec.x--;
      else if (_MoveVec.x < 0)
        _MoveVec.x++;
      if (_MoveVec.y > 0)
        _MoveVec.y--;
      else if (_MoveVec.y < 0)
        _MoveVec.y++;
    }

    return ret;

  } //_Startから_MoveVec移動した場合に取得できる

  enum {

    Width = 20, // 幅
    Height = 20 // 高さ

  };

  DWORD GetItemNum() {

    DWORD ret = 0;

    for (int i = 0; i < Width; i++) {

      for (int j = 0; j < Height; j++) {

        if (m_ItemFlag[i][j])
          ret++;
      }
    }

    return ret;

  } // ワールド上に落ちている残りアイテム数を取得

private:
  bool m_ItemFlag[Width][Height]; // アイテムフラグ
};

int main() {

  std::map<char, Vector2> MoveMap; // 移動方向
  std::vector<bool> ClearFlag;     // クリアフラグ
  MoveMap['N'] = Vector2(0, 1);
  MoveMap['E'] = Vector2(1, 0);
  MoveMap['S'] = Vector2(0, -1);
  MoveMap['W'] = Vector2(-1, 0);

  while (true) {

    DWORD n;
    World w;
    scanf("%d", &n);

    if (n == 0)
      break;

    for (DWORD i = 0; i < n; i++) {

      Vector2 ItemPos;
      scanf("%d %d", &ItemPos.x, &ItemPos.y);
      w.SetItem(ItemPos);
    }

    DWORD m;
    scanf("%d", &m);

    Vector2 Position(10, 10);

    for (DWORD i = 0; i < m; i++) {

      char c, Dummy;
      int v;
      scanf("%c%c %d", &Dummy, &c, &v);

      Vector2 MoveVec = MoveMap[c] * v;

      w.GetItemsPosToPos(Position, MoveVec);
      // Position += MoveVec;
    }

    // ClearFlag.push_back( w.GetItemNum() == 0 );
  }

  for (DWORD i = 0; i < ClearFlag.size(); i++) {

    if (ClearFlag[i])
      printf("Yes\\n");
    else
      printf("No\\n");
  }

  return 0;
}