JSOI2009 游戏

1443: [JSOI2009]游戏Game

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 557  Solved: 251
[Submit][Status]

Description

Input

输入数据首先输入两个整数N,M,表示了迷宫的边长。 接下来N行,每行M个字符,描述了迷宫。

Output

若小AA能够赢得游戏,则输出一行"WIN",然后输出所有可以赢得游戏的起始位置,按行优先顺序输出 每行一个,否则输出一行"LOSE"(不包含引号)。

Sample Input

3 3
.##
...
#.#

Sample Output

2 3
3 2

HINT

对于100%的数据,有1≤n,m≤100。 
对于30%的数据,有1≤n,m≤5。

Source

JSOI2009Day2

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #define rep(i,n) for (int i=1;i<=n;i++)
 6 #define num(i,j) (i-1)*m+j
 7
 8 using namespace std;
 9
10 const int N=105;
11 const int d[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
12 char map[N][N];
13 int ans[N],n,m,i,j,nx,ny,cnt,tot,linker[N*N],tmp[N*N],g[N*N][5];
14 bool v[N*N],fail[N*N],black[N*N],flag;
15
16 void init()
17 {
18     scanf("%d%d",&n,&m);
19     rep(i,n) scanf("%s",map[i]+1);
20     rep(i,n)rep(j,m)
21     {
22         if (map[i][j]==‘#‘) {fail[num(i,j)]=1;continue;}
23         if ((i+j)%2==0) black[num(i,j)]=1;
24         for (int k=0;k<4;k++)
25         {
26             nx=i+d[k][0];ny=j+d[k][1];
27             if (nx<1||nx>n||ny<1||ny>m||map[nx][ny]==‘#‘) continue;
28             int u=num(i,j),v=num(nx,ny);
29             g[u][++g[u][0]]=v;
30         }
31     }
32 }
33
34 int dfs(int x)
35 {
36     rep(i,g[x][0])
37     {
38         int t=g[x][i];
39         if (v[t]) continue;
40         v[t]=1;
41         if (linker[t]==0||dfs(linker[t]))
42         {
43             linker[t]=x;
44             linker[x]=t;
45             return 1;
46         }
47     }
48     return 0;
49 }
50
51 void dawn()
52 {
53     for (int i=1;i<=n*m;i++) if (!fail[i]&&black[i])
54     {
55         memset(v,0,sizeof(v));
56         if (dfs(i)) cnt++;
57     }
58     flag=1;
59     rep(i,n*m) if (!fail[i])
60     {
61         memset(v,0,sizeof(v));
62         v[i]=1;
63         if (!linker[i]||dfs(linker[i]))
64         {
65             tot++;
66             if (flag) puts("WIN"),flag=0;
67             linker[i]=0,printf("%d %d\n",(i-1)/m+1,(i-1)%m+1);
68         }
69     }
70     if (!tot) puts("LOSE");
71 }
72
73 int main()
74 {
75     //freopen("1.txt","r",stdin);
76     //freopen("2.txt","w",stdout);
77     init();
78     dawn();
79     //while (1);
80 }

--lyd

貌似整个算法的流程是:

1.黑白染色

2.对黑、白进行二分图最大匹配

3.枚举每一个可达点,若该点可不再最大匹配中,则输出该点

…………

Is this ok? 反正AC了,原理在哪里?这样就行了?

JSOI2009 游戏

时间: 2024-10-01 05:59:02

JSOI2009 游戏的相关文章

BZOJ1443: [JSOI2009]游戏Game

如果没有不能走的格子的话,和BZOJ2463一样,直接判断是否能二分图匹配 现在有了一些不能走的格子 黑白染色后求出最大匹配 如果是完备匹配,则无论如何后手都能转移到1*2的另一端,故先手必输 否则的话,将棋子放在不是必须点的点上则先手必赢 证明是这样的: 先手先选一个不在最大匹配里面的点,然后对手有两种情况: 一.走一个在最大匹配里的点,然后有了上面考虑错的那种情况,但是不同的是,如果出现了后手最后走某边达到一个非最大匹配中点,就代表出现了一条增广路,显然因为是最大匹配,所以这种情况是不会出现

BZOJ:1443: [JSOI2009]游戏Game

原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1443 反正不看题解我是完全想不出系列-- 先把棋盘黑白染色,也就是同一对角线上颜色相同,使得一个格子上下左右都不同色. 然后我们会发现,某一个人所走的全部格子颜色都是相同的. 把黑白格子当作点提取出来,放在两边,就变成了二分图,游戏的全过程变得像匈牙利算法的增广. 这提示我们也许跟二分图匹配有关. 如果一个点必定在最大匹配中,而一开始棋子放在了这里小YY只要沿着匹配边走小AA就gg了.

二分图的一些题目合集

妈蛋状态都被狗吃了,已经开始不自觉对着电脑发呆……被几道二分图的题亮瞎了双眼(这么弱可是gdkoi只剩一个月gdoi只剩100+天……!!) wikioi1222信与信封问题 二分图,但是判断两个合集中的某两个点是不是只能连在一起.那么我们就在跑一边最大匹配后直接用是否可以增广来判断.如果可以增广那么这两个点是有其他方式连在一起的,否则这两个点就必须连在一起.具体做法是先去掉这两个点的边,不过那么match数组也要跟着改一下. var map:array[0..200,0..200]of boo

博弈论题表(好少~~~)

bzoj2017:[Usaco2009 Nov]硬币游戏 *用了一小点思想的傻逼dp(记忆化搜索)bzoj1188:[HNOI2007]分裂游戏 **很神奇的把游戏拆分为子游戏的方法bzoj1022:[SHOI2008]小约翰的游戏John *傻逼SJ定理题bzoj1982:[Spoj 2021]Moving Pebbles **思路不一般的并不是很难证的傻逼结论题bzoj2688:Green Hackenbush **切树模型的傻逼概率dp(外有特殊的飞行技巧-判0剪枝)bzoj2281:[S

【算法总结】博弈论相关

[相关资料] <博弈论 SG函数> [相关题目] 1.[bzoj1188][HNOI2007]分裂游戏 题意:共有n个瓶子,标号为0,1,2.....n-1,第i个瓶子中装有p[i]颗巧克力豆,两个人轮流取豆子,每一轮每人选择3个瓶子,标号为i,j,k,并要保证i<j,j<=k且第i个瓶子中至少要有1颗巧克力豆.随后这个人从第i个瓶子中拿走一颗豆子并在j,k中各放入一粒豆子(j可能等于k).如果轮到某人而他无法按规则取豆子,那么他将输掉比赛.问先手必胜策略的第一步方案. 分析:hz

【BZOJ1444】[Jsoi2009]有趣的游戏 AC自动机+概率DP+矩阵乘法

[BZOJ1444][Jsoi2009]有趣的游戏 Description Input 注意 是0<=P Output Sample Input Sample Output HINT  30%的数据保证, n ≤ 2. 50%的数据保证, n ≤ 5. 100%的数据保证, n , l, m≤ 10. 题解:本题的做法真的很多啊,概率DP,期望DP,当然还有矩乘黑科技~ 就是先跑AC自动机,弄出转移矩阵,然后自乘50次就行了. #include <cstdio> #include <

【BZOJ1443】【JSOI2009】游戏Game 二分图+博弈

#include <stdio.h> int main() { puts("转载请注明出处谢谢"); puts("http://blog.csdn.net/vmurder/article/details/43311795"); } 题解:二分图博弈经典模型模板题. 首先黑白染色. 然后我们考虑到有一种优秀的走法, 就是先求个最大匹配,然后如果先手选择了一个最大匹配中的点,那么显然后手可以依照此点的匹配再走一步,然后先手无法走此匹配,就乱走一气,于是有两种

BZOJ1444 : [Jsoi2009]有趣的游戏

建立AC自动机,并求出转移矩阵. 再用$\sum E(终止节点)=1$去替换第一个方程,高斯消元即可. 时间复杂度$O(n^3l^3)$. 注意精度问题,要特判0.00的情况. #include<cstdio> #include<cmath> #include<algorithm> #define N 110 using namespace std; int n,l,S,i,j,k,tot,son[N][10],v[N],fail[N],q[N],fin[N]; cha

BZOJ 1444 JSOI2009 有趣的游戏 AC自动机+矩阵乘法

题目大意:给定n个长度为l的模式串,现在要用前m个大写字母生成一个随机串,每个字符有自己的出现几率,第一次出现的字符串获胜,求最终每个字符串的获胜几率 建出AC自动机,搞出转移矩阵 如果某个节点是模式串那么这个节点只向自己连一条概率为1的出边 然后把转移矩阵自乘50遍即可 #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 120 us