HDU 3446 daizhenyang's chess

http://acm.hdu.edu.cn/showproblem.php?pid=3446

题意:一个棋盘,有个KING,有一些能走的点,每次只能走到没走过的地方,没路可走的输,求先手是否必胜。

思路:先去掉KING的位置,只考虑其他的,如果这样求出的匹配数和加上king的匹配数一样,说明KING这个位置没有在匹配中,因此后手必胜,否则先手必胜,为什么?

可以思考一下,匹配的路径是一条:匹配,不匹配,匹配。。。不匹配,匹配,因此如果KING在匹配中,那最后一步也能够是先手走的。

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
int dx[]={-1,-1,-1,1,1,1,0,0,2,-2,2,-2,2,-2,2,-2,1,-1,-1,1};
int dy[]={-1,1,0,0,1,-1,-1,1,2,2,-2,-2,1,-1,-1,1,2,-2,2,-2};
int match[250],G[250][250],inpath[250],q[250],head,tail,newbase;
int inqueue[250],inblossom[250],base[250],father[250],n;
int finish,start,R,C,kx,ky,c[250];
char s[25][25];
int read(){
    int t=0,f=1;char ch=getchar();
    while (ch<‘0‘||ch>‘9‘){if (ch==‘-‘) f=-1;ch=getchar();}
    while (‘0‘<=ch&&ch<=‘9‘){t=t*10+ch-‘0‘;ch=getchar();}
    return t*f;
}
int lca(int u,int v){
    memset(inpath,0,sizeof inpath);
    while (1){
        u=base[u];
        inpath[u]=1;
        if (!match[u]) break;
        u=father[match[u]];
    }
    while (1){
        v=base[v];
        if (inpath[v]) break;
        v=father[match[v]];
    }
    return v;
}
void reset(int u){
    while (u!=newbase){
        int v=match[u];
        inblossom[base[v]]=inblossom[base[u]]=1;
        u=father[v];
        if (base[u]!=newbase) father[u]=v;
    }
}
void blossomcontract(int u,int v){
    newbase=lca(u,v);
    memset(inblossom,0,sizeof inblossom);
    reset(u);
    reset(v);
    if (base[u]!=newbase) father[u]=v;
    if (base[v]!=newbase) father[v]=u;
    for (int i=1;i<=n;i++)
     if (inblossom[base[i]]){
            base[i]=newbase;
            if (!inqueue[i]) c[++tail]=i,inqueue[i]=1;
     }
}
void findaugmentingpath(){
    memset(inqueue,0,sizeof inqueue);
    memset(father,0,sizeof father);
    for (int i=1;i<=n;i++) base[i]=i;
    head=1;tail=1;c[1]=start;inqueue[start]=1;
    finish=0;
    while (head<=tail){
        int u=c[head++];
        for (int v=1;v<=n;v++)
         if (G[u][v]&&base[u]!=base[v]&&match[v]!=u){
                if (v==start||(match[v]>0)&&(father[match[v]]>0)){
                    blossomcontract(u,v);
                }else
                if (father[v]==0){
                    father[v]=u;
                    if (match[v]){
                        c[++tail]=match[v];inqueue[match[v]]=1;
                    }else{
                        finish=v;
                        return;
                    }
                }
         }
    }
}
void augmentpath(){
    int u,v,w;
    u=finish;
    while (u>0){
        v=father[u];
        w=match[v];
        match[u]=v;
        match[v]=u;
        u=w;
    }
}
int solve(){
    int res=0;
    memset(match,0,sizeof match);
    for (int i=1;i<=n;i++)
     if (!match[i]){
        start=i;
        findaugmentingpath();
        if (finish) augmentpath(),res++;
     }
    return res;
}
int main(){
    int T=read(),Tcase=0;
    while (T--){
        printf("Case #%d: daizhenyang ",++Tcase);
        R=read();C=read();
        memset(G,0,sizeof G);
        for (int i=1;i<=R;i++){
            scanf("%s",s[i]+1);
        }
        for (int i=1;i<=R;i++)
         for (int j=1;j<=C;j++)
          if (s[i][j]!=‘#‘){
           for (int k=0;k<20;k++){
                int x=i+dx[k],y=j+dy[k];
                if (x>=1&&x<=R&&y>=1&&y<=C&&s[x][y]!=‘#‘){
                    G[(i-1)*C+j][(x-1)*C+y]=1;
                    G[(x-1)*C+y][(i-1)*C+j]=1;
                }
           }
           if (s[i][j]==‘K‘) kx=i,ky=j;
          }
        n=R*C;
        int t1=solve();
        int x=(kx-1)*C+ky;
        for (int i=1;i<=n;i++) if (G[x][i]) G[x][i]=G[i][x]=0;
        if (solve()==t1) puts("lose");
        else puts("win");
    }
    return 0;
}

