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

日々精進

aikoと旅行とプログラミング

【AOJ 1193】Chain Disappearance Puzzle

問題

連鎖消滅パズル | Aizu Online Judge

方針

  1. 横に3つ以上連鎖している箇所は消すことができる.
  2. 消えた部分には, 上にある石が空きを埋めるように落ちてくる.
  3. すべての石を落とした後に消滅の条件をみたすようなものがあればまた繰り返す.
    上の通りにシミュレーションする.

コード

#include <iostream>
#include <algorithm>

using namespace std;

#define REP(i,a,n) for(int i = a ; i < (int)n ; i++)
#define rep(i,n) REP(i,0,n)

int h;
int field[20][10];

signed main(){

  while(cin >> h, h){
    rep(i, h){
      rep(j, 5){
        cin >> field[i][j];
      }
    }
 
    int ans = 0;
    bool flag = true;
    while(flag){
      int tmp = 0;

      rep(i, h){
        int prev = -1;
        int count = 0;
        int start = 0;

        REP(j, 0, 5){
          if(prev == field[i][j] && field[i][j] > 0){
            count++;
        
            if(count >= 3 && field[i][j+1]!=field[i][j]){
              REP(k, 0, count){
                tmp += field[i][start+k];
                field[i][start+k] = -1;
              }
              count = 1;
            }
          }else{
            if(count >= 3){
              REP(k, 0, count){
                tmp += field[i][start+k];
                field[i][start+k] = -1;
              }
            }
            start = j;
            count = 1;
            prev = field[i][j];
          }
        }
      }

      if(tmp == 0){
        cout << ans << endl;
        flag = false;
        continue;
      }
      
      ans += tmp;
      
      REP(k, 1, h){
        rep(l, 5){
          if(field[k][l] == -1 && field[k-1][l]){
            for(int m = k ; m > 0 ; m--){
              swap(field[m][l], field[m-1][l]);
            }
          }
        }
      }      
    } 
  }

}