CCF-201512-消除类游戏

问题描述
试题编号: 201512-2
试题名称: 消除类游戏
时间限制: 1.0s
内存限制: 256.0MB
问题描述:
问题描述
  消除类游戏是深受大众欢迎的一种游戏,游戏在一个包含有nm列的游戏棋盘上进行,棋盘的每一行每一列的方格上放着一个有颜色的棋子,当一行或一列上有连续三个或更多的相同颜色的棋子时,这些棋子都被消除。当有多处可以被消除时,这些地方的棋子将同时被消除。
  现在给你一个nm列的棋盘,棋盘中的每一个方格上有一个棋子,请给出经过一次消除后的棋盘。
  请注意:一个棋子可能在某一行和某一列同时被消除。
输入格式
  输入的第一行包含两个整数nm,用空格分隔,分别表示棋盘的行数和列数。
  接下来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 ≤ nm ≤ 30。

分析:未完待续。。。。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cmath>
  4 #include <cstring>
  5 #include <vector>
  6 using namespace std;
  7 const int maxn = 30;
  8 struct Point{
  9     int x;
 10     int y;
 11     int sign;  //方向 
 12     int count; //个数 
 13     Point(int x = 0,int y = 0,int sign = 0,int count = 0){
 14         this->x = x;
 15         this->y = y;
 16         this->sign = sign;
 17         this->count = count;
 18     }
 19 };
 20 int graph[maxn][maxn];
 21 int have_find[maxn][maxn];    //-1为未标记,1为已标记 
 22 int m,n,count;
 23 vector<Point*> point;    //存放需要消除的点 
 24 void finded(Point* p){        //标记已经确定消除的点
 25     int x = p->x;
 26     if(p->sign == 1){
 27         for(int i = p->y;i < p->y+p->count;i++){
 28             have_find[p->x][i] = 1;
 29         }
 30     }else if(p->sign == 2){
 31         for(int i = p->x;i < p->x+p->count;i++){
 32             have_find[i][p->y] = 1;
 33         }
 34     } 
 35 }
 36 void judge(int x,int y,int s){  //判断以点(x,y)为首的行(列)是否符合消除条件 
 37     int count = 0;              //根据s的值来判断是行遍历还是列遍历 
 38     int temp = graph[x][y];     //s == 1为行遍历,s == 2为列遍历 
 39     if(s == 1){    //行遍历 
 40         for(int i = y;i < m;i++){
 41             if(graph[x][i] == temp){
 42                 count++;
 43             }else{
 44                 break;
 45             }
 46         }
 47     }else if(s == 2){   //列遍历 
 48         for(int i = x;i < n;i++){
 49             if(graph[i][y] == temp){
 50                 count++;
 51             }else{
 52                 break;
 53             }
 54         } 
 55     }
 56     if(count >= 3){
 57         Point* p = new Point(x,y,s,count);
 58         finded(p);  //标记已经确定消除的点 
 59         point.push_back(p);
 60     } 
 61 }
 62 
 63 void make_work(){     //消除掉所有标记的点 
 64     for(int i = 0;i < point.size();i++){
 65         Point* p = point[i];
 66         if(p->sign == 1){
 67             for(int i = p->y;i < p->y + p->count;i++){
 68                 graph[p->x][i] = 0;
 69             }
 70         }else if(p->sign == 2){
 71             for(int i = p->x;i < p->x + p->count;i++){
 72                 graph[i][p->y] = 0;
 73             }
 74         } 
 75     }
 76 } 
 77 int main(){
 78     cin >> n >> m;
 79     for(int i = 0;i < n;i++){
 80         for(int j = 0;j < m;j++){
 81             cin >> graph[i][j];
 82         }
 83     }
 84     memset(have_find,-1,sizeof(have_find)); 
 85     
 86     for(int i = 0;i < n;i++){      //进行行标记 
 87         for(int j = 0;j < m;j++){
 88             if(have_find[i][j] == -1){
 89                 judge(i,j,1);
 90             } 
 91         }
 92     }
 93     memset(have_find,-1,sizeof(have_find)); 
 94     for(int i = 0;i < n;i++){      //进行列标记 
 95         for(int j = 0;j < m;j++){
 96             if(have_find[i][j] == -1){
 97                 judge(i,j,2);
 98             } 
 99         }
100     }
101     make_work(); //进行清除 
102     for(int i = 0;i < n;i++){
103         for(int j = 0;j < m;j++){
104             cout << graph[i][j] << " ";
105         }
106         cout << "\n";
107     } 
108     return 0;
109 } 

 

 

 

201512-2
posted @ 2020-03-30 17:43  争不过朝夕  阅读(180)  评论(0)    收藏  举报