[BZOJ]1059 矩阵游戏(ZJOI2007)
虽然说是一道水题,但小C觉得还是挺有意思的,所以在这里mark一下。
Description
Input
Output
输出文件应包含T行。对于每一组数据,如果该关卡有解,输出一行Yes;否则输出一行No。
Sample Input
2
2
0 0
0 1
3
0 0 1
0 1 0
1 0 0
Sample Output
No
Yes
HINT
对于100%的数据,N ≤ 200。
Solution
拿到这道题目肯定要思考,什么样的局面通过交换行列可以变成主对角线上都为黑格的情况?
由于交换是可逆的,我们倒过来思考,主对角线上都是黑格的情况通过交换行列可以变成什么局面。
这样就一目了然了。一开始是1~n的排列,每次交换行列相当于交换两个位置上的数字。
这样问题就转化成:是否能从每行选出恰好一个黑格,n行黑格代表的列数正好组成一个1~n的全排列。
正解是二分图匹配。全排列可以看作是行和列的匹配,思路很清晰。时间复杂度O(n^2)(匈牙利算法)/O(n^1.5)(网络流)。
但是小C这里要介绍的,是另一种做法。
想到矩阵和排列,我们会很自然地想起行列式。
我们思考一下行列式的计算公式:
。
发现如果一个排列上的所有数都不为0,就一定会对答案有贡献!
所以我们就直接求这个矩阵的行列式的值就可以了???复杂度O(n^3)。
当然不行,这些排列对答案的贡献有正有负,矩阵的值全为0或1的话很容易凑出0。例如{{0,1,1},{0,1,1},{1,0,0}}。
那怎么办?
很简单啊,我们给矩阵里的黑格都随机一个权值就好了嘛。
什么?还是WA?
我们来看一看行列式等于0还有什么条件:
1.有一行或一列全为0的情况;
2.有两行或两列数值成比例的情况;
3.行向量之间或列向量之间有相关的情况;
4.逆矩阵不存在的情况:
5.行列式对应的矩阵的秩小于行列式的阶数的情况……
够了!似乎第二条看起来特别扎眼,于是我们给矩阵里的黑格都随机一个质数权值如何?
过了卧槽。
二分图匹配:
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MN 205
using namespace std;
bool u[MN],mp[MN][MN];
int mat[][MN];
int t,n; inline int read()
{
int n=,f=; char c=getchar();
while (c<'' || c>'') {if(c=='-')f=-; c=getchar();}
while (c>='' && c<='') {n=n*+c-''; c=getchar();}
return n*f;
} bool dfs(int x)
{
if (u[x]) return false;
u[x]=true;
for (register int i=;i<=n;++i)
{
if (!mp[x][i]||mat[][x]==i) continue;
if (!mat[][i]||dfs(mat[][i])) {mat[][x]=i; mat[][i]=x; return true;}
}
return false;
} int main()
{
register int i,j;
t=read();
while (t--)
{
n=read();
for (i=;i<=n;++i)
for (j=;j<=n;++j) mp[i][j]=read();
memset(mat,,sizeof(mat));
for (i=;i<=n;++i)
{
memset(u,,sizeof(u));
if (!dfs(i)) break;
}
if (i<=n) puts("No"); else puts("Yes");
}
}
高斯消元求行列式:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#define mod 1000000007
#define MP 2000005
#define MN 205
using namespace std;
int a[MN][MN],p[MP];
bool u[MP];
int t,n,pin; inline int read()
{
int n=,f=; char c=getchar();
while (c<'' || c>'') {if(c=='-')f=-; c=getchar();}
while (c>='' && c<='') {n=n*+c-''; c=getchar();}
return n*f;
} int mi(int x,int y)
{
register int z=;
for (;y;x=1LL*x*x%mod,y>>=) if (y&) z=1LL*z*x%mod;
return z;
} void init()
{
register int i,j;
for (i=;i<MP;++i)
{
if (!u[i]) p[++pin]=i;
for (j=;i*p[j]<MP;++j)
{
u[i*p[j]]=true;
if (i%p[j]==) break;
}
}
} int main()
{
register int i,j,k,x,mxi,lt;
srand(); init();
t=read();
while (t--)
{
n=read();
for (i=;i<=n;++i)
for (j=;j<=n;++j)
if (read()&) a[i][j]=p[(rand()*rand()%pin+rand())%pin+];
else a[i][j]=;
for (i=;i<n;++i)
{
mxi=i;
for (j=i+;j<=n;++j) if (a[j][i]>a[mxi][i]) mxi=j;
if (mxi!=i) swap(a[mxi],a[i]);
if (!a[i][i]) break;
for (j=i+;j<=n;++j)
for (lt=1LL*mi(a[i][i],mod-)*a[j][i]%mod,k=i;k<=n;++k)
a[j][k]=(a[j][k]-1LL*a[i][k]*lt%mod+mod)%mod;
}
if (i<n||!a[n][n]) puts("No"); else puts("Yes");
}
}
Last Word
行列式还能这么用.jpg。
这题又让小C了解了一下行列式的一点点性质,好像还练习了一下乱搞技巧?
小C的n^3做法似乎成功拿到了bzoj那一题的垫底:

