読者です 読者をやめる 読者になる 読者になる

Tamflexの貯蔵庫

やる気のない備忘録

codingame - The Paranoid Android

CodinGame c++

そこまで難しくはないが例外処理に手間取った.

struct Info
{
  int floor;
  int pos;
  Info(){};
  Info(int f,int p):floor(f),pos(p){};
  bool operator==(const Info &a)
  {
    return floor==a.floor && pos==a.pos;
  }
};

const int SPACE = 0;
const int BLOCK = 1;
const int ELEVS = 2;
const int GOALS = 3;

int main()
{
  int nf; // number of floors
  int w; // width of the area
  int r; // maximum number of rounds
  int nc; // number of generated clones
  int nba; // ignore (always zero)
  int ne; // number of elevators
  Info e, target;
  cin >> nf >> w >> r >> e.floor >> e.pos >> nc >> nba >> ne; cin.ignore();
  vector<Info> a(ne);
  vector<vector<int> > T(nf,vector<int>(w,SPACE));
  REP(i,ne) cin >> a[i].floor >> a[i].pos;
  REP(i,ne) T[a[i].floor][a[i].pos] = ELEVS;
  T[e.floor][e.pos] = GOALS;
  bool change = true, reach = false;
  while (1)
  {
    Info c;
    string d; // direction of the leading clone: LEFT or RIGHT
    bool command = true;
    cin >> c.floor >> c.pos >> d; cin.ignore();
    int dir = (d=="RIGHT")?1:-1;
    cerr << c.floor << " " << c.pos << " " << dir << endl;
    if(c==Info(-1,-1))
    {
      cerr << "no clone" << endl;
      cout << "WAIT" <<endl;
      command = false;
    }
    else if(T[c.floor][c.pos]==BLOCK)
    {
      cerr << "yet changed" << endl;
      cout << "WAIT" <<endl;
      command = false;
    }
    else if(change)
    {
      cerr << "new clone ";
      Info t = c;
      bool flag = false;
      int cnt = 0;
      int id = c.pos+dir>w?w-1:(c.pos+dir<0?0:c.pos+dir);
      target = Info(c.floor,id);
      while(t.pos >= 0 && t.pos < w)
      {
        switch (T[t.floor][t.pos])
        {
          case SPACE:
            t.pos += dir;
            break;
          case BLOCK:
            dir *= -1;
            t.pos += dir*2;
            break;
          case ELEVS:
            t.floor++;
            if(!e.floor<t.floor) target = Info(t.floor,t.pos+dir);
            break;
          case GOALS:
            flag = true;
            break;
          default :
            break;
        }
        if(flag) break;
        if(e.floor<t.floor) break;
        if(++cnt > r) break;
      }
      change = false;
      reach = flag;
    }
    if(command)
    {
      if(reach)
      {
        cerr << "can reach goal" << endl;
        cout << "WAIT" << endl;
      }
      else if(c==target)
      {
        cerr << "arrived at target" << endl;
        cout << "BLOCK" << endl;
        T[c.floor][c.pos] = BLOCK;
        change = true;
      }
      else
      {
        cout << "WAIT" << endl;
        cerr << "toward " << target.floor << " " << target.pos << endl;
      }
    }
  }
}