您的位置:首页 > 其它

pku1568 Find the Winning Move 完全极大极小搜索

2016-03-14 16:03 295 查看
 比较简单,因为只有三种局面也没有权重不知道怎么AB剪枝= =我们可以直接用1表示正无穷,-1表示负无穷,0表示和局

有一个强力剪枝那就是,如果当前只下了<=4颗棋子那就一定无解

然而比赛的时候这个剪枝不是特别敢加.

不过实际上那个剪枝可能只是数学证明,实际测试改成7都是可以AC的

时间复杂度(2^m)*16,可秒过,然而让人遗憾的是我并没有0ms出现= =

Problem: 1568 User: BPM136
Memory: 688K Time: 16MS
Language: G++ Result: Accepted

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<bitset>
#define LL long long
#define get(i,j) (i*n+j)
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define down(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
inline LL read()
{
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
#define N 4
#define MIN -2
int map

;
int n=4,m=(1<<16)-1,cnt,cstatus;
char s;

void init()
{
memset(map,0,sizeof(map));
cnt=0;cstatus=0;int po=1;
fo(i,0,n-1)
{
fo(j,0,n-1)
{
scanf("%c",&s);
if(s=='.')
{
map[i][j]=0;
}else
if(s=='o')
{
map[i][j]=2;
cnt++;
}else
if(s=='x')
{
map[i][j]=1;
cnt++;
}
if(!map[i][j])cstatus+=po;
po<<=1;
}
getchar();
}
}

bool getvalue(int x,int y)
{
if(x==y)
{
if(map[0][0]==map[1][1])
if(map[1][1]==map[2][2])
if(map[2][2]==map[3][3])
return 1;
}
if(x==3-y)
{
if(map[0][3]==map[1][2])
if(map[1][2]==map[2][1])
if(map[2][1]==map[3][0])
return 1;
}
int tot=0;
fo(i,0,3)if(map[x][i]==map[x][y])tot++;
if(tot==4)return 1;
tot=0;
fo(i,0,3)if(map[i][y]==map[x][y])tot++;
if(tot==4)return 1;
return 0;
}

int maxmini(int status,int i,int j);
int minimax(int status,int i,int j);
int maxmini(int status,int i,int j)
{
if(getvalue(i,j))return -1;
if(cnt==16)return 0;
int st=status,ma=-2;
while(st)
{
int k=st&(-st);
int pos=log(k+0.5)/log(2.0);
int x=pos/4,y=pos%4;
map[x][y]=1;cnt++;
int t=minimax(status-k,x,y);
map[x][y]=0;cnt--;
ma=max(ma,t);
if(ma==1)return 1;
st-=k;
}
return ma;
}

int minimax(int status,int i,int j)
{
if(getvalue(i,j))return 1;
if(cnt==16)return 0;
int st=status,mi=2;
while(st)
{
int k=st&(-st);
int pos=log(k+0.5)/log(2.0);
int x=pos/4,y=pos%4;
map[x][y]=2;cnt++;
int t=maxmini(status-k,x,y);
map[x][y]=0;cnt--;
mi=min(mi,t);
if(mi==-1)return -1;
st-=k;
}
return mi;
}

void work()
{
int st=cstatus;
while(st)
{
int k=st&(-st);
int pos=log(k+0.5)/log(2.0);
int x=pos/4,y=pos%4;
map[x][y]=1;cnt++;
int t=minimax(cstatus-k,x,y);
// cout<<k<<' '<<pos<<' '<<x<<' '<<y<<' '<<t<<endl;
if(t==1)
{
printf("(%d,%d)\n",x,y);
return;
}
map[x][y]=0;cnt--;
st-=k;
}
printf("#####\n");
}

int main()
{
char ch;
while(scanf("%c",&ch))
{
if(ch=='$')break;
scanf("%c",&ch);
init();
if(cnt<=7)
{
printf("#####\n");
continue;
}
work();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息