【poj1568】 Find the Winning Move

http://poj.org/problem?id=1568 (题目链接)

题意

  两人下4*4的井字棋,给出一个残局,问是否有先手必胜策略。

Solution

  极大极小搜索。。

  这里有个强力优化,若已经被下了的的格子数cnt小于等于4的话,那么一定是平局至于为什么,自己YY一下发现好像是这样的。。

代码

// poj1568
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<queue>
#define MOD 100003
#define inf 2147483640
#define LL long long
#define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);
using namespace std;

char s[4][4];
int a[4][4],cnt;

int check(int f,int &X,int &Y) {
	for (int i=0;i<4;i++) {
		int ff=0;
		for (int j=0;j<4;j++) if (a[i][j]==f) ff++;
		//if (ff==3) for (int j=0;j<4;j++) if (!a[i][j]) {X=i,Y=j;return 1;}
		if (ff==4) return 1;
	}
	for (int j=0;j<4;j++) {
		int ff=0;
		for (int i=0;i<4;i++) if (a[i][j]==f) ff++;
		//if (ff==3) for (int i=0;i<4;i++) if (!a[i][j]) {X=i,Y=j;return 1;}
		if (ff==4) return 1;
	}
	int ff=0;
	for (int i=0;i<4;i++) if (a[i][i]==f) ff++;
	//if (ff==3) for (int i=0;i<4;i++) if (!a[i][i]) {X=i,Y=i;return 1;}
	if (ff==4) return 1;
	ff=0;
	for (int i=0;i<4;i++) if (a[i][4-i-1]==f) ff++;
	//if (ff==3) for (int i=0;i<4;i++) if (!a[i][4-i-1]) {X=i,Y=4-i-1;return 1;}
	if (ff==4) return 1;
	return 0;
}
int maxdfs(int beta,int &X,int &Y);
int mindfs(int alpha,int &X,int &Y) {
	if (cnt==16) return 0;
	int x,y,tmp=inf;
	int f=check(1,X,Y);
	if (f==1) return inf;
	for (int i=0;i<4;i++)
		for (int j=0;j<4;j++) if (!a[i][j]) {
				X=i,Y=j;a[i][j]=2;cnt++;
				tmp=min(tmp,maxdfs(tmp,x,y));
				a[i][j]=0;cnt--;
				if (tmp<=alpha) return tmp;
			}
	return tmp;
}
int maxdfs(int beta,int &X,int &Y) {
	if (cnt==16) return 0;
	int x,y,tmp=-inf;
	int f=check(2,X,Y);
	if (f==1) return -inf;
	for (int i=0;i<4;i++)
		for (int j=0;j<4;j++) if (!a[i][j]) {
				X=i,Y=j;a[i][j]=1;cnt++;
				tmp=max(tmp,mindfs(tmp,x,y));
				a[i][j]=0;cnt--;
				if (tmp>=beta) return tmp;
			}
	return tmp;
}
int main() {
	while (scanf("%s",s[0]) && s[0][0]!=‘$‘) {
		cnt=0;
		for (int i=0;i<4;i++) scanf("%s",s[i]);
		for (int i=0;i<4;i++)
			for (int j=0;j<4;j++) {
				if (s[i][j]==‘.‘) a[i][j]=0;
				else if (s[i][j]==‘x‘) a[i][j]=1;
				else if (s[i][j]==‘o‘) a[i][j]=2;
				if (s[i][j]!=‘.‘) cnt++;
			}
		if (cnt<=4) {printf("#####\n");continue;}   //蜜汁优化
		int X,Y;
		int res=maxdfs(inf,X,Y);
		if (res==inf) printf("(%d,%d)\n",X,Y);
		else printf("#####\n");
	}
	return 0;
}

  

时间: 2024-10-09 21:13:14

【poj1568】 Find the Winning Move的相关文章

【迭代博弈+搜索+剪枝】poj-1568--Find the Winning Move

poj  1568:Find the Winning Move   [迭代博弈+搜索+剪枝] 题面省略... Input The input contains one or more test cases, followed by a line beginning with a dollar sign that signals the end of the file. Each test case begins with a line containing a question mark and

POJ Find the Winning Move【minmax搜索+alpha-beta剪枝】【北大ACM/ICPC竞赛训练】

1 #include<iostream> 2 using namespace std; 3 4 int row,col,chess; 5 char board[5][5]; 6 7 int minSearch(int i,int j,int alpha); 8 int maxSearch(int i,int j,int beta); 9 10 11 bool check(int r,int c){ 12 if( board[r][0]==board[r][1] && board

【LeetCode】283. Move Zeros

题目 Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements. For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0]. Note:Yo

poj1568 Find the Winning Move[极大极小搜索+alpha-beta剪枝]

Find the Winning Move Time Limit: 3000MS   Memory Limit: 32768K Total Submissions: 1286   Accepted: 626 Description 4x4 tic-tac-toe is played on a board with four rows (numbered 0 to 3 from top to bottom) and four columns (numbered 0 to 3 from left t

Python高手之路【七】python基础之模块

本节大纲 模块介绍 time &datetime模块 random os sys shutil json & picle shelve xml处理 yaml处理 configparser hashlib subprocess logging模块 re正则表达式 1:模块介绍 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个函数才能完成(函数又可以

【LeetCode】Dungeon Game 解题报告【Solution】

[题目] The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. The dungeon consists of M x N rooms laid out in a 2D grid. Our valiant knight (K) was initially positioned in the top-left room and must fight h

【struts2】预定义拦截器

1)预定义拦截器 Struts2有默认的拦截器配置,也就是说,虽然我们没有主动去配置任何关于拦截器的东西,但是Struts2会使用默认引用的拦截器.由于Struts2的默认拦截器声明和引用都在这个Struts-default.xml里面,因此我们需要到这个文件的struts-default包里去看一下.定义如下: 1 <interceptors> 2 <interceptor name="alias" class="com.opensymphony.xwor

27. Remove Element【easy】

27. Remove Element[easy] Given an array and a value, remove all instances of that value in place and return the new length. Do not allocate extra space for another array, you must do this in place with constant memory. The order of elements can be ch

【转】UML中的几种关系详细解析

UML图中类之间的关系:依赖,泛化,关联,聚合,组合,实现 类与类图 1) 类(Class)封装了数据和行为,是面向对象的重要组成部分,它是具有相同属性.操作.关系的对象集合的总称. 2) 在系统中,每个类具有一定的职责,职责指的是类所担任的任务,即类要完成什么样的功能,要承担什么样的义务.一个类可以有多种职责,设计得好的类一般只有一种职责,在定义类的时候,将类的职责分解成为类的属性和操作(即方法). 3) 类的属性即类的数据职责,类的操作即类的行为职责 一.依赖关系(Dependence) 依