poj1027 模拟

来源:互联网 发布:手机淘宝改差评步骤 编辑:程序博客网 时间:2024/05/29 18:50
题意:在一个固定大小为10x15的矩形区域A内被RGB三种颜色的小球填满,每次可以选择同种颜色(上下左右)连通小球数>=2的区域进行删除,删除后,上方的小球会下落,如果有空列,将其右边的列进行整列左移,移动后小球的相对顺序不变。设m(m>=2)为删除个数,每次的得分为(m-2)*(m-2),如果最后所有的小球全部能够删除,奖励1000分。当区域A没有剩余小球或是最大连通区域的小球个数为1时游戏结束。现每步删除最大的连通区域,如果存在多个相同的最大连通区域,选择最左最下的小球所在的连通区域,输出每步得分和总得分。

 



算法:模拟,寻找最大连通区域时可用dfs或bfs



#include <iostream>#include <string.h>using namespace std;char map[11][26];int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};  bool vis[11][16];int cnt;int curr_row,curr_col;bool inMap(int row, int col){return (row>=0 && row<10 && col>=0 && col<15);}// 计算最大连通区域 void dfs(int row, int col){vis[row][col] = true;cnt++;for (int i=0; i<4; i++){int nr = row + dir[i][0];int nc = col + dir[i][1];if (inMap(nr,nc) && !vis[nr][nc] && map[nr][nc]==map[row][col]){dfs(nr,nc);}}}void remove(int row, int col){char c = map[row][col];map[row][col] = ' ';for (int i=0; i<4; i++){int nr = row + dir[i][0];int nc = col + dir[i][1];if (inMap(nr,nc) && map[nr][nc]==c){remove(nr,nc);}}}int chooseBall(){memset(vis,false,sizeof(vis));int num = -1;int row,col;// 从左下角开始选 for (int i=0; i<15; i++){for (int j=0; j<10; j++){if (map[j][i] == ' ' || vis[j][i]){continue;}cnt = 0;dfs(j,i);if (cnt > num){num = cnt;curr_row = j;curr_col = i;}}}return num;}// 小球落下+非空行左移 void fresh(){int i,j,k;bool isEmpty[20];// isEmpty[i]=true:第i列为空 memset(isEmpty,false,sizeof(isEmpty));for (i=0; i<15; i++){// 找每一列的第一个非空元素 int ballNum = -1;for (j=0; j<10; j++){if (map[j][i] != ' '){map[++ballNum][i] = map[j][i];}}// 如果是空行 if (ballNum == -1){isEmpty[i] = true;continue;}// 小球落下 for (k=ballNum+1; k<10; k++){map[k][i] = ' ';}}// 非空行左移 for (i=0; i<15; i++){if (isEmpty[i]){for (j=i+1; j<15; j++){if (!isEmpty[j]){break; }}if (j >= 15){break;}isEmpty[j] = true;isEmpty[i] = false;for (k=0; k<10; k++){map[k][i] = map[k][j];map[k][j] = ' ';}}}}int main(){int cases;cin >> cases;for (int i=1; i<=cases; i++){for (int j=9; j>=0; j--){cin >> map[j];}cout << "Game " << i << ":" << endl << endl;int steps = 1;int score = 0;int ballNum;int leftBallNum=150;while (true){ballNum = chooseBall();if (ballNum == -1){score += 1000;break;}else if (ballNum == 1){break;}leftBallNum -= ballNum;cout << "Move " << steps++ << " at (" << curr_row+1 << "," << curr_col+1 << "): removed " << ballNum << " balls of color " << map[curr_row][curr_col] << ", got " << (ballNum-2)*(ballNum-2) << " points." << endl;score += (ballNum-2) * (ballNum-2);remove(curr_row,curr_col);fresh();}cout << "Final score: " << score << ", with " << leftBallNum << " balls remaining. " << endl << endl;}}

 

#include <iostream>#include <queue>#include <string.h>using namespace std;char map[11][26];int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};  bool vis[11][16];int cnt;int curr_row,curr_col; bool inMap(int row, int col){return (row>=0 && row<10 && col>=0 && col<15);}// 计算最大连通区域 void bfs(int row, int col){int q[160];int tail,head;tail = head = 0;int loc = row * 15 + col;vis[row][col] = true;q[tail++] = loc;while(head < tail){loc = q[head++];cnt++;for (int i=0; i<4; i++){int nr = loc/15 + dir[i][0];int nc = loc%15 + dir[i][1];if (inMap(nr,nc) && !vis[nr][nc] &&  map[nr][nc]==map[row][col]){vis[nr][nc] = true;q[tail++] = nr*15+nc;}}}}// 将从(row,col)开始的连通区域置为空 void remove(int row, int col){char c = map[row][col];map[row][col] = ' ';for (int i=0; i<4; i++){int nr = row + dir[i][0];int nc = col + dir[i][1];if (inMap(nr,nc) && map[nr][nc]==c){remove(nr,nc);}}}int chooseBall(){memset(vis,false,sizeof(vis));int num = -1;int row,col;// 最左,最下 for (int i=0; i<15; i++){for (int j=0; j<10; j++){if (map[j][i] == ' ' || vis[j][i]){continue;}cnt = 0;bfs(j,i);if (cnt > num){num = cnt;curr_row = j;curr_col = i;}}}return num;}// 小球落下+非空行左移 void fresh(){int i,j,k;bool isEmpty[20];// isEmpty[i]=true:第i列为空 memset(isEmpty,false,sizeof(isEmpty));for (i=0; i<15; i++){// 找每一列的第一个非空元素 int ballNum = -1;for (j=0; j<10; j++){if (map[j][i] != ' '){map[++ballNum][i] = map[j][i];}}// 如果是空行 if (ballNum == -1){isEmpty[i] = true;continue;}// 小球落下 for (k=ballNum+1; k<10; k++){map[k][i] = ' ';}}// 非空行左移 for (i=0; i<15; i++){if (isEmpty[i]){for (j=i+1; j<15; j++){if (!isEmpty[j]){break; }}if (j >= 15){break;}isEmpty[j] = true;isEmpty[i] = false;for (k=0; k<10; k++){map[k][i] = map[k][j];map[k][j] = ' ';}}}}int main(){int cases;cin >> cases;for (int i=1; i<=cases; i++){for (int j=9; j>=0; j--){cin >> map[j];}cout << "Game " << i << ":" << endl << endl;int steps = 1;int score = 0;int ballNum;int leftBallNum=150;while (true){ballNum = chooseBall();if (ballNum == -1){score += 1000;break;}else if (ballNum == 1){break;}leftBallNum -= ballNum;cout << "Move " << steps++ << " at (" << curr_row+1 << "," << curr_col+1 << "): removed " << ballNum << " balls of color " << map[curr_row][curr_col] << ", got " << (ballNum-2)*(ballNum-2) << " points." << endl;score += (ballNum-2) * (ballNum-2);remove(curr_row,curr_col);fresh();}cout << "Final score: " << score << ", with " << leftBallNum << " balls remaining. " << endl << endl;}}





0 0
原创粉丝点击