[HDU] 3368 Reversi [DFS]

题目来源:HDU 3368 [“光庭杯”第五届华中北区程序设计邀请赛 暨 WHU第八届程序设计竞赛]

题目大意:首先,给你一副走到一半的棋盘(8*8),现在轮到黑棋走。规则如下:若新增的黑棋和另外一颗已存在的黑棋之间全是白棋(即没有空格或另外的黑棋),例如:黑(new)白白黑(old),则里面的白棋全变黑棋,另外,[边界]白白黑(new),这种情况不算。问:这颗黑棋放下后,最多能够翻转多少颗白棋?(输入时字母D(Dark)代表黑棋,字母L(Light)代表白棋,*号代表空格。)

简单分析:遍历所有棋牌上的位置,若该位置为空,则用一个DFS分别从该位置的8个方向(即上[0,1],下[0,-1],左[-1,0],右[1,0],左上[-1,-1],右上[1,-1],左下[-1,1],右下[1,1])依次试探。同时把每一个位置最多能够翻转的白棋个数存放在变量sum中。

AC代码如下:

#include<stdio.h>

const int SIZE=10;
char s[SIZE][SIZE];

int dir[8][2]={
	-1,0,
	1,0,
	0,-1,
	0,1,
	1,1,
	-1,-1,
	-1,1,
	1,-1
};

void DFS(int x,int y,int d,int num,int &sum) 
{
	int i;
	if(x<0||x>7||y<0||y>7) return;
	if(d==8){
		for(i=0;i<8;++i)
			DFS(x+dir[i][0],y+dir[i][1],i,num,sum);
	} else {
		if(s[x][y]=='*') return;
		if(s[x][y]=='D') { sum+=num; return; }
		if(s[x][y]=='L') DFS(x+dir[d][0],y+dir[d][1],d,num+1,sum);
	}
}

int solve()
{
	int x,y;
	int sum,Max=0;
	for(x=0;x<8;++x)
		for(y=0;y<8;++y){
			sum=0;
			if(s[x][y]=='*') {
				DFS(x,y,8,0,sum);
				if(sum>Max) Max=sum;
			}
		}
		return Max;
}

int main()
{
	int t,i,ans,cas=1;
	scanf("%d",&t);
	while(t--){
		for(i=0;i<8;++i)
			scanf("%s",s[i]);
		ans=solve();
		printf("Case %d: %d\n",cas++,ans);
	}
	return 0;
}
posted @ 2010-04-03 21:36  timebug  Views(470)  Comments(0Edit  收藏  举报