2019HDU多校第四场 Just an Old Puzzle ——八数码有解条件
理论基础
轮换与对换
概念:把 $S$ 中的元素 $i_1$ 变成 $i_2$,$i_2$ 变成 $i_3$ ... $i_k$ 又变成 $i_1$,并使 $S$ 中的其余元素保持不变的置换称为循环,又称轮换,记为 $(i_1, i_2,...,i_k)$,$k$ 称为循环长度,特别地,循环长度为2的循环称为对换。
定理:
(1)任一置换可表示成若干个无公共元素的循环之积
(2)任一置换可表示成若干个对换之积,且对换个数的奇偶性不变。
八数码中的置换
若一个置换可以分解成奇数个对换之积称为奇置换,否则称为偶置换.

即进行如下置换:
$$\begin{pmatrix}
1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 & 0 & 12 & 13 & 14 & 11 & 15\\ 
1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 & 11 & 12 & 13 & 14 & 15 & 0
\end{pmatrix}$$
等价于轮换之积:
$\begin{pmatrix}
0 & 11 & 15\\ 
11 & 15 & 0
\end{pmatrix} = \left ( 0 \  11 \ 15\right ) = (0 \ 11)(0 \ 15)$
当置换的奇偶性与空格移动的奇偶性相同则有解,反之无解。
这是一个偶置换,而空格移动到右下角也是偶数步,所以是有解的。
然而,求两个状态的置换不方便实现,对换的奇偶性等价于逆序对奇偶性(gugu,我猜的)
逆序对
如果我们从上到下、从左到右展开成一维数组,某状态的奇偶性定义为逆序对(不包括0的)总数的奇偶性。
首先,空格的左右移动不会改变逆序对奇偶性
列数为奇数时,上下移动不改变奇偶性
列数为偶数时,上下移动奇偶取反。
大概的证明如下:

题目
由于是15数码,列数为偶数,且终态逆序对为偶数,所以只需 y%2=pair%2,y为空格到右下角的纵距离,pair为初始状态的逆序对数。
值得一提的是,题目有个120步的迷惑条件,维基百科有:十五数码的最优解至多80步,而八数码推盘的最优解至多31步。(数字推盘游戏)
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std; const int maxn = ;
int a[maxn]; struct BIT{
int C[maxn], n;
void init(int n)
{
this->n = n;
memset(C, , sizeof(C));
// for (int i = 1; i <= n; i++)
// add(i, a[i]);
}
int lowbit(int x)
{
return x & -x;
}
int sum(int x)
{
int ret = ;
while (x > )
{
ret += C[x];
x -= lowbit(x);
}
return ret;
}
void add(int x, int d)
{
while (x <= n)
{
C[x] += d;
x += lowbit(x);
}
}
int getPair()
{
int ret = ;
for(int i = n;i >=;i--)
{
ret += sum(a[i] - );
add(a[i], );
}
return ret;
}
}bit; int main()
{
int T;
scanf("%d", &T);
while(T--)
{
int cnt = , y;
for(int i = ;i <= ;i++)
{
int tmp;
scanf("%d", &tmp);
if(!tmp) y = - (i-)/;
else a[++cnt] = tmp;
}
bit.init(cnt); //printf("%d %d %d\n", bit.n, bit.getPair(), y);
if(y% == bit.getPair()%) printf("Yes\n");
else printf("No\n");
} return ;
}
参考链接:http://www.voidcn.com/article/p-wsmvxpvl-bbo.html
2019HDU多校第四场 Just an Old Puzzle ——八数码有解条件的更多相关文章
- 2019HDU多校第四场 K-th Closest Distance ——主席树&&二分
		