HDU 3446 daizhenyang's chess

时间: 2024-10-18 21:49:15

HDU 3446 daizhenyang's chess的相关文章

hdu3446 daizhenyang&#39;s chess 【一般图匹配】

链接:http://acm.hdu.edu.cn/showproblem.php?pid=3446 题意:在一个R行C列的棋盘上,俩个人轮流移动一个棋子,每次可以向相邻的20个格子移动,走过的每个格子自能走一次.另外,某些各自一开始就固定了不能走.  无法移动者输.问:先手能否赢. 分析:首先,忽略K点,将其他能相互移动的格子连边,求一次最大匹配,再将K点加入图中,若存在增广路,则先手赢,否则后手赢. 代码: #include<algorithm> #include<iostream&g

HDU 3537 Daizhenyang&#39;s Coin(博弈-sg)

Daizhenyang's Coin Problem Description We know that Daizhenyang is chasing a girlfriend. As we all know, whenever you chase a beautiful girl, there'll always be an opponent, or a rival. In order to take one step ahead in this chasing process, Daizhen

HDU 4405:Aeroplane chess(概率DP入门)

http://acm.split.hdu.edu.cn/showproblem.php?pid=4405 Aeroplane chess Problem Description Hzz loves aeroplane chess very much. The chess map contains N+1 grids labeled from 0 to N. Hzz starts at grid 0. For each step he throws a dice(a dice have six f

HDU 4405:Aeroplane chess 概率DP求期望

One Person Game 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4405 题意: 有个人在玩飞行棋,规则是:掷一个骰子,就能从当前点x飞到(x+点数)处,在棋盘上有一些飞行通道,如果点x和点y间存在飞行通道,那么当你走到点x,就会飞到点y处,起点在0,求从起点飞到终点n所需要投掷骰子次数的期望. 题解: 一道简单的求期望的题,不会求期望的可以看下这里 当点i是飞行通道的起点的时候,由于不需要投掷骰子,就能飞到飞行通道的终点处,所以此

HDU 4405(Aeroplane chess)

Aeroplane chess Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2060    Accepted Submission(s): 1346 Problem Description Hzz loves aeroplane chess very much. The chess map contains N+1 grids lab

HDU 5794 A Simple Chess(杨辉三角+容斥原理+Lucas)

题目链接 A Simple Chess 打表发现这其实是一个杨辉三角…… 然后发现很多格子上方案数都是0 对于那写可能可以到达的点(先不考虑障碍点),我们先叫做有效的点 对于那些障碍,如果不在有效点上,则自动忽略 障碍$(A, B)$如果有效,那么就要进行如下操作: 以这个点为一个新的杨辉三角的顶点,算出目标点的坐标$(x, y)$. 目标点的答案减去$C(A, B) * C(x, y)$的值. 但是这样会造成重复计算,原因是障碍之间可能有相互影响的关系. 这个时候就要考虑容斥原理,DFS消除这

【HDU】4405 Aeroplane chess

http://acm.hdu.edu.cn/showproblem.php?pid=4405 题意:每次可以走1~6格,初始化在第0格,走到>=n的格子就结束.还有m个传送门,表示可以从X[i]格传送到Y[i]而不需要消耗次数,X[i]<Y[i].n<=100000, m<=1000. #include <cstdio> #include <cstring> using namespace std; double d[100010]; int n, m, m

HDU 5794 A Simple Chess (Lucas + dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5794 多校这题转化一下模型跟cf560E基本一样,可以先做cf上的这个题. 题目让你求一个棋子开始在(1,1),只能像马一样走且往右下方走,不经过坏点,有多少种走法能到达(n,m)点. 比如n=6, m=5 有两个坏点,模型转换 如下图: 转换成简单模型之后,只要把棋子可能经过的坏点存到结构体中,按照x与y从小到大排序. dp[i]表示从起点到第i个坏点且不经过其他坏点的方案数. dp[i] = L

HDU 4403(Aeroplane chess ,求期望,概率DP)

Aeroplane chess Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description Hzz loves aeroplane chess very much. The chess map contains N+1 grids labeled from 0 to N. Hzz starts at grid 0. For each step he