2018AHU新生赛Panelatta与华容道题解

题目描述

Panelatta很喜欢玩益智游戏,今天,他又开始玩一个古老的游戏:华容道!但是Panelatta不喜欢原版的华容道,所以他对此做了一些修改。给定一个由 n2n^{2}n
​2
​​ ( n 为奇数)个方格组成的 n⋅n 方阵,在 n⋅n−1 个方格中填入数字 1 ~ n⋅n−1 ,并将剩下的一个方格留空。在游戏过程中,可以将空置的方格与其上下左右方向的任何一个数字交换。Panelatta将这个游戏称为 n 阶华容道。
现在给你两个 n 阶华容道游戏的局面,请判断是否存在一种移动空置方格的方法,使得从其中一个局面可以变换成另一个局面?

输入格式

多组数据,对于每组数据:
第1行一个奇数 n ,(n < 500)
接下来 n 行,每行 n 个整数,表示第一个局面。
接下来 n 行,每行 n 个整数,表示第二个局面。
每个局面中用 0 表示空置方格,并保证每个局面都恰好用数字 0 ~ n⋅n−1填充满。
输出格式
对于每组数据,若两个局面可达,输出TAK,否则输出NIE。

样例

输入样例

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

输出样例

TAK
TAK

注:xls出的这个题没点相关知识的话太难了,不愧是AHU全能王,出题就是有水平 ?
下面先介绍这道题所涉及到的相关知识点:

奇排列

下面是百度百科上对奇排列 先自行阅读后再看下面的解释

https://baike.baidu.com/item/奇排列/18881587?fr=aladdin

看完百度百科对奇排列的解释后 不难知道以下结论:

