news 2026/6/10 3:01:40

P10454 奇数码问题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
P10454 奇数码问题

P10454 奇数码问题

题目描述

你一定玩过八数码游戏,它实际上是在一个3×33 \times 33×3的网格中进行的,111个空格和1∼81 \sim 818888个数字恰好不重不漏地分布在这3×33 \times 33×3的网格中。

例如:

5 2 8 1 3 _ 4 6 7

在游戏过程中,可以把空格与其上、下、左、右四个方向之一的数字交换(如果存在)。

例如在上例中,空格可与左、上、下面的数字交换,分别变成:

5 2 8 5 2 _ 5 2 8 1 _ 3 1 3 8 1 3 7 4 6 7 4 6 7 4 6 _

奇数码游戏是它的一个扩展,在一个n×nn \times nn×n的网格中进行,其中nnn为奇数,111个空格和1∼n2−11 \sim n^2-11n21n2−1n^2-1n21个数恰好不重不漏地分布在n×nn \times nn×n的网格中。

空格移动的规则与八数码游戏相同,实际上,八数码就是一个n=3n=3n=3的奇数码游戏。

现在给定两个奇数码游戏的局面,请判断是否存在一种移动空格的方式,使得其中一个局面可以变化到另一个局面。

输入格式

多组数据,对于每组数据:

111行输入一个整数nnnnnn为奇数。

接下来nnn行每行nnn个整数,表示第一个局面。

再接下来nnn行每行nnn个整数,表示第二个局面。

局面中每个整数都是0∼n2−10 \sim n^2-10n21之一,其中用000代表空格,其余数值与奇数码游戏中的意义相同,保证这些整数的分布不重不漏。

输出格式

对于每组数据,若两个局面可达,输出TAK,否则输出NIE

输入输出样例 #1

输入 #1

3 1 2 3 0 4 6 7 5 8 1 2 3 4 5 6 7 8 0 1 0 0

输出 #1

TAK TAK

说明/提示

1≤n<5001 \le n < 5001n<500

奇数码问题题解

这是我针对奇数码问题的解题题解,核心依托归并排序求逆序对来完成可达性判断,下面结合我的代码详细拆解解题思路。

一、题目分析

本题要求我们判断两个n×nn \times nn×nnnn为奇数)的奇数码局面是否可达,其中000代表空格,其余数字为1∼n2−11 \sim n^2-11n21,空格仅能与上下左右相邻数字交换。这是一道经典的数码问题,核心在于掌握奇数码局面可达性的判定定理,同时需要高效求解逆序对。

二、核心解题思路

1. 奇数码可达性判定定理

对于nnn为奇数的奇数码问题,两个局面可达的充要条件是:忽略空格(数字000)后,两个局面的数字序列的逆序对数量奇偶性相同。

  • 逆序对定义:对于一个数字序列,若存在两个数aia_iaiaja_jaji<ji < ji<j),满足ai>aja_i > a_jai>aj,则称这对数字为一个逆序对。
  • 为什么该定理成立?因为空格的移动(与相邻数字交换)不会改变整个序列逆序对数量的奇偶性,因此只有当两个局面的逆序对奇偶性一致时,才可以通过移动空格实现相互转化。

2. 逆序对的高效求解

由于nnn最大接近500500500n2n^2n2最大为250000250000250000,普通的暴力枚举(O(n4)O(n^4)O(n4))会超时,因此我采用归并排序求解逆序对,时间复杂度为O(mlog⁡m)O(m \log m)O(mlogm)m=n2m = n^2m=n2),能够高效处理最大数据量。

三、代码逐部分解析

