[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;
}

浙公网安备 33010602011771号