Poj 1027 The Same Game

又是一个模拟题。。。。


给出一个棋盘,然后每次要去消除消除后能得到分数最多的棋子

每次消除的时候这个棋子和与它相邻(四联通)并且同色的棋子

(如果没有和他相邻并且同色的棋子,那这个棋子不可消除

如果有多个位置可以选择,更靠左的,要是还是有多个位置,选靠下的

消除之后把所有的棋子往下移,然后再往左靠拢

然后如果干掉所有的棋子了,分数+1000


大概就是这样(


----------------------------------我是代码的昏割线----------------------

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

char map[30][30];
int huge[30][30];
bool vis[30][30];

const int dx[] = {1,0,-1,0};
const int dy[] = {0,-1,0,1};
const char none = '.';

void outhuge(){
	for(int i=0;i<=10;i++)
		for(int j=0;j<20;j++)
			printf(j<19?"%d ":"%d\n",huge[i][j]);
}
void outmap(){
	for(int i=0;i<=10;i++)
		for(int j=0;j<20;j++)
			printf(j<19?"%c ":"%c\n",map[i][j]);
}
int dffs(int x,int y){
	int ret = 1;
	vis[x][y]=true;
	for(int d=0;d<4;d++){
		int mx = x + dx[d];
		int my = y + dy[d];
		if(map[x][y] == map[mx][my] && vis[mx][my]==false){
			ret += dffs(mx,my);
		}
	}
	return ret;
}
void dfss(int x,int y,int hg){
	huge[x][y]=hg;
	for(int d=0;d<4;d++){
		int mx = x + dx[d];
		int my = y + dy[d];
		if(map[x][y] == map[mx][my] && huge[mx][my]==-1){
			dfss(mx,my,hg);
		}
	}
}
void clean(int x,int y){
	char C = map[x][y];
	map[x][y]=none;
	for(int d=0;d<4;d++){
		int mx = x + dx[d];
		int my = y + dy[d];
		if(map[mx][my]==C){
			clean(mx,my);
		}
	}
}
bool getMax(int &x,int &y){
	memset(huge,-1,sizeof(huge));
	memset(vis,0,sizeof(vis));
	for(int i=1;i<20;i++)
		for(int j=1;j<20;j++){
			if(huge[i][j]==-1 && map[i][j]!=none){
				int hg = dffs(i,j);
				dfss(i,j,hg);
			}
		}
	x = y = 0;
	for(int j=1;j<20;j++)
		for(int i=10;i>0;i--)
			if(huge[i][j] > huge[x][y])
				x = i,y = j;
	if(huge[x][y] < 2)
		return false;
	return true;
}
void dit(int t){
	char list[20];
	for(int i=0;i<20;i++)
		list[i] = none;
	int len = 0;
	for(int i=10;i>0;i--){
		if(map[i][t]!=none){
			list[len++]=map[i][t];
			map[i][t]=none;
		}
	}
	for(int i=0;i<len;i++)
		map[10-i][t] = list[i];
}
void downer(){
	for(int i=1;i<20;i++)
		dit(i);
}
void moveto(int st,int ed){
	for(int i=10;i>0;i--){
		map[i][st]=map[i][ed];
		map[i][ed]=none;
	}
}
int have(int st){
	for(int i=st;i<20;i++)
		if(map[10][i]!=none)
			return i;
	return -1;
}
void lefter(){
	for(int i=1;i<20;i++)
		if(map[10][i]==none){
			int ed = have(i);
			if(ed==-1)
				return;
			moveto(i,ed);
		}
}
void solve(){
	int cnt = 1;
	int x,y;
	int poi=0;
	int left=150;
	while(getMax(x,y)==true){
		int num = huge[x][y];
		left -= num;
		poi += (num-2)*(num-2);
		printf("Move %d at (%d,%d): removed %d balls of color %c, got %d points.\n",
			cnt++,11-x,y,num,map[x][y],(num-2)*(num-2));
		clean(x,y);
		downer();
		lefter();
	//	outmap();
	}
	if(left == 0)
		poi += 1000;
	printf("Final score: %d, with %d balls remaining.\n",poi,left);
}
int main(){
	int t;
	int icase = 1;
	scanf("%d",&t);
	while(t--){
		printf("Game %d:\n\n",icase++);
		for(int i=0;i<20;i++)
			for(int j=0;j<20;j++)
				map[i][j]=none;
		for(int i=1;i<=10;i++){
			scanf("%s",map[i]+1);
		}
		for(int i=0;i<=10;i++)
			map[i][16]=none;
		solve();
		puts("");
	}
	return 0;
}

------------------------------关于代码我想说的---------------------------



两遍dfs来消棋子我也是没谁了


(不知道是不是这段时间在写C#的原因,一个地方思路卡住了就写一个函数。。。思路卡住了又写一个函数。。。

(如你所见这个代码函数是很多Orz


关于代码中迷的各种20,30:

其实只是我一时想不起来数据的范围然后随手糊上去。。。

反正只要比题中的数据范围大就好了(笑


10不是随手糊的。。是行数。。。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值