UVa852 - Deciding victory in Go(DFS,种子填充法)

本文介绍了一种用于计算围棋比赛中每位玩家得分的算法。通过深度优先搜索确定棋盘上被包围的地盘及其归属,实现自动计分。文章详细解释了算法的工作原理,并提供了一个具体的例子来说明如何计算黑白两方的得分。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

The history of Go stretches back some 3000 years and the rules have remained essentially unchanged throughout this very long period. The game probably originated in China or the Himalayas. In the Far East, where it originated, Go enjoys great popularity today and interest in the game is growing steadily in Europe and America. 

A game of Go starts with an empty square board and each player has an unlimited supply of stones, one taking the black stones, the other taking white. The basic object of the game is to use one’s stones to form territories by surrounding vacant areas of the board. It is also possible to capture the opponent’s stones by completely surrounding them. The players take turns, placing one of their stones on a vacant point at each turn, Black playing first. Note that the stones are placed on the intersections of the lines rather than in the squares (there are no diagonal connections). Once played, stones are not moved although they may be captured, in which case they are removed from the board. At the end of the game (when both players pass) the players count one point for each vacant point inside their own territory and one point for every stone they have on the board. The player with the larger total of points wins.

Problem

Given a certain Go board position; decide the number of points of each player.

 

Example

Black has surrounded 15 points of territory: 3 at the top of the board, 2 points just below, 9 in the lower right corner plus one point for the territory at intersection a. Adding the actual stones on board (24 stones), Black has a total of 39 points.White’s territory is 17 points: 11 on the left sector plus 6 on the right sector. With 24 stones on board, he has a total of 41 points. So, White wins the game by two points.Notice that intersection b does not belong to either player.

 

Input

The input file will contain one line with one integer defining the number of board positions. On the following lines the positions are presented. Each position consists of nine lines of nine characters: X for black stones, O for white stones and a ‘.’ (a dot) for empty intersections. There is no empty line separating each problem set. 

Output

Correct output consists of a set of lines (one for each problem solution) where each line consists of: Black <Black points> White <White points> newline.

Sample Input

1
OX..XXO..
OXX.XOO..
OOXX.XO.O
.OOX.XOO.
..OOXXXOO
..OO.X.XO
..OOXX.XX
..OX.X...
..OXX.... 

Sample Output

Black 39 White 41



 

import java.io.FileInputStream;
import java.io.BufferedInputStream;
import java.io.PrintWriter;
import java.io.OutputStreamWriter;
import java.util.Scanner;

public class Main implements Runnable{
	private static final boolean DEBUG = false;
	private static final int N = 9;
	private Scanner cin;
	private PrintWriter cout;
	private char[][] grid = new char[N][N];
	private int[][] vis;
	private boolean found;
	private int cnt;
	
	private void init() 
	{
		try {
			if (DEBUG) {
				cin = new Scanner(new BufferedInputStream(
						new FileInputStream("e:\\uva_in.txt")));
			} else {
				cin = new Scanner(new BufferedInputStream(System.in));
			}

			cout = new PrintWriter(new OutputStreamWriter(System.out));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void input() 
	{
		for (int i = 0; i < N; i++) {
			String s = cin.next();
			grid[i] = s.toCharArray();
		}
	}

	
	private int dfs(int x, int y, char ch, int v)
	{
		if (x < 0 || x >= N || y < 0 || y >= N || vis[x][y] != 0) return 0;

		if (grid[x][y] != ch) return 0;
		else {
			vis[x][y] = v;
			
		}

		int ans = 1;
		
		ans += dfs(x - 1, y, ch, v);
		ans += dfs(x + 1, y, ch, v);
		ans += dfs(x, y - 1, ch, v);
		ans += dfs(x, y + 1, ch, v);

		return ans;
	}

	private void dfs2(int x, int y, char ch, int v)
	{
		if (x < 0 || x >= N || y < 0 || y >= N) return ;

		if (grid[x][y] == ch && vis[x][y] == 0) {
			vis[x][y] = v;
			cnt++;
			dfs2(x - 1, y, ch, v);
			dfs2(x + 1, y, ch, v);
			dfs2(x, y - 1, ch, v);
			dfs2(x, y + 1, ch, v);
		} else {
			if (vis[x][y] != v) {
				found = false;
			} 

			return;
		}
	}
	
	private void solve() 
	{
		vis = new int[N][N];

		int black = 0, white = 0;
		
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				if (grid[i][j] != '.') {
					if (grid[i][j] == 'X' && vis[i][j] == 0) {
	
						black += dfs(i, j, 'X', 1);
					} else if (grid[i][j] == 'O' && vis[i][j] == 0) {
						
						white += dfs(i, j, 'O', 2);
						
					}
				}
			}
		}

		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				if (grid[i][j] == 'X') {
					if (i > 0 && grid[i - 1][j] == '.' && vis[i - 1][j] == 0) {
						found = true;
						cnt = 0;
						dfs2(i - 1, j, '.', 1);
						if (found) black += cnt;
					}

					if (i < N - 1 && grid[i + 1][j] == '.' && vis[i + 1][j] == 0) {
						found = true;
						cnt = 0;
						dfs2(i + 1, j, ',', 1);
						if (found) black += cnt;
					}

					if (j > 0 && grid[i][j - 1] == '.' && vis[i][j - 1] == 0) {
						found = true;
						cnt = 0;
						dfs2(i, j - 1, '.', 1);
						if (found) black += cnt;
					}

					if (j < N - 1 && grid[i][j + 1] == '.' && vis[i][j + 1] == 0) {
						found = true;
						cnt = 0;
						dfs2(i, j + 1, '.', 1);
						if (found) black += cnt;
					}
				}else if (grid[i][j] == 'O') {
					if (i > 0 && grid[i - 1][j] == '.' && vis[i - 1][j] == 0) {
						found = true;
						cnt = 0;
						dfs2(i - 1, j, '.', 2);
						if (found) white += cnt;
					}

					if (i < N - 1 && grid[i + 1][j] == '.' && vis[i + 1][j] == 0) {
						found = true;
						cnt = 0;
						dfs2(i + 1, j, '.', 2);
						if (found) white += cnt;
					}

					if (j > 0 && grid[i][j - 1] == '.' && vis[i][j - 1] == 0) {
						found = true;
						cnt = 0;
						dfs2(i, j - 1, '.', 2);
						if (found) white += cnt;
					}

					if (j < N - 1 && grid[i][j + 1] == '.' && vis[i][j + 1] == 0) {
						found = true;
						cnt = 0;
						dfs2(i, j + 1, '.', 2);
						if (found) white += cnt;
					}
				}
			}
		}

		cout.println("Black " + black + " White " + white);
		cout.flush();
	}

	public void run()
	{
		init();

		int t = cin.nextInt();
		while (t-- > 0) {
			input();
			solve();
		}
	}
	
	public static void main(String[] args) 
	{
		new Thread(new Main()).start();
	}
}


 

 

