poj 1027.The Same Game

#include<iostream.h>

const int R=10;
const int C=15;

char board[R][C+1];
int cluster[R][C];
int sizeOfCluster[R*C];
int nMove, score;

//得到游戏版中包含位置(r,c)处小球的Cluster。 
void GetCluster(int r, int c, int id);
//得到各个Cluster及其小球个数.
void GetSizeofCluster();
//溢出一个小球个数大于1的Cluster,成功移除返回1;不存在返回0;
 int Remove();
 //对剩余小球进行移动压缩
 void Compress();
 //对一句给定游戏模拟求解
 void Simulate();
 
 int main()
 {
 	int T, t, i;
 	
 	cin>>T;
 	for(t=0;t<T;t++){
	 	//读入数据.
		 for(i=0;i<R;i++){
 			cin>>board[i];
 		} 
 		//模拟求解并输出.
		 cout<<"Game "<<t+1<<":\n\n";
		 Simulate();
		 cout<<endl; 
	 }
	 return 0;
 }
 
 void GetCluster(int r, int c, int id)
 {
 	cluster[r][c]=id;
 	if(r-1>=0&&cluster[r-1][c]==-1&&board[r-1][c]==board[r][c]){
	 	GetCluster(r-1,c,id);
	 }
	 if(c+1<=C&&cluster[r][c+1]==-1&&board[r][c+1]==board[r][c]){
	 	GetCluster(r,c+1,id);
	 }
	 if(r+1<=R&&cluster[r+1][c]==-1&&board[r+1][c]==board[r][c]){
	 	GetCluster(r+1,c,id);
	 }
	 if(c-1>=0&&cluster[r][c-1]==-1&&board[r][c-1]==board[r][c]){
	 	GetCluster(r,c-1,id);
	 }
 } 
 
 void GetSizeofCluster()
 {
 	int i, j;
 	//初始化 
 	int id=0;
 	for(i=0;i<R;i++){
	 	for(j=0;j<C;j++){
	 		cluster[i][j]=-1;
	 		sizeOfCluster[i*R+j]=0;
	 	}
	 }
	 
	 //得到各个Cluster.
	 for(i=0;i<R;i++){
 		for(j=0;j<C;j++){
		 	//位置(i,j)有小球且未被划分到一个Cluster.
			 if(cluster[i][j]==-1&&board[i][j]!=0){
 				GetCluster(i,j,id);
 				id++;
 			}
		 }
 	} 
 	
 	//得到各个Cluster中小球个数.
	 for(i=0;i<R;i++){
 		for(j=0;j<C;j++){
		 	if(cluster[i][j]!=-1){
	 			sizeOfCluster[cluster[i][j]]++;
	 		}
		 }
 	} 
 }
 
 int Remove()
 {
 	int maxSize, r, c;
 	int i, j;
 	
 	//得到当前游戏板中各个Cluster小球个数.
	 GetSizeofCluster();
	 
	 //得到当前游戏板中小球个数最多的Cluster及其小球个数.
	 maxSize=0;
	 for(j=0;j<C;j++){
 		for(i=R-1;i>=0;i++){
		 	if(cluster[i][j]!=-1&&sizeOfCluster[cluster[i][j]]>maxSize){
	 			maxSize=sizeOfCluster[cluster[i][j]];
	 			r=i;
	 			c=j;
	 		}
		 }
	 }
	 if(maxSize<2){//不存在小球个数大于1的Cluster. 
 		return 0;
 	}
	 
	 //存在小球个数大于1的Cluster,将其移除.
	 char color=board[r][c];
	 for(i=0;i<R;i++){
 		for(j=0;j<C;j++){
		 	if(cluster[i][j]==cluster[r][c]){
	 			board[i][j]=0;
	 		}
		 }
 	} 
 	//暑促和本步操作信息和得分情况,将本步得分加到游戏最终得分
	 cout<<"Move "<<nMove<<" at ("<<10-r<<","<<c+1<<"):removed"<<maxSize<<" balls of color "<<color<<", got "<<(maxSize-2)*(maxSize-2)<<" points.\n";
	 score+=(maxSize-2)*(maxSize-2);
	 
	 return 1;
 } 
 
 void Compress()
 {
 	int r1, c1, r2, c2;//(r1,c1)为压缩前位置,(r2,c2)为压缩后位置.
	 
	 //置压缩后位置列坐标为0,即游戏板最左面.
	 c2=0;
	 //列优先求出压缩前位置(r1,c1)所对应的压缩后位置(r2,c2).
	 for(c1=0;c1<C;c1++){
 		
 		//置压缩前后位置行坐标为R-1,即游戏最下面.
		 r2=r1=R-1;
		 
		 while(r1>=0){
 			//从下向上查找一个有球的位置(r1,c1)
			 while(r1>=0&&board[r1][c1]==0){
 				r1--;
 			} 
 			
 			while(r1>=0&&board[r1][c1]!=0){
			 	if(r2>r1||c2<c1){
	 				board[r2][c2]=board[r1][c1];
	 				board[1][c1]=0;
	 			}
	 			//将压缩前后位置行列坐标减1,以上移1行.
				 r2--;
				 r1--; 
			 }
 		} 
 		if(r2<R-1){//不是一个空白咧,压缩后位置列坐标加1,以右移1列. 
		 	c2++;
		 }
 	} 
 }
 
 void Simulate()
 {
 	int nBalls=0;
 	int i,j;
 	
 	nMove=1;
 	score=0;
 	//每一次成功移除当前游戏板中一个Cluster后,对生育小球进行移动压缩.
	 while(Remove()==1){
 		Compress();
 		nMove++;
 	} 
 	//计算游戏最终得分并输出
	 for(i=0;i<R;i++){
 		for(j=0;j<C;j++){
		 	if(board[i][j]!=0){
	 			nBalls++;
	 		}
		 }
 	} 
 	if(nBalls==0){
	 	score+=1000;
	 }
	 cout<<"Final score: "<<score<<",with"<<nBalls<<"balls remaining.\n";
 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值