csp 201512-2 消除類遊戲
- 題目
問題描述
消除類遊戲是深受大眾歡迎的一種遊戲,遊戲在一個包含有n行m列的遊戲棋盤上進行,棋盤的每一行每一列的方格上放著一個有顏色的棋子,當一行或一列上有連續三個或更多的相同顏色的棋子時,這些棋子都被消除。當有多處可以被消除時,這些地方的棋子將同時被消除。
現在給你一個n行m列的棋盤,棋盤中的每一個方格上有一個棋子,請給出經過一次消除後的棋盤。
請注意:一個棋子可能在某一行和某一列同時被消除。
輸入格式
輸入的第一行包含兩個整數n, m,用空格分隔,分別表示棋盤的行數和列數。
接下來n行,每行m個整數,用空格分隔,分別表示每一個方格中的棋子的顏色。顏色使用1至9編號。
輸出格式
輸出n行,每行m個整數,相鄰的整數之間使用一個空格分隔,表示經過一次消除後的棋盤。如果一個方格中的棋子被消除,則對應的方格輸出0,否則輸出棋子的顏色編號。
樣例輸入
4 5
2 2 3 1 2
3 4 5 1 4
2 3 2 1 3
2 2 2 4 4
樣例輸出
2 2 3 0 2
3 4 5 0 4
2 3 2 0 3
0 0 0 4 4
樣例說明
棋盤中第4列的1和第4行的2可以被消除,其他的方格中的棋子均保留。
樣例輸入
4 5
2 2 3 1 2
3 1 1 1 1
2 3 2 1 3
2 2 3 3 3
樣例輸出
2 2 3 0 2
3 0 0 0 0
2 3 2 0 3
2 2 0 0 0
樣例說明
棋盤中所有的1以及最後一行的3可以被同時消除,其他的方格中的棋子均保留。
評測用例規模與約定
所有的評測用例滿足:1 ≤ n, m ≤ 30。
- 基本思路
這題因為n,m比較小,可以採取暴力的方式解決,因為這個遊戲規則就是某行或某列存在3個或3個以上的數字相同就可以消除掉,所以我們可以遍歷行和列,分別開兩個for迴圈去做,然後如果存在3個或3個以上的數字就用一個數組去標記,可以消除掉的就是1,不能消除掉的就是0,輸出原來的數字就可以了。
- 演算法思想
這題最關鍵的演算法就是陣列標記法,可以消除掉的就是1,不能消除掉的就是0,這樣做標記的好處就是可以做到一個棋子可能在某一行和某一列同時被消除的標記情況,因為它如果在行那裡標記過,那麼我列如果也有存在消除它的話,就可以消除;那如果列不存在消除也不影響要消除這個數,反之一樣,所以這個標記法很好用。
- 流程
- 讀入一個n*m的矩陣
- 進行行的遍歷,判斷每行是否存在可以消除的數,標記這些數字的位置為1
- 進行列的遍歷,判斷每列是否存在可以消除的數,標記這些數字的位置為1
- for迴圈的遍歷輸出,如果這個位置的標記陣列是1的話,就輸出0,不是的話就輸出之前讀入的數字。
- 程式碼實現
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=99;///定義的一個最大值
int mp[maxn][maxn];///陣列開大點比較好
int flag[maxn][maxn];
int n,m;
void judge_row(int pos,int x,int y,int z){///判斷每行是否存在3個或3個以上的數
if(mp[pos][x]==mp[pos][y]&&mp[pos][y]==mp[pos][z]){
flag[pos][x]=1;
flag[pos][y]=1;
flag[pos][z]=1;
}
}
void judge_col(int pos,int x,int y,int z){///判斷每列是否存在3個或3個以上的數
if(mp[x][pos]==mp[y][pos]&&mp[y][pos]==mp[z][pos]){
flag[x][pos]=1;
flag[y][pos]=1;
flag[z][pos]=1;
}
}
int main(){
memset(flag,0,sizeof(flag));///初始化標記陣列
scanf("%d%d",&n,&m);
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
scanf("%d",&mp[i][j]);
}
}
for(int i=0;i<n;++i){
for(int j=0;j<m-2;++j){
judge_row(i,j,j+1,j+2);
}
}
for(int j=0;j<m;++j){
for(int i=0;i<n-2;++i){
judge_col(j,i,i+1,i+2);
}
}
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
if(j==0){
printf("%d",flag[i][j]==0?mp[i][j]:0);///三目運算子,跟if差不多,就是用起來比較方便
}else{
printf(" %d",flag[i][j]==0?mp[i][j]:0);
}
}
puts("");///換行
}
return 0;
}
六.測試結果
測試1:
測試2: