我只说两个字:好气啊。
消消乐小游戏。写了这个算法可以写个消消乐了。。。
只不过加个数字交换位置。
这道题应该是比较简单的,难的就是细节。
解题思路:
从左上角到右下角dfs深搜遍历可以消除的最多的数字,记录下其坐标A根据dfs判断A周围的和A相等的数字,并将其消除(置为0)更新游戏地图 一个不能忽视的细节就是在更新地图时。 我只给大家两个数据: 5 5 00002 00001 00001 00000 00000 5 5 00002 00001 00001 00030 00000 更新地图后的结果: 代码: #include <stdio.h> #include <string.h> using namespace std; #define INF 0x3fffffff char map[25][25]; int n,m,sum; int res=0; int dir[4][2]={1,0,-1,0,0,1,0,-1}; bool vis[25][25]; //测试输出 void print() { for(int i=0;i<m;i++) { printf("%s\n",map[i]); } } //边界条件 bool limit(int x,int y) { if(x<0||y<0||x>=m||y>=n||map[x][y]=='0') return false; return true; } //深搜 搜索符合条件的一组 void dfs(int x,int y,char c) { for(int i=0;i<4;i++) { int xx=x+dir[i][0]; int yy=y+dir[i][1]; if(!vis[xx][yy]&&c==map[xx][yy]&&limit(xx,yy)) { vis[xx][yy]=true; sum++; dfs(xx,yy,c); } } } //更新游戏 void updateBlocks() { //垂直方向 for(int i=m-1;i>0;i--) { for(int j=0;j<n;j++) { if(map[i][j]=='0') { int x=i; while(x>=0&&map[x][j]=='0') x--; if(x>=0) { map[i][j]=map[x][j]; map[x][j]='0'; } } } } /** * 判断一整列是否都为‘0’ * 若是:左移 */ for(int j=n-1;j>=0;j--) { //若一列的最下为‘0’则一整列都是‘0’ ,左移 if(map[m-1][j]=='0') { for(int k=j;k<n-1;k++) { for(int i=0;i<m;i++) { if(map[i][k+1]!='0') { map[i][k]=map[i][k+1]; map[i][k+1]='0'; } } } } } // printf("-----------运行结果:-----------------\n"); // print(); } // 把要移除的一组放入队列 void removeBlocks(int x,int y,char c) { map[x][y]='0'; for(int i=0;i<4;i++) { int xx=x+dir[i][0]; int yy=y+dir[i][1]; if(c==map[xx][yy]&&limit(xx,yy)) { removeBlocks(xx,yy,c); } } } //程序开始 void checkGroups() { memset(vis,0,sizeof(vis)); int maxsum=-INF; int x,y; for(int i=0;i<m;i++) { for(int j=0;j<n;j++) { if(!vis[i][j]&&map[i][j]!='0') { vis[i][j]=true; sum=1; dfs(i,j,map[i][j]); if(maxsum<sum) { maxsum=sum; x=i;y=j; } } } } if(maxsum!=INF&&maxsum>=2) { res+=maxsum*(maxsum-1); removeBlocks(x,y,map[x][y]); updateBlocks(); checkGroups(); } } int main() { while(~scanf("%d %d",&m,&n)) { res=0; memset(map,0,sizeof(map)); for(int i=0;i<m;i++) { scanf("%s",map[i]); } checkGroups(); printf("%d\n",res); } return 0; } /* 测试数据 5 5 00002 00001 00001 00000 00000 5 5 00002 00001 00001 00030 00000 */