備忘録

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

AOJ-ICPC 1193

今日友人に勧められて解いた問題。

Chain Disappearance Puzzle | Aizu Online Judge

通称(?)ぷよぷよ問題。
同じ数字が横に3つ以上並んだ時に消え、上から降ってくる…という感じの問題。
友人曰くすぐ解けるそうなのでチャレンジ、1時間半ぐらいかかった気がする。

#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 delete_piece();
 
int puzzle[10][5];
int h;
 
int main()
{
    while(1){
        cin >> h;
        if(h == 0) break;
        for(int i = h - 1; i >= 0; i--){
            for(int j = 0; j < 5; j++){
                cin >> puzzle[i][j];
            }
        }
        int get_score = 0;
        int total_score = 0;
        while(1){
            get_score = delete_piece();
            if(get_score == 0) break;
            else total_score += get_score;
        }
        cout << total_score << endl;
    }
    return 0;
}
 
int delete_piece()
{
    int sum_score = 0;
    for(int i = h - 1; i >= 0; i--){
        int delete_start = 0;
        int delete_end = 0;
        for(int j = 0; j < 3; j++){
            if(puzzle[i][j] != 0 && puzzle[i][j] == puzzle[i][j + 1] && puzzle[i][j] == puzzle[i][j + 2]){
                delete_start = j;
                if(j == 0){
                    if(puzzle[i][j] == puzzle[i][j + 3]){
                        if(puzzle[i][j] == puzzle[i][j + 4]) delete_end = 5;
                        else delete_end = 4;
                    } else delete_end = 3;
                } else if(j == 1){
                    if(puzzle[i][j] == puzzle[i][j + 3]) delete_end = 4;
                    else delete_end = 3;
                } else delete_end = 3;
                break;
            }
        }
        if(delete_end == 0) continue;
        sum_score += puzzle[i][delete_start] * delete_end;
        for(int j = delete_start; j < delete_start + delete_end; j++){
            puzzle[i][j] = 0;
        }
    }
    if(sum_score == 0) return 0;
    for(int i = 0; i < h; i++){
        for(int j = 0; j < 5; j++){
            if(puzzle[i][j] == 0){
                if(i != h - 1){
                    for(int k = 1; i + k < h; k++){
                        if(puzzle[i + k][j] != 0){
                            puzzle[i][j] = puzzle[i + k][j];
                            puzzle[i + k][j] = 0;
                            break;
                        }
                    }
                } else puzzle[i][j] = 0;
            }
        }
    }
    return sum_score;
}

一番下を0段目にしたかったので、for文をh - 1からまわして数列を読み込んだ。
(あっでもdelete_pieceでは上から調べてるな…このへんごちゃごちゃして統一されてない。)
その後delete_pieceを用いていくつ連続しているか調べ、連続しているところを0に置き換え、上から下へ一個ずつ落としていきました。

消える箇所を確認する部分がかなりごちゃごちゃしてしまって反省。
でもけっこうすんなり通ったのでよかった。