题目地址:http://poj.org/problem?id=1085
极大极小排序,就是注意当一方有个三角形后可以再走一次
有个小小小的问题结果卡一天了......
代码如下:
#include<cstdio>
#include<cstring>
#include<queue>
#include<set>
#include<string>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn=20+5;
const int Triangle[9][3]={ {1,2,3},{4,5,8},{3,5,6},{6,7,9},{10,11,16},{8,11,12},{12,13,17},{9,13,14},{14,15,18}
};
const int Edge[19][2]={ //每条边连接的顶点 {0,0},{1,2},{1,3},{2,3},{2,4},{2,5},{3,5},{3,6},{4,5},{5,6},{4,7},{4,8},{5,8},{5,9},{6,9},{6,10},{7,8},{8,9},{9,10}
};
int edge;
bool edges[20]; //18个边
int Num(){ //三角形总数 int cnt=0;for(int i=0;i<9;i++){bool ok=true;for(int j=0;j<3&&ok;j++)if(edges[Triangle[i][j]]==false) ok=false;if(ok) cnt++;}return cnt;
}
bool MinSearch(int A,int B);
bool MaxSearch(int A,int B);
bool MaxSearch(int A,int B)
{if(A>=5) return true;if(B>=5) return false;if(edge==18) return A>B;for(int i=1;i<=18;i++)if(!edges[i]){edges[i]=true; edge++;int nt=Num(); bool tmp;if(nt>A+B) tmp=MaxSearch(nt-B,B); //三角形变多了 else tmp=MinSearch(A,B);edges[i]=false; edge--;if(tmp==true) return true;}return false;
}
bool MinSearch(int A,int B)
{if(A>=5) return true;if(B>=5) return false;if(edge==18) return A>B;for(int i=1;i<=18;i++)if(!edges[i]){edges[i]=true; edge++;int nt=Num(); bool tmp;if(nt>A+B) tmp=MinSearch(A,nt-A); //再走一次 else tmp=MaxSearch(A,B);edges[i]=false; edge--;if(tmp==false) return false;}return true;
}
int find(int x,int y)
{for(int i=1;i<=18;i++)if(Edge[i][0]==x&&Edge[i][1]==y) return i;return -1;
}
int main()
{int T,kase=0,A,B; cin>>T;while(T--){int n,x,y; cin>>n;memset(edges,false,sizeof(edges));A=B=0; int next=1; //1代表A for(int i=1;i<=n;i++){scanf("%d%d",&x,&y);edges[find(x,y)]=true;int nt=Num();if(nt>A+B) next?A=nt-B:B=nt-A;else next^=1;}edge=n;bool ans;if(next) ans=MaxSearch(A,B);else ans=MinSearch(A,B);printf("Game %d: %c wins. \n",++kase,ans?'A':'B');}return 0;
}