Description
Input
输入数据首先输入两个整数N,M,表示了迷宫的边长。 接下来N行,每行M个字符,描述了迷宫。
Output
若小AA能够赢得游戏,则输出一行"WIN",然后输出所有可以赢得游戏的起始位置,按行优先顺序输出 每行一个,否则输出一行"LOSE"(不包含引号)。
Sample Input
3 3
.##
...
#.#
.##
...
#.#
Sample Output
WIN
2 3
3 2
2 3
3 2
HINT
对于100%的数据,有1≤n,m≤100。 对于30%的数据,有1≤n,m≤5。
这道题挺好,想我半天。。
首先看到这个图就想跑网络流,给他一套黑白染色操作,mengbier No.1
根据题意其实放棋子就是放障碍,如果它四周有联通块最大匹配不完美就GG
但是按这个复杂度跑会GG,mengbier No.2
继而想更优的方法,画个图跑一跑。。。
发现其实不用这么麻烦??
这是二分图匹配啊,如果你当前这个棋子可以不在完美匹配里跑就没问题啊??
有点不会表达看图吧:
像2号点,是不必要在这个二分图里面的,你放一个棋子,那么对手往哪边跑你都可以跑他的匹配,所以赢
但是如果在1点,就只能沿着边一直跑到死???然后就会爆炸
然后WIN要大写差评~~~ mengbier No.3
为什么这道题怎么水还要写这么多。。。
友情支援一组小数据:
/*
Sample Int
5 5
.....
.....
.....
.....
...#.
Sample Output
WIN
1 1
1 3
1 5
2 2
2 4
3 1
3 3
3 5
4 2
4 4
5 1
5 3
5 5
*/
代码如下:
#include<cmath> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; struct node{ int x,y,next; }a[210000];int len,last[210000]; void ins(int x,int y) { len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len; } const int dx[4]={1,0,-1,0}; const int dy[4]={0,1,0,-1}; struct form{ int x,y; }p[110000],ans[110000]; int n,m; int col[110][110]; int ys[110][110],id; char st[110]; bool in[11000]; int match[11000]; int tim,chw[11000]; bool findmuniu(int x) { for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(chw[y]!=tim) { chw[y]=tim; if(match[y]==0||findmuniu(match[y])==true) { in[y]=true; match[y]=x,match[x]=y; return true; } } } return false; } bool findanother(int x) { for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(chw[y]!=tim&&y!=match[x]) { chw[y]=tim; if(match[y]==0||findanother(match[y])==true) return true; } } return false; } /* Sample Int 5 5 ..... ..... ..... ..... ...#. Sample Output WIN 1 1 1 3 1 5 2 2 2 4 3 1 3 3 3 5 4 2 4 4 5 1 5 3 5 5 */ bool cmp(form a,form b){if(a.x==b.x)return a.y<b.y;return a.x<b.x;} int main() { scanf("%d%d",&n,&m);id=0; len=0;memset(last,0,sizeof(last)); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) col[i][j]=1; for(int i=1;i<=n;i++) { scanf("%s",st+1); for(int j=1;j<=m;j++) { if(st[j]=='.')ys[i][j]=++id,p[id].x=i,p[id].y=j; if(j==1)col[i][j]^=col[i-1][j]; else col[i][j]^=col[i][j-1]; } } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(ys[i][j]!=0&&col[i][j]%2==0) for(int k=0;k<4;k++) if(ys[i+dx[k]][j+dy[k]]!=0) ins(ys[i][j],ys[i+dx[k]][j+dy[k]]),ins(ys[i+dx[k]][j+dy[k]],ys[i][j]); tim=0; memset(match,0,sizeof(match)); memset(chw,0,sizeof(chw)); memset(in,false,sizeof(in)); for(int i=1;i<=id;i++) { if(col[p[i].x][p[i].y]==1)continue; tim++; if(findmuniu(i)==true)in[i]=true; } int tot=0; for(int i=1;i<=id;i++) { if(in[i]==false)ans[++tot]=p[i]; else { tim++; if(findanother(match[i])==true)ans[++tot]=p[i]; } } if(tot==0)printf("LOSE\n"); else { printf("WIN\n"); sort(ans+1,ans+1+tot,cmp); for(int i=1;i<tot;i++)printf("%d %d\n",ans[i].x,ans[i].y); printf("%d %d",ans[tot].x,ans[tot].y); } return 0; }
by_lmy