[BZOJ]1059 矩阵游戏(ZJOI2007)的更多相关文章
- BZOJ 1059 矩阵游戏
Description 小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏--矩阵游戏.矩阵游戏在一个\(N \times N\)黑白方阵进行(如同国际象棋一般,只是颜色是随意的). ...
- BZOJ 1059 矩阵游戏 二分图匹配
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1059 题目大意: 小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏 ...
- [bzoj]1059矩阵游戏<二分图匹配*匈牙利算法>
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1059 初见此题,我觉得这是水题,我认为只要每一行和每一列至少存在一个黑格就可以出现对角线, ...
- 洛谷 P1129 BZOJ 1059 cogs 660 [ZJOI2007]矩阵游戏
题目描述 小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏――矩阵游戏.矩阵游戏在一个N*N黑白方阵进行(如同国际象棋一般,只是颜色是随意的).每次可以对该矩阵进行两种操作: 行交 ...
- 矩阵游戏|ZJOI2007|BZOJ1059|codevs1433|luoguP1129|二分图匹配|匈牙利算法|Elena
1059: [ZJOI2007]矩阵游戏 Time Limit: 10 Sec Memory Limit: 162 MB Description 小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩 ...
- BZOJ 3240 矩阵游戏
Description 婷婷是个喜欢矩阵的小朋友,有一天她想用电脑生成一个巨大的\(n\)行\(m\)列的矩阵(你不用担心她如何存储).她生成的这个矩阵满足一个神奇的性质:若用\(F[i][j]\)来 ...
- 【BZOJ】【1059】【ZJOI2007】矩阵游戏
二分图完美匹配/匈牙利算法 如果a[i][j]为黑点,我们就连边 i->j ,然后跑二分图最大匹配,看是否有完美匹配. <_<我们先考虑行变换:对于第 i 行,如果它第 j 位是黑点 ...
- bzoj 1059: [ZJOI2007]矩阵游戏 二分图匹配
1059: [ZJOI2007]矩阵游戏 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1891 Solved: 919[Submit][Statu ...
- BZOJ 1059 [ZJOI2007]矩阵游戏
1059: [ZJOI2007]矩阵游戏 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2707 Solved: 1322[Submit][Stat ...
随机推荐
- 树莓派3启动wifi并且配置wifi
概述 树莓派3内置了wifi和蓝牙模块,我们不用像以前的版本那样,再去购买一个外接的模块练到raspberry上. 当我们第一次启动了树莓派的时候,必然使用了网线,但是之后的每一次使用,我们当然更希望 ...
- NOIP2012 提高组 Day 2
http://www.cogs.pro/cogs/page/page.php?aid=16 期望得分:100+100+0=0 实际得分:100+20+0=120 T2线段树标记下传出错 T1 同余方程 ...
- sql 用临时表时报错 "Chinese_PRC_90_CI_AI" 和 "Chinese_PRC_CI_AS" 之间的排序规则冲突
在用临时表关联数据库中的表做关联查询时,如果报这种情况的话,就要把临时表和关联的表的排序规则统一掉. LEFT JOIN #tsub ON #tsub.joinjarno collate Chines ...
- WIN7 局域网共享打印机每次电脑重启后必须登录密码重新连接问题修复
第一步,WIN+R(或者开始->附件->运行)输入gpedit或gpedit.msc 进入 第二步:把这几个拒绝的Guest给删除掉,也可以只删除""拒绝从王洛访问这台 ...
- Mego开发文档 - 数据注释建模
数据注释建模 Mego框架使用一组约定来基于CLR类来构建模型.您可以指定其他配置来补充或覆盖通过约定发现的内容. 在 Mego 中所有的数据对象必须要有主键.这里需要声明与EF不同的是框架只支持数据 ...
- emqtt 试用(二)验证 emq 和 mosquito 的共享订阅
本地订阅(Local Subscription) 本地订阅(Local Subscription)只在本节点创建订阅与路由表,不会在集群节点间广播全局路由,非常适合物联网数据采集应用. 使用方式: 订 ...
- docker注意事项
当你最后投入容器的怀抱,发现它能解决很多问题,而且还具有众多的优点: 第一:它是不可变的 – 操作系统,库版本,配置,文件夹和应用都是一样的.您可以使用通过相同QA测试的镜像,使产品具有相同的表现 ...
- Scala入门(1)Linux下Scala(2.12.1)安装
Scala入门(1)Linux下Scala(2.12.1)安装 一.文件准备 1.1 文件名称 scala-2.12.1.tgz 1.2 下载地址 http://www.scala-lang.org/ ...
- Linux之Shell命令
开始接触Linux命令行,学习Linux文件系统导航以及创建.删除.处理文件所需的命令. 注:文末有福利! 几个快捷键: Linux发行版通常使用Ctrl+Alt组合键配合F1~F7进入要使用的控制 ...
- WebApi 基于token的多平台身份认证架构设计
1 概述 在存在账号体系的信息系统中,对身份的鉴定是非常重要的事情. 随着移动互联网时代到来,客户端的类型越来越多, 逐渐出现了 一个服务器,N个客户端的格局 . 不同的客户端产生了不同的用户使用 ...