本来想一次性大批量更新的,每次都发现东西太多,又懒得写了
干脆改成休息的时候,写博文放松算了,好吧,本博客处于半荒废状态
梭哈游戏,参见ctsc2012d1t1(ctsc太颓了,酱油记都不想写)
其实这道题,不是容斥恶心,而是牌局的大小判断恶心。
分别搜出两人的牌局,然后统一排序,那么我们只需知道一个牌局前面有多少没有相同重复手牌的牌局即可,这部分就用容斥统计,然后比较大小各种恶心
#include <cstdio>
#include <cstdlib>
#include <cstring>
#ifdef WIN32
#define fmt64 "%I64d"
#else
#define fmt64 "%lld"
#endif
struct state{int a[6],b[6],e,u1,u2;}st[2600000];
int a[6],b[6],v[15][5],u[2600000],o[5],d[10],pi,qi,debug;
int n,m,tot,xx[15],yy[5],g[8000000],p[10];
long long ans1,ans2,f[32];
void sort(state &u)
{
int i,j,e;
for (i=1;i<=4;i++)
for (j=i+1;j<=5;j++)
if (u.a[i]<u.a[j] || (u.a[i]==u.a[j] && u.b[i]<u.b[j]))
e=u.a[i],u.a[i]=u.a[j],u.a[j]=e,
e=u.b[i],u.b[i]=u.b[j],u.b[j]=e;
}
void yasuo(state &x)
{
int i,k;
for (i=1,k=6;i<=5;i++,k--)
x.u2+=x.a[i]*d[k];
x.u2+=x.b[1];
}
int tonghuashun(state &x)
{
int i;
if (o[x.b[1]]!=5) return 0;
for (i=2;i<=5;i++)
if (x.a[i]!=x.a[i-1]-1) return 0;
x.u1=9;x.u2+=x.a[1]*d[6],x.u2+=x.b[1];
return 1;
}
int sitiao(state &x)
{
if (u[x.a[1]]!=4 && u[x.a[2]]!=4) return 0;
x.u1=8;
if (u[x.a[1]]==4) x.u2+=x.a[1]*d[6];
else x.u2+=x.a[2]*d[6];
return 1;
}
int mantanghong(state &x)
{
if (!((u[x.a[1]]==3 && u[x.a[4]]==2) || (u[x.a[1]]==2 && u[x.a[3]]==3))) return 0;
x.u1=7;
if (u[x.a[1]]==3 && u[x.a[4]]==2) x.u2+=x.a[1]*d[6];
else x.u2+=x.a[3]*d[6];
return 1;
}
int tonghua(state &x)
{
if (o[x.b[1]]!=5) return 0;
x.u1=6;yasuo(x);
return 1;
}
int shunzi(state &x)
{
int i;
for (i=2;i<=5;i++)
if (x.a[i]!=x.a[i-1]-1) return 0;
x.u1=5;
x.u2+=x.a[1]*d[6],x.u2+=x.b[1];
return 1;
}
int santiao(state &x)
{
if (!(u[x.a[1]]==3 || u[x.a[2]]==3 || u[x.a[3]]==3)) return 0;
x.u1=4;
if (u[x.a[1]]==3) x.u2+=x.a[1]*d[6];
else if (u[x.a[2]]==3) x.u2+=x.a[2]*d[6];
else x.u2+=x.a[3]*d[6];
return 1;
}
int liangdui(state &x)
{
if (!(u[x.a[2]]==2 && u[x.a[4]]==2)) return 0;
x.u1=3;
if (u[x.a[1]]==1) x.u2+=x.a[2]*d[6]+x.a[4]*d[5]+x.a[1]*d[4]+x.b[2];
else if (u[x.a[3]]==1) x.u2+=x.a[1]*d[6]+x.a[4]*d[5]+x.a[3]*d[4]+x.b[1];
else x.u2+=x.a[1]*d[6]+x.a[3]*d[5]+x.a[5]*d[4]+x.b[1];
return 1;
}
int yidui(state &x)
{
int i,j,k;
for (i=2;i<=5;i++)
if (x.a[i]==x.a[i-1]) break;
if (i>5) return 0;
x.u1=2;
x.u2+=x.a[i-1]*d[6]+x.b[i-1];
for (j=1,k=5;j<=5;j++) {
if (j==i || j==i-1) continue;
x.u2+=x.a[j]*d[k--];
}
return 1;
}
void check(int e)
{
int i;
++tot;st[tot].e=e;
for (i=1;i<=5;i++) st[tot].a[i]=a[i],st[tot].b[i]=b[i];
sort(st[tot]);
if (tonghuashun(st[tot])) return ;
if (shunzi(st[tot])) return ;
for (i=1;i<=5;i++) st[tot].a[i]=(st[tot].a[i]==1) ? 14 : st[tot].a[i];
sort(st[tot]);
if (tonghuashun(st[tot])) return ;
if (sitiao(st[tot])) return ;
if (mantanghong(st[tot])) return ;
if (tonghua(st[tot])) return ;
if (shunzi(st[tot])) return ;
if (santiao(st[tot])) return ;
if (liangdui(st[tot])) return ;
if (yidui(st[tot])) return ;
st[tot].u1=1,yasuo(st[tot]);
}
void dfs(int x,int e,int lim1,int lim2)
{
if (x>5) {
check(e);return ;
}
int i,j;
for (i=lim1;i<=13;i++) {
for (j=(i!=lim1) ? 1 : lim2;j<=4;j++)
if (!v[i][j]) {
a[x]=i,b[x]=j;
v[i][j]=1;
u[i]++,o[j]++,u[14]=(i==1) ? u[14]+1 : u[14];
dfs(x+1,e,i,j);
a[x]=b[x]=0;
v[i][j]=0;
u[i]--,o[j]--,u[14]=(i==1) ? u[14]-1 : u[14];
}
}
}
long long gcd(long long a,long long b)
{
long long t;
for (;a%b;) {
t=a%b;
a=b;
b=t;
}
return b;
}
int cmp(const void *i,const void *j)
{
pi=*(int *)i,qi=*(int *)j;
if (st[pi].u1!=st[qi].u1) return st[pi].u1-st[qi].u1;
return st[pi].u2-st[qi].u2;
}
void init()
{
int i,j,x,y,k,e,sum;
scanf("%d\n",&n);
for (i=2,d[1]=15;i<=6;i++) d[i]=d[i-1]*15;
for (i=1;i<=n;i++) {
scanf("%d%d\n",&x,&y);y=4-y+1;
a[i]=x,b[i]=y;
v[x][y]=1;
u[x]++,o[y]++,u[14]=(x==1) ? u[14]+1 : u[14];
}
for (i=1;i<=n-1;i++) scanf("%d%d\n",&xx[i],&yy[i]),v[xx[i]][4-yy[i]+1]=1;
dfs(n+1,0,1,1);
memset(a,0,sizeof(a));memset(b,0,sizeof(b));memset(o,0,sizeof(o));
for (i=1;i<=15;i++) u[i]=0;
for (i=1;i<=n-1;i++) {
x=xx[i],y=4-yy[i]+1;
a[i]=x,b[i]=y;
v[x][y]=1;
u[x]++,o[y]++,u[14]=(x==1) ? u[14]+1 : u[14];
}
dfs(n,1,1,1);
for (ans2=0,i=1;i<=tot;i++) {
u[i]=i;
if (st[i].e) continue;
x=47-n+1,y=5-n+1;
for (sum=1,j=x;j>=x-y+1;j--) sum*=j;
for (j=1;j<=y;j++) sum/=j;
ans2+=sum;
}
qsort(u+1,tot,sizeof(u[1]),cmp);
for (i=1,sum=0;i<=tot;i++) {
if (st[u[i]].e==0) f[0]+=sum;else sum+=1;
if (st[u[i]].a[1]!=14) continue;
for (j=1;j<=5;j++)
st[u[i]].a[j]=(st[u[i]].a[j]==14) ? 1 : st[u[i]].a[j];
sort(st[u[i]]);
}
for (i=2,p[1]=1;i<=5;i++) p[i]=p[i-1]*53;
for (i=1;i<=tot;i++) {
for (j=1;j<=30;j++) {
for (k=1,e=0,debug=0;k<=5;k++)
if ((j>>(k-1))&1 && !v[st[u[i]].a[k]][st[u[i]].b[k]])
debug+=((st[u[i]].a[k]-1)*4+st[u[i]].b[k])*p[++e];else if (j>>(k-1)&1) break;
if (k<=5) continue;
if (!st[u[i]].e) f[j]+=g[debug];
else g[debug]++;
}
}
for (ans1=0,i=0;i<=30;i++) {
if (!f[i]) continue;
for (e=1,k=i;k;k>>=1) if (k&1) e*=-1;
ans1+=f[i]*e;
}
long long gc=gcd(ans1,ans2);
printf(fmt64"/"fmt64,ans1/gc,ans2/gc);
}
int main()
{
freopen("showhand.in","r",stdin);
freopen("showhand.out","w",stdout);
init();
return 0;
}