poj 1085 Triangle War 极大极小搜索

来源:互联网 发布:网络作家协会怎么加入 编辑:程序博客网 时间:2024/05/20 17:58

Description


给定一个三角形矩阵如下
这里写图片描述
两个人每次每人可以把一条虚线涂黑,若操作后的一条边与另外两条邻边形成一个三角形就能再操作一次,每次操作的得分为此次操作形成的新的三角形。现在给定一些已经走了的操作求谁会赢,假设两人绝对聪明

Solution


裸的极大极小搜索了。一开始以为做成一个三角形就结束了

我看很多题解说要压缩状态但是好像不用也可以

这里的alphabeta可能打反了,可是不影响理解

Code


#include <stdio.h>#include <string.h>#define rep(i,st,ed) for (int i=st;i<=ed;i+=1)#define fill(x,t) memset(x,t,sizeof(x))#define max(x,y) ((x)>(y)?(x):(y))#define min(x,y) ((x)<(y)?(x):(y))#define INF 0x3f3f3f3f#define N 21struct edge{int x,y;}e[N];int rc[N][N],id[N][N],A;int edgeCnt;int read() {    int x=0; char ch=getchar();    for (;ch<'0'||ch>'9';ch=getchar());    for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar());    return x;}void addEdge(int x,int y) {    e[++edgeCnt]=(edge){x,y};}bool isTriangle(int x,int y,int z) {    return rc[x][y]&&rc[y][z]&&rc[x][z];}int check() {    int ret=0;    ret+=isTriangle(1,2,3)+isTriangle(2,4,5)+isTriangle(2,3,5);    ret+=isTriangle(3,5,6)+isTriangle(4,7,8)+isTriangle(4,5,8);    ret+=isTriangle(5,8,9)+isTriangle(5,6,9)+isTriangle(6,9,10);    return ret;}int findMin(int dep,int alpha);int findMax(int dep,int beta) {    if (dep==18) return ((A)>(0)?(INF):(-INF));    int ret=-INF;    int record=check();    rep(i,1,edgeCnt) {        if (!rc[e[i].x][e[i].y]) {            rc[e[i].x][e[i].y]=rc[e[i].y][e[i].x]=1;            int now=check(),val;            A+=now-record;            if (now-record>0) val=findMax(dep+1,beta);            else val=findMin(dep+1,ret);            A-=now-record;            rc[e[i].x][e[i].y]=rc[e[i].y][e[i].x]=0;            ret=max(ret,val);            if (ret>=beta) return ret;        }    }    return ret;}int findMin(int dep,int alpha) {    if (dep==18) return ((A)>(0)?(INF):(-INF));    int ret=INF;    int record=check();    rep(i,1,edgeCnt) {        if (!rc[e[i].x][e[i].y]) {            rc[e[i].x][e[i].y]=rc[e[i].y][e[i].x]=1;            int now=check(),val;            A-=now-record;            if (now-record>0) val=findMin(dep+1,alpha);            else val=findMax(dep+1,ret);            A+=now-record;            rc[e[i].x][e[i].y]=rc[e[i].y][e[i].x]=0;            ret=min(val,ret);            if (ret<=alpha) return ret;        }    }    return ret;}void init() {    addEdge(1,2);    addEdge(1,3);    addEdge(2,3);    addEdge(2,4);    addEdge(2,5);    addEdge(3,5);    addEdge(3,6);    addEdge(4,5);    addEdge(5,6);    addEdge(4,7);    addEdge(4,8);    addEdge(5,8);    addEdge(5,9);    addEdge(6,9);    addEdge(6,10);    addEdge(7,8);    addEdge(8,9);    addEdge(9,10);}int main(void) {    init();    int T=read();    int game=0;    while (T--) {        fill(rc,0);        A=0;        int n=read();        int last=0,now=0;        int person=1;        rep(i,1,n) {            int x=read();            int y=read();            rc[x][y]=rc[y][x]=1;            now=check();            if (person) {                A+=now-last;            } else {                A-=now-last;            }            if (now==last) {                person^=1;            }            last=now;        }        int ans;        if (person) {            ans=findMax(n,INF);        } else {            ans=findMin(n,-INF);        }        if (ans==INF) {            printf("Game %d: A wins.\n", ++game);        } else {            printf("Game %d: B wins.\n", ++game);        }    }    return 0;}