備忘録

まとめておきたいことのメモ 主にプロコンのこと

AOJ-ICPC 2000

ちょっと前に解いてここに書くのを忘れていたやつ。

Misterious Gems | Aizu Online Judge

20×20マスの幾つかに宝石が転がっています。始めに(x,y)=(10, 10)のところにいるロボットが指示通りに動いたときに全部の宝石を回収できるかどうか判定しなさい、という問題です。
解答はこちら。

#include <cstdio>
#include <iostream>
#include <cmath>
#include <ctype.h>
#include <string> 
#include <sstream>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <map>
#include <queue>
#include <utility>
#include <vector>
#include <set>
  
using namespace std;
 
int main()
{
    int N;
    while(1){
        cin >> N;
        if(N == 0) break;
        int gemmap[21][21] = {0};
        int gem_x, gem_y;
        for(int i = 0; i < N; i++){
            cin >> gem_x >> gem_y;
            gemmap[gem_x][gem_y] = 1;
        }
        int M;
        cin >> M;
        char direction;
        int howfar;
        int now_x = 10, now_y = 10;
        int get_gem = 0;
        for(int i = 0; i < M; i++){
            cin >> direction >> howfar;
            if(direction == 'N'){
                for(int j = 1; j <= howfar; j++){
                    now_y++;
                    if(gemmap[now_x][now_y] == 1){
                        get_gem++;
                        gemmap[now_x][now_y] = 0;
                    }
                }
            }else if(direction == 'E'){
                for(int j = 1; j <= howfar; j++){
                    now_x++;
                    if(gemmap[now_x][now_y] == 1){
                        get_gem++;
                        gemmap[now_x][now_y] = 0;
                    }
                }
            }else if(direction == 'S'){
                for(int j = 1; j <= howfar; j++){
                    now_y--;
                    if(gemmap[now_x][now_y] == 1){
                        get_gem++;
                        gemmap[now_x][now_y] = 0;
                    }
                }
            }else if(direction == 'W'){
                for(int j = 1; j <= howfar; j++){
                    now_x--;
                    if(gemmap[now_x][now_y] == 1){
                        get_gem++;
                        gemmap[now_x][now_y] = 0;
                    }
                }
            }
        }
        if(get_gem == N) cout << "Yes" << endl;
        else cout << "No" << endl;
    }
   return 0;
}

宝石があるマスを記録するための二次元配列gemmapを用いて、(x, y)に宝石があるときgemmap[x][y]の値を1にしておきます。
その後指示通りにロボットを動かすようにします。変数directionに方向、変数howfarに距離を記録。その後directionに合わせて一マスずつ動かし、その場所に宝石がある場合はget_gem(今まで手に入れた宝石の数)に1を加えgemmap[x][y]の値を0にします。0にすることで二重に数えてしまうのを防ぎます。最終的にget_gemの値とすべての宝石の数が一致すればYes、そうでないときはNoを表示します。

今回はdirectionで一つ一つ場合分けしたのですが、もうちょっと綺麗に書きたいなと思いました。