种子填充算法,自己写的,希望对大家有用 // 种子法View.cpp : implementation of the CMyView class // #include "stdafx.h" #include "种子法.h" #include "种子法Doc.h" #include "种子法View.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif struct point { int x; int y; }p[10]={200,100,100,200,150,100,200,300,250,100,300,200,-1}; point stack[1024000]; int top; void push(int x,int y) { if(top>1024000)exit(0); stack[top].x=x; stack[top].y=y; top++; } void pop(int &x,int &y) { if(top==0) exit(0); x=stack[top-1].x; y=stack[top-1].y; top--; } void gettop(int &x,int &y) { if(top==0) exit(0); x=stack[top-1].x; y=stack[top-1].y; } ///////////////////////////////////////////////////////////////////////////// // CMyView IMPLEMENT_DYNCREATE(CMyView, CView) BEGIN_MESSAGE_MAP(CMyView, CView) //{{AFX_MSG_MAP(CMyView) ON_WM_LBUTTONDOWN() //}}AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CMyView construction/destruction CMyView::CMyView() { // TODO: add construction code here } CMyView::~CMyView() { } BOOL CMyView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs return CView::PreCreateWindow(cs); } ///////////////////////////////////////////////////////////////////////////// // CMyView drawing void CMyView::OnLButtonDown(UINT nFlags, CPoint point) { int x,y; CClientDC dc(this); // TODO: Add your message handler code here and/or call default origin=point; push(origin.x,origin.y); while(top!=0) { pop(x,y); if(dc.GetPixel(x-1,y)!=0)//不等于边界色 { dc.SetPixel(x-1,y,0);//染成黑色 push(x-1,y); //加入栈 } if(dc.GetPixel(x+1,y)!=0) { dc.SetPixel(x+1,y,0); push(x+1,y); } if(dc.GetPixel(x,y-1)!=0) { dc.SetPixel(x,y-1,0); push(x,y-1); } if(dc.GetPixel(x,y+1)!=0) { dc.SetPixel(x,y+1,0); push(x,y+1); } } CView::OnLButtonDown(nFlags, point); } void CMyView::OnDraw(CDC* pDC) { CClientDC dc(this); dc.TextOut(1,5,"请为每个区选种子,务必在图形内"); CMyDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); int i; for(i=0;p[i+1].x!=-1;i++) { dc.MoveTo(p[i].x,p[i].y); dc.LineTo(p[i+1].x,p[i+1].y); } dc.MoveTo(p[i].x,p[i].y); dc.LineTo(p[0].x,p[0].y); // TODO: add draw code for native data here } ///////////////////////////////////////////////////////////////////////////// // CMyView printing BOOL CMyView::OnPreparePrinting(CPrintInfo* pInfo) { // default preparation return DoPreparePrinting(pInfo); } void CMyView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add extra initialization before printing } void CMyView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add cleanup after printing } ///////////////////////////////////////////////////////////////////////////// // CMyView diagnostics #ifdef _DEBUG void CMyView::AssertValid() const { CView::AssertValid(); } void CMyView::Dump(CDumpContext& dc) const { CView::Dump(dc); } CMyDoc* CMyView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc))); return (CMyDoc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CMyView message handlers
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值