intn;inta[250005];intt[250005];longlongans,ans1,ans2;voidms(intl,intr){if(l==r)return;// 递归终止条件:区间仅含一个元素,无需排序intm=(l+r)/2;ms(l,m);// 递归处理左区间 [l, m]ms(m+1,r);// 递归处理右区间 [m+1, r]intlp=l;// 左区间指针intrp=m+1;// 右区间指针inttp=l;// 临时数组t的指针while(lp<=m&&rp<=r){if(a[rp]<a[lp]){t[tp]=a[rp];if(a[rp]!=0){// 忽略空格0,不统计0参与的逆序对ans+=m-lp+1;// 核心:统计逆序对数量}tp++;rp++;}else{t[tp]=a[lp];tp++;lp++;}}// 处理左区间剩余元素while(lp<=m){t[tp]=a[lp];tp++;lp++;}// 处理右区间剩余元素while(rp<=r){t[tp]=a[rp];tp++;rp++;}// 将临时数组的有序元素复制回原数组afor(inti=l;i<=r;i++){a[i]=t[i];}return;}longlongcalc(intx){for(inti=1;i<=x*x;i++){cin>>a[i];// 读取x*x个元素,将二维矩阵展平为一维数组}ans=0;// 初始化逆序对数量为0ms(1,x*x);// 调用归并排序统计逆序对returnans;// 返回当前局面的逆序对数量}intmain(){while(cin>>n){// 多组输入,直到输入结束ans1=calc(n);// 计算第一个局面的逆序对数量ans2=calc(n);// 计算第二个局面的逆序对数量if(ans1%2==ans2%2){cout<<"TAK\n";// 奇偶性相同,可达}else{cout<<"NIE\n";// 奇偶性不同,不可达}}return0;}

1. 全局变量说明

  • nnn:存储奇数码矩阵的边长,因多组输入,在循环中读取。
  • a[]a[]a[]:用于存储展平后的n×nn \times nn×n数码矩阵(二维转一维,方便归并排序处理),数组大小250005250005250005是为了容纳500×500=250000500 \times 500 = 250000500×500=250000个元素,预留充足余量。
  • t[]t[]t[]:归并排序的临时辅助数组,用于合并两个有序子数组,避免直接修改原数组导致数据混乱。
  • ansansans:临时存储单个局面的逆序对数量;ans1ans1ans1ans2ans2ans2分别存储两个输入局面的逆序对数量。

2. 归并排序求逆序对(ms 函数)

  • 函数功能:对aaa数组的[l,r][l, r][l,r]区间进行归并排序,同时统计该区间内忽略000后的逆序对数量,累加到全局变量ansansans中。
  • 核心逻辑(合并阶段统计逆序对):当a[rp]<a[lp]a[rp] < a[lp]a[rp]<a[lp]时,说明a[rp]a[rp]a[rp]与左区间中从lplplpmmm的所有元素都构成逆序对,因此逆序对数量增加m−lp+1m - lp + 1mlp+1;同时通过a[rp]!=0判断,跳过空格000,不统计其参与的逆序对,符合可达性判定定理的要求。
  • 归并排序的稳定性:保证了在统计逆序对时不会重复或遗漏,是高效求解逆序对的经典方法。

3. 读取局面并计算逆序对(calc 函数)

  • 函数功能:读取一个x×xx \times xx×x的数码局面,将其展平为一维数组后,调用归并排序函数计算逆序对数量,并返回该值。
  • 二维转一维:无需额外存储二维数组,直接按行读取所有元素存入aaa数组,简化了数据处理逻辑,同时不影响逆序对的统计结果(因为矩阵的行优先展平不改变数字之间的相对位置关系)。

4. 主函数(多组输入处理与可达性判断)

  • 多组输入处理:使用while(cin>>n)循环读取每组数据的边长nnn,适配题目多组输入的要求。
  • 可达性判断:通过比较两个局面逆序对数量的奇偶性,若相同则输出TAK(可达),否则输出NIE(不可达),完全符合奇数码可达性判定定理。

四、总结

本题的核心是掌握奇数码问题的可达性判定定理,以及使用归并排序高效求解逆序对。我的代码通过“二维矩阵展平 + 归并排序统计逆序对 + 奇偶性判断”的流程,高效且准确地解决了该问题,能够适配n<500n < 500n<500的最大数据规模。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/6 17:08:34

心理咨询数据集实战:从零构建AI心理服务系统

心理咨询数据集实战&#xff1a;从零构建AI心理服务系统 【免费下载链接】efaqa-corpus-zh 项目地址: https://gitcode.com/gh_mirrors/ef/efaqa-corpus-zh 角色定位 你是一位资深AI技术专家&#xff0c;专注于心理健康领域的智能应用开发。拥有丰富的心理咨询数据集处…

作者头像 李华
网站建设 2026/6/4 15:27:51

Proteus安装完整指南:从下载到配置一步到位

从零搭建Proteus仿真环境&#xff1a;一次成功的安装背后&#xff0c;你必须知道的那些坑作为一名带过无数学生做单片机课程设计的嵌入式讲师&#xff0c;我见过太多人卡在第一步——Proteus装不上。不是弹窗报错“License not found”&#xff0c;就是刚打开就闪退&#xff1b…

作者头像 李华
网站建设 2026/6/6 5:14:14

DeepBump终极指南:5分钟从图片到专业3D纹理的完整教程

DeepBump终极指南&#xff1a;5分钟从图片到专业3D纹理的完整教程 【免费下载链接】DeepBump Normal & height maps generation from single pictures 项目地址: https://gitcode.com/gh_mirrors/de/DeepBump DeepBump是一款革命性的深度学习工具&#xff0c;能够从…

作者头像 李华
网站建设 2026/6/9 4:26:03

掌握AI绘图核心技术:FLUX.1 Schnell图像生成实战指南

掌握AI绘图核心技术&#xff1a;FLUX.1 Schnell图像生成实战指南 【免费下载链接】FLUX.1-schnell 项目地址: https://ai.gitcode.com/hf_mirrors/black-forest-labs/FLUX.1-schnell FLUX.1 Schnell作为业界领先的文本到图像生成模型&#xff0c;凭借其出色的生成质量和…

作者头像 李华
网站建设 2026/6/4 21:33:52

如何快速掌握PyVRP:多行程VRP的完整使用指南

如何快速掌握PyVRP&#xff1a;多行程VRP的完整使用指南 【免费下载链接】PyVRP Open-source, state-of-the-art vehicle routing problem solver in an easy-to-use Python package. 项目地址: https://gitcode.com/gh_mirrors/py/PyVRP PyVRP是一个开源、先进的车辆路…

作者头像 李华
网站建设 2026/6/1 5:19:05

DJI无人机固件安全分析实战:从零掌握开源工具链

DJI无人机固件安全分析实战&#xff1a;从零掌握开源工具链 【免费下载链接】dji_rev DJI Reverse engineering 项目地址: https://gitcode.com/gh_mirrors/dj/dji_rev 想象一下&#xff0c;当你拿到一款DJI无人机时&#xff0c;是否曾好奇它内部的固件是如何工作的&…

作者头像 李华