定理1 : 对换改变排列的奇偶性。(经过一次对换,奇排列变成偶排列,偶排列变成奇排列。

例如:1 2 3 4 5 6是逆序对为0 所以为偶排列 若调换其中任意两个位置的数 比如1 5 3 4 2 6 就变成偶排列

定理2 :任意一个n级排列与排列 都可以经过一系列对换互变,并且所作对换的个数与这个排列有相同的奇偶性。

定理2结合定理1也不难理解,偶排列换一次变成奇排列,再变化一次就变成了偶排列,以此类推得知:互变的次数的奇偶性与排列的奇偶性保持一致。

那么华容道是怎样具有排列的性质呢?
首先理解华容道不一定总是有解的,比如网上很火的一道数字华容道题
具体可以看下这个有关华容道里群论的视频:华容道群论视频
这种数字华容道是无解的,而原因就是因为它是一种奇排列,而他要变成的1 2 3 4…… 14 15是一种偶排列,我们不难想到奇排列与偶排列在数字华容道中不能互相转化。

了解了上面的知识再来看这道题 给出两个数字华容道 问第一个能否转换成第二个,换个思路想,问题可以转化为第一个第二个是否都是同一种排列(比如都是奇排列和偶排列)。转化为这个问题后,我们又要想到如何判断数字华容道的排列的奇偶性,那不妨找一个标准排列来与这两个数字华容道作比较,看看这两个数字华容道要互换几次才能变成我们所规定的那个标准排列,若两种变化次数为奇数或偶数,说明这两种排列具有相同的奇偶性,故可以相互转化,输出TAK。

不妨令标准排列为1 2 3 4 5 6 7 ……

此时问题就转化为了一个排列最少交换几次才能变成1 2 3 4 5 6 7……这种升序排序。

由于数据为500*500=250000 数据很大 冒泡排序等方法很容易被卡超时

下面介绍一种复杂度o(n)的方法来处理这种问题:

创建一个数组记录一组数 然后再创建一个数组来记录数所对应的位数 比如第一组数 1 2 3 4 6 7 5 8 第一个数组叫a[1]=1 a[2]=2…a[5]=6 a[6]=7 a[7]=5 然另一个数组arem[1]=1 arem[2]=2 arem[6]=5 arem[7]=6 arem[5]=7 然后遍历 如果a[i] ! =i 就让arem[i]查到i值在第几位 然后让a[i]与a[arem[i]]交换数值 同时更新arem数组

注:更新arem数组的作用何在?
如果交换完位置后还用原来的数值记录位置就会在后面调取某个数值的位置时产生错误。

ac代码

// An highlighted block
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
int a[250000],arem[250000];
int b[250000],brem[250000];
int main()
{int t=10;while(t--){int n,cnta=0,cntb=0,tep;scanf("%d",&n);if(n==0){continue;};if(n==1){scanf("%d",&n);scanf("%d",&n);printf("TAK\n");continue;}for(int i=1;i<=n*n-1;i++){scanf("%d",&a[i]);if(a[i]==0){i=i-1;continue;}arem[a[i]]=i;}for(int i=1;i<=n*n-1;i++){scanf("%d",&b[i]);if(b[i]==0){i=i-1;continue;}brem[b[i]]=i;}int m,q;for(int i=1;i<=n*n-1;i++){if(a[i]!=i){m=arem[i];q=a[i];tep=a[arem[i]];a[arem[i]]=a[i];a[i]=tep;cnta++;arem[q]=m;}if(b[i]!=i){m=brem[i];q=b[i];tep=b[brem[i]];b[brem[i]]=b[i];b[i]=tep;cntb++;brem[q]=m;}}if(cnta%2==cntb%2){printf("TAK\n");}else{printf("NIE\n");}}return 0;
}

幸运的是这道题内存限制没什么要求,但是我们可以进一步优化下内存,我们可以让a和arem数组输入完成后直接进入运算cnta的奇偶性,然后再把原来的b和brem直接输入到a和arem,这样就省去了b和brem所占有的内存。

下面是改进版本的代码:

// An highlighted block
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
int a[250000],arem[250000];
int main()
{//freopen("1.in","r",stdin);int t=10;while(t--){int n,cnta=0,cntb=0,tep;int m,q;scanf("%d",&n);if(n==0){continue;};if(n==1){scanf("%d",&n);scanf("%d",&n);printf("TAK\n");continue;}for(int i=1;i<=n*n-1;i++){scanf("%d",&a[i]);if(a[i]==0){i=i-1;continue;}arem[a[i]]=i;}for(int i=1;i<=n*n-1;i++){if(a[i]!=i){m=arem[i];q=a[i];tep=a[arem[i]];a[arem[i]]=a[i];a[i]=tep;cnta++;arem[q]=m;}}for(int i=1;i<=n*n-1;i++){scanf("%d",&a[i]);if(a[i]==0){i=i-1;continue;}arem[a[i]]=i;}for(int i=1;i<=n*n-1;i++){if(a[i]!=i){m=arem[i];q=a[i];tep=a[arem[i]];a[arem[i]]=a[i];a[i]=tep;cntb++;arem[q]=m;}}if(cnta%2==cntb%2){printf("TAK\n");}else{printf("NIE\n");}}return 0;
}

内存少了一半左右,且排序算法是o(n)的,现在应该是优化的很好的代码啦。

下面再贴一种出题人Xls滴方法。

xls滴排序是o(nlogn)的方法。

// An highlighted block
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=5e5+5;long long ans;
int a[maxn];
int r[maxn];void msort(int s,int t){if(s==t)return;int mid=(s+t)/2;msort(s,mid);msort(mid+1,t);int i=s,j=mid+1,k=s;while(i<=mid&&j<=t){if(a[i]<=a[j]){r[k]=a[i];k++;i++;}else{r[k]=a[j];k++;j++;ans+=mid-i+1;}}while(i<=mid){r[k]=a[i];k++;i++;}while(j<=t){r[k]=a[j];k++;j++;}for(int i=s;i<=t;i++)a[i]=r[i];
}
int main(){int n;int p;int val;while(~scanf("%d",&n)){p=1;for(int i=1;i<=n*n;i++){scanf("%d",&val);if(val!=0){a[p]=val;p++;}}ans=0;msort(1,p);long long t=ans;p=1;for(int i=1;i<=n*n;i++){scanf("%d",&val);if(val!=0){a[p]=val;p++;}}ans=0;msort(1,p);if(t%2==ans%2)printf("TAK\n");else printf("NIE\n");}return 0;
}

问题到此就解决了?

最后表白郭希贤同学!!!!

2018AHU新生赛Panelatta与华容道题解相关推荐

  1. 21级爪哇程序设计新生赛(二)题解

    21级爪哇程序设计新生赛(二) 序 A 小爪的数字集合(并查集) B 小爪的得分(博弈) C 小爪的博弈(博弈) D ljc和cyj玩五子棋(模拟) E ljc和雪球(模拟) F LJC的背包(动态规 ...

  2. 20级爪哇程序设计新生赛(一)题解

    20级爪哇程序设计新生赛题解 20级爪哇程序设计新生赛1.0(正式赛) A.The Tree Of LittleZhua(思维或者线段树) Easy Version Hard Version B.小爪 ...

  3. 2019太原理工大学第二届程序设计新生赛预赛暨公开赛题解

    A - Creeper? 按照题目要求,判断输入的字符串是什么,输出对应的字符串即可. 读入时需要注意一次读入一行,因为"Awww man."和"Se no!" ...

  4. 2019年安徽大学ACM/ICPC实验室新生赛题解

    本文仅作个人收藏学习使用 题目及解析来源牛客竞赛网 //作者:王清楚 //链接:https://ac.nowcoder.com/discuss/351408?type=101&order=0& ...

  5. ACM新生赛部分题解

    2021级的ACM新生赛已经完结了,我就自己做出来的八道题整理一下题解,因为其他是真的不会. 链接:登录-专业IT笔试面试备考平台_牛客网 来源:牛客网 一.我们是冠军 7 日星期 777 的凌晨,7 ...

  6. 2015GPNU新生赛题解

    2015GPNU新生赛题解 今年的题目结合了往年的题目和华工,华师新生赛题目,确实是历年最难. * 1001 * Problem Description 最近ACM协会各种各样的费用都要申报,会长一时 ...

  7. 2021暨南大学轩辕杯ACM程序设计新生赛题解

    title : 2021暨南大学轩辕杯ACM程序设计新生赛 date : 2021-12-12 tags : ACM,练习记录 author : Linno 题目链接:https://ac.nowco ...

  8. 2016中北大学ACM程序设计新生赛题解

    新生赛题目地址 a or an 输入字符串后判断第一个字符是不是'a','e','i','o','u',即可. #include<algorithm> #include <iostr ...

  9. 小乐乐与二段数(2019哈理工新生赛第20题)

    链接:2019哈理工新生赛题解 2019哈理工新生赛第20题 T题: 链接:https://ac.nowcoder.com/acm/contest/1877/T 来源:牛客网 题目描述 小乐乐从老师口 ...

  10. 论如何举办一个承载400人的比赛(XUPT新生赛承办小记)

    XUPT新生赛承办小记 老师去年就想搞一个新生赛了,奈何去年时间不够,没有搞,于是今年就开始提前搞起来了.ZLS说要不然搞一个domjudge,我寻思着好鸭好鸭,看起来很牛逼,然后就开始了苦逼的配环境 ...

最新文章

  1. 电动双联电位器ZW1613
  2. NPTL简介 (NATIVE POSIX Thread Library)
  3. JS跨域访问(ajax跨域)
  4. C#面向对象--继承
  5. (五)Docker查看容器ip及指定固定IP
  6. 印象笔记 还回快捷_模块化编辑器、OCR、素材库...一大波新功能来袭丨印象笔记7周年现场实况...
  7. 干旱的草原与拉大提琴的牧人
  8. python中难的算法_一个python的比较难的算法,有懂的人可以进来一下
  9. js中的总结汇总(以后的都收集到这篇)
  10. Java编程思想学习笔记-第11章
  11. [C++ primer]运行时类型识别(RTTI)
  12. 滴滴配合警方调证不超 10 分钟;苹果否认恶意芯片报道;贝索斯建火箭中心 | 极客头条...
  13. idea改类名快捷键_IDEA使用之快捷键(default设置)
  14. 全文检索(LuceneSolr)
  15. 【CodeForces - 471D 】【构造差分kmp】MUH and Cube Walls
  16. gif怎么转换html,gif转视频的教程:怎么把gif转换成mp4、avi、wmv
  17. CAPM模型的应用--回归模型中的Alpha, r_f
  18. aspose导出word转pdf并加水印
  19. 基于MATLAB的电弧仿真模型(Mayr/Cassie 电弧模型)
  20. python-绘制散点图

热门文章

  1. 3.30团体天梯赛后个人感想
  2. 中国20年互联网的发展史
  3. itunes显示无法更新服务器失败怎么办啊,更新iTunes出现错误 iTunes更新失败解决方案...
  4. 服务器先装系统还是先做热备,安装ibm服务器双机热备操作系统图文详细步骤.doc...
  5. iOS开发APP瘦身之PDF图片资源加载框架
  6. 计算机系统文件夹打不开,为什么打不开文件夹
  7. php转html为pdf后部分图片无法显示
  8. notes服务器标识文件,怎样重新验证将要过期的服务器标识符文件_lotus notes
  9. 食品和饮料销售预测分析
  10. ArcEngine代码 两规冲突检测