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