博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj1027 模拟
阅读量:2239 次
发布时间:2019-05-09

本文共 5566 字,大约阅读时间需要 18 分钟。

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

 

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

#include 
#include
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 
#include
#include
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; }}

你可能感兴趣的文章
深入理解JVM虚拟机12:JVM性能管理神器VisualVM介绍与实战
查看>>
深入理解JVM虚拟机13:再谈四种引用及GC实践
查看>>
Spring源码剖析1:Spring概述
查看>>
Spring源码剖析2:初探Spring IOC核心流程
查看>>
Spring源码剖析5:JDK和cglib动态代理原理详解
查看>>
Spring源码剖析6:Spring AOP概述
查看>>
【Linux】进程的理解(二)
查看>>
【C++】STL -- Vector容器的用法
查看>>
【Linux】Linux中的0644 和 0755的权限
查看>>
【数据结构】有关二叉树的面试题
查看>>
【Linux】内核态和用户态
查看>>
【Linux】HTTP的理解
查看>>
【Linux】HTTPS的理解
查看>>
【操作系统】大小端问题
查看>>
Git上传代码时碰到的问题及解决方法
查看>>
【Linux】vim的简单配置
查看>>
【C++】智能指针
查看>>
【C++】const修饰的成员函数
查看>>
【C++】面向对象的三大特性
查看>>
【C++】智能指针(后续)
查看>>