题意 给定 $n$ 个数,接下来有 $q$ 次询问,每个询问的 $l, r, p, k$ 要异或上一次的答案,才是真正的值(也就是强制在线).每次询问,输出 $[l, r]$ 内第 $k$ 小的 $| ...
 - [2019HDU多校第四场][HDU 6617][D. Enveloping Convex]
		
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6617 题目大意:给出一凸包\(P\),求最小的与\(P\)相似且对应边平行的多边形,使得题目给出的\( ...
 - 2019HDU多校第四场题解
		
1001.AND Minimum Spanning Tree 传送门:HDU6614 题意:给你一个又n个点的完全图,点编号从1~n,每条边的权值为被连接的两点编号按位与后的值.现在要你找到最小生成树 ...
 - 2018 HDU多校第四场赛后补题
		
2018 HDU多校第四场赛后补题 自己学校出的毒瘤场..吃枣药丸 hdu中的题号是6332 - 6343. K. Expression in Memories 题意: 判断一个简化版的算术表达式是否 ...
 - 牛客多校第四场sequence C (线段树+单调栈)
		
牛客多校第四场sequence C (线段树+单调栈) 传送门:https://ac.nowcoder.com/acm/contest/884/C 题意: 求一个$\max {1 \leq l \le ...
 - 【2019HDU多校】第九场1006/HDU6685-Rikka with Coin——位运算打表
		
题目链接 题目大意 使用10.20.50.100元面额的硬币能分别组成题目给出的面额,需要最少的硬币个数 分析 一开始队友想用一堆if-else解决问题,然后WA了无数发-- 我想到了一种比较简单的打 ...
 - 2019HDU多校第七场 HDU6646 A + B = C 【模拟】
		
一.题目 A + B = C 二.分析 比较考验码力的题. 对于$c$,因为首位肯定不为0,那么$a$或者$b$至少有一个最高位是和$c$平齐的,或者少一位(相当于$a$+$b$进位得到). 那么这里 ...
 - 2014多校第四场1006  || HDU 4902 Nice boat (线段树 区间更新)
		
题目链接 题意 : 给你n个初值,然后进行两种操作,第一种操作是将(L,R)这一区间上所有的数变成x,第二种操作是将(L,R)这一区间上所有大于x的数a[i]变成gcd(x,a[i]).输出最后n个数 ...
 - 2014多校第四场1005 || HDU 4901 The Romantic Hero (DP)
		
题目链接 题意 :给你一个数列,让你从中挑选一些数组成集合S,挑另外一些数组成集合T,要求是S中的每一个数在原序列中的下标要小于T中每一个数在原序列中下标.S中所有数按位异或后的值要与T中所有的数按位 ...
 
随机推荐
- K8S从入门到放弃系列-(4)kubernetes集群之kubectl命令行工具部署
			
摘要:随着版本的不断迭代,k8s为了集群安全,集群中趋向采用TLS+RBAC的安全配置方式,所以我们在部署过程中,所有组件都需要证书,并启用RBAC认证. 我们这里采用二进制安装,下载解压后,把对应组 ...
 - oracle 列合并成并用拼接符拼接 -- LISTAGG函数用法
			
==注:wm_concat(str1) 11g 后不支持使用== LISTAGG函数用法 select LISTAGG(name, ',') WITHIN GROUP (ORDER BY id) fr ...
 - 转载:微信开放平台开发第三方授权登陆(二):PC网页端
			
微信开放平台开发第三方授权登陆(二):PC网页端 2018年07月24日 15:13:32 晋文子上 阅读数 12644更多 分类专栏: 微信开发 第三方授权登录 版权声明:本文为博主原创文章,遵 ...
 - eclipse3.62开发第一个java程序HelloWorld
			
[学习笔记] 用eclipse3.62开发第一个java程序: 使用eclipse之前们需要先配置一下jdk.window/preference/java/installed JREs,详细请见视频. ...
 - MyEclipse开发第一个java程序HelloWorld
			
[学习笔记] 用MyEclipse开发第一个java程序: 我们先看看一个具体例子,给你们有个先入为主的感觉. 步骤一:在Eclipse开发工具中我们New一个java项目, 如图2_1 图2_1 步 ...
 - vscode配置phpxdebug
			
打debug还是很有必要的,以前嫌麻烦,现在觉得,通过debug可以看自己写的代码的执行的逻辑,更容易理清别人代码的逻辑. 步骤: 下载phpdebug插件 查看自己的php版本信息,下载对应的deb ...
 - ORACLE 的前后台进程
			
关于oracle用户进程,服务进程,后台进程 用户进程(User Process) 是一个需要与Oracle Server交互的程序 运行于客户端 当用户运行某个工具或应用程序(如SQL*Plus)时 ...
 - (1+x)^n
			
#include<stdio.h> int main() { int n,i; while(scanf("%d %d",&n,&i)!=EOF) { i ...
 - Angular系列-AngularJs1使用Ace编辑器
			
Ace编辑器 Ace编辑器是一个嵌入web的代码编辑器,支持语法高亮,自动补全等功能,如果想在页面展示或编辑代码,使用该工具是很合适的. 参考项目地址:https://github.com/ajaxo ...
 - .net core mvc + mysql dbfirst  生成 ado.net 数据模型
			
1.点击“工具”->“NuGet包管理器”->“程序包管理器控制台” 安装一下包 Install-Package MySql.Data.EntityFrameworkCore -Pre I ...