一、题目描述

小军的军训进行到了一半了,今天军训教官搞了一波突然袭击,进行了一个寝的查。

提前了解到查寝消息的小军准备进行一波整理归纳,来使自己的寝室变得更加整洁。具体来说,小军有 n 件物品,放在 n 个盒子里,第 i 个盒子有物品 i ,小军会进行 m 次整理,第i次整理,小军会依次在第 x 个盒子顶拿走物品放入第 y 个盒子内,直至第 x 个盒子完全搬空。比如第1个盒子自顶向下有物品1、2,第2个盒子有物品3,将盒子1内的物品搬入盒子2内后结果是: 第1个盒子没有物品,第2个盒子自顶向下是2、1、3

现在,小军告诉你 n 还有 m 次操作具体是什么,你能告诉他最后每个盒子内有几个物品,他们具体是什么?

输入:

一个正整数n代表盒子和物品数,一个正整数m代表整理归纳的次数

接下来m行输入,一行两个正整数x y,代表用上述的方法将盒子x的物品搬到盒子y里

1n≤10^5, 1≤m≤10^6, 1≤x,y≤n

题目保证x != y

输出:

有 n 行输出

第 i 行,先输出一个正整数 k ,表示第 i 个盒子内的物品数,接下来输出 n 个数,表示第 i 个盒子自顶向下的物品标号

注意:

行末无空格,文末有回车。

测试输入 期待的输出 时间限制 内存限制 额外进程
测试用例 1 以文本方式显示

  1. 3 2↵
  2. 1 2↵
  3. 2 3↵
以文本方式显示

  1. 0↵
  2. 0↵
  3. 3 2 1 3↵
1秒 64M 0

二、思路分析

这个真的是我的思路,每次写的都是我的心路过程,至于有时候跨度确实大,能不能描述清楚就另说。

思路一:

最开始的思路是最简单、不加掩饰、同时也是最耗时的原始方法。考虑到每一个物体的取放十分符合栈“先进后出,后进先出”的规则,我便建立 n 个结构体box[n],每个box都是一个栈,每次读入一组数据x y,表示将第x个盒子里的东西拿到第y个盒子里,每次将box[x]的栈顶元素取出放在box[y]的栈顶,然后box[x].pop......如此循环。

这种代码的优势是美观整洁,十分容易理解,然而缺点十分致命:它会超时。

考虑最坏情况,我有1e5个箱子,第一次操作我将第一个箱子里的东西放入第二个箱子,第二次操作我将第二个箱子里的东西放入第三个箱子,......,第 i 次操作我将第 i 个箱子里的东西放入第 i+1 个箱子,......,依次操作n-1次。不难发现,第一个箱子里的第一个物品,就这样被反反复复地拿了n-1次,我们的程序也这样傻乎乎的进行了n-1次,十分的耗力耗时。

上面的情况还可以更坏,经过上面的操作之后所有的物品都装到了最后一个箱子,接下来的 k 次操作中,我把它们从最后一个箱子里拿到第一个箱子里,然后把它们从第一个箱子里拿到最后一个箱子里,反复操作。明明只是把顺序反过来,在我们的认知里颠倒一次,只要操作一次完全足够。但是程序就会反反复复操作 n 次,进行一个时的超。

思路二:

看来简便的代码就注定会有亿点点的超时,那就只好优化算法。

双向链表。

不难知道,当一个物品与另一个物品接触后,它们之间就形成了一种“连接关系”。假设原来的顺序是1 2 3 5 6,那它经过一次操作只能变为6 5 3 2 1,不会横生枝节,也不会打乱顺序。和大一时接触的链表不同,单向的链表不能满足这道题目的基本需求,那么于是就需要恰当的引入双向链表的相关内容。

说实话,在这以前,我连这玩意都没听说过,甚至是链表基础在大一就学的稀巴烂。今天我知道了这个概念,但我不打算用它。换言之,既然我不会双向链表,我尝试使用我学过的其他结构体去模仿这玩意儿,达到和双向链表几乎一样的效果。

(如果你会双向链表的话,当然做起这道题来会更简单啊)


三、思路三 · 半成品

我想使用二维数组+结构体的形式来“逼近”双向链表。

考虑构建这样的一个结构体:

struct artical
{int id;int next ; int previous ;
};
artical a[N];
//id是这个物品的序号,next是下一个物品的序号,previous是上一个物品的序号
//初始时next和previous都为0,表示没有与之连接的物品

不难看出,next和previous充当链表中指针的作用。

(后期补充,当时定义了id这个东西,但是它其实没有用,你可以看到我的最终代码里已经把它去掉了。不过作为我的思维过程的一部分,我决定保留。)

初始化箱子:

int box[n+1][3];
for (int i=1;i<=n;i++) {a[i].id = i;   a[i].next = 0;        // 等于0表示不指向其他物品a[i].previous = 0;    // 等于0表示不指向其他物品box[i][0] = 1;box[i][1] = i;        //1为顶 box[i][2] = i;        //2为底
}

其中的二维数组box[x][y],x表示第x个箱子;y只能为0、1、2。当y=0时,其值是物品数量,初始为1;当y=1时,其值是箱子顶部的物品,初始为x;当y=2时,其值是箱子底部的物品,初始为x。

和以往不同,这次我先写的是输出,再写其他操作。

//输出
for ( int i=1 ; i<=n ; i++) {//输出物品数量printf( "%d" , box[i][0] );//如果有物品,就输出物品id。if ( box[i][0] ) {//如果物品只有一件,输出这个物品id就行了。if ( box[i][0]==1 ) printf( " %d" , a[ box[i][1] ].id );//否则物品不止一件,要先确定它是头(next)还是尾(previous),然后输出。else {int j = box[i][1];if ( a[j].next ) do { printf( " %d" , a[j].id );j = a[j].next; } while (a[j].next);else             do { printf( " %d" , a[j].id );j = a[j].previous; } while (a[j].previous);  }}  printf("\n");
} 

(一个小时过去了)

使用next和previous有一项极大的不方便,举个例子更好说明:

假设我现在要将物品2放在物品1上面:

其中,2.next -> 1,1.previous -> 2。

再把3放在2的上面,于是3.next -> 2,2.previous -> 3.

同样有另一堆物品,由4和5组成,且4在5的上面,4.next -> 5,5.previous -> 4

我现在要把321这一堆叠在45这一堆上面,变成12345,在3和4的连接处,应当有3.next -> 4

这把上面的3.next -> 2覆盖掉了。

要解决这个问题,就要对3.next -> 4,2.next -> 3,1.next -> 2全部重新设置一遍,当数据量大的时候仍然会出现操作重复、浪费时间的情况。

不过即便是会超时,我们写出了一个半成品,半成品代码如下。

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
struct artical
{int next=0 , previous=0;
};
artical a[N];int main(){int n,m;scanf( "%d %d" , &n , &m );int box[n+1][3];for ( int i=1 ; i<=n ; i++) {box[i][0] = 1;box[i][1] = i; //1为顶 box[i][2] = i; //2为底 }for ( int i=0 ; i<m ; i++ ) {//把x的物品放到yint x,y;scanf( "%d %d" , &x , &y );if ( box[x][0] ) {for ( int j=0 ; j<box[x][0] ; j++ ) {//每次取x顶的物品,对其next和previous进行重置  a[ box[x][1] ].previous = a[ box[x][1] ].next;a[ box[x][1] ].next = box[y][1];//更新y顶的x顶的物品                box[y][1] = box[x][1];box[x][1] = a[ box[x][1] ].previous;}//更新x和y中的物品数量box[y][0] = box[x][0] + box[y][0];box[x][0] = 0;//更新x底的物品box[x][2] = 0;}}//输出 for ( int i=1 ; i<=n ; i++ ) {printf( "%d" , box[i][0] );if ( box[i][0] ) {if ( box[i][0]==1 ) printf( " %d" , box[i][1] );else {int j = box[i][1] ;printf(" %d",j);while(a[j].next) { j = a[j].next; printf(" %d",j); }     }}  printf("\n");} return 0;
}

有一个样例超时。

休息一会儿,等今晚或者明天再优化,届时在《下篇》中有思路四(思路三的优化版本)的呈现。

查寝 | c++ | 不用双向链表(上篇)相关推荐

  1. 查寝 | c++ | 不用双向链表(下篇)

    还是这个样例 之前提到,将321放在45的上面,就要对3.next -> 4,2.next -> 3,1.next -> 2全部重新设置一遍,也就是要操作3次. 既然顺序是一定的,换 ...

  2. 提交日期表单状态操作_奇怪的知识又增加了,表单还能查寝?

    Hi,胖友们,大家好!好久不见呀,最近表姐在刷微博时,无意间发现一位小伙伴神奇的表单用法. 别人都用表单收集数据,登记信息,而这位小伙伴则是用表单来"查寝",看了他的讲解,表姐不禁 ...

  3. 【BIT2021程设】20.军训日记:查寝

    写在前面: 本系列博客仅作为本人十一假期过于无聊的产物,对小学期的程序设计作业进行一个总结式的回顾,如果将来有BIT的学弟学妹们在百度搜思路时翻到了这一条博客,也希望它能对你产生一点帮助(当然,依经验 ...

  4. 20. 军训日记:查寝

    小军的军训进行到了一半了,今天军训教官搞了一波突然袭击,进行了一个寝的查. 提前了解到查寝消息的小军准备进行一波整理归纳,来使自己的寝室变得更加整洁.具体来说,小军有n件物品,放在n个盒子里,第i个盒 ...

  5. 高校“花式查寝”到底多有意思?

    滴--您有一条新的消息 今晚查寝. 收到. 你,经历过查寝吗? 辅导员推门问候,查人查锅查卫生 查寝变成我们大学寝室生活的"家常便饭"后 还衍生出了一些"奇奇怪怪&quo ...

  6. 【毕业设计源码】基于微信小程序的查寝系统的设计与实现

    目录 一.程序介绍: 三.文档目录: 四.运行截图: 五.数据库表: 六.代码展示: 七.更多学习目录: 八.互动留言 一.程序介绍: 文档:开发技术文档.参考LW.答辩PPT,部分项目另有其他文档 ...

  7. 辽宁师范大学计算机学院查寝吗,辽宁师范大学影视艺术学院

    影视艺术学院研究生会章程 辽宁师范大学影视艺术学院研究生会以促进研究生的全面发展为宗旨,以服务全体研究生为己任.通过组织各种活动推进校园民主与校园文化建设,营造良好校园文化氛围和学术氛围,树立一种蓬勃 ...

  8. 学校校园学生寝室管理查寝打分系统 毕业设计毕设源码毕业论文开题报告参考(1)功能概要

    该系统主要分网站管理员.班主任.任课老师.学生这几个角色 网站管理员 学校设置 学校概要:设置学校简介.学校机构.学校领导.校园风景.联系我们 分院设置:录入分院信息.分院列表.分院信息修改和删除 广 ...

  9. OSChina 周二乱弹 ——查寝大妈,你写我在床上硬不起来是怎么回事!

    2019独角兽企业重金招聘Python工程师标准>>> @xuhuazi : first blood~ 动弹,你好. 你送一血,我送你首歌吧~ 派对动物 - 五月天 手机党少年们想听 ...

最新文章

  1. 私人仓库免费后本地git和远程github首次连接
  2. Apache PDFBox 存在高危 XXE 漏洞,建议升级至 2.0.15
  3. iOS开发UI篇——Button基础
  4. ant target间的dependency
  5. JAVA复习5(集合——拓展——单向链表)
  6. 前端学习(1739):前端调试值之页面元素的调试技巧
  7. 空间参考不存在_空间实景三维信息如何服务于BIM应用
  8. macos删除快捷键的各种区别用法
  9. php ckfinder basedir,ckfinder后,上传文件
  10. Linux 目录结构及主要内容 2
  11. 关于在GridControl中添加GridLookUpEdit绑定数据
  12. Docker游戏Dos小游戏,一个web版的dos游戏库
  13. 安装西门子博图一直重启_西门子博图重启后继续安装没完成的程序怎么去除?...
  14. PowerPoint-漂亮表格三招
  15. 字符个数统计 java
  16. 太平洋电脑城 GHOST XP SP3 快速装机版 V9.8
  17. 3rd TMA大数据营销案例征集赛正式启动,报名ing!
  18. [2001-2003美/新等合拍经典奇幻大片][魔戒1-3][BD-RMVB][中英字幕/1280x720高清晰版]
  19. 数据结构实验-稀疏一元多项式计算
  20. python批量检索文献_快解锁新姿势,教你如何用Python搞定文献搜索和科研图片!...

热门文章

  1. swing学习笔记:GridBagLayout
  2. 如何批量给照片加水印?详细图文教程
  3. 在一种特殊情况下损坏了wav音频文件,修复的方法
  4. 基于Android Studio的记账类app开发
  5. 2019/01/21 一位前端实习生 艰辛过程 励志 实习周记(四)——第四 五周
  6. python获取文件夹下的子目录_用Python获取子目录或文件列表
  7. MAC系统IDEA工具栏没有svn图标,svn项目也不显示修改信息
  8. 计算机二级c语言速记,全国计算机等级考试7日达标(冲刺模拟+考点速记):二级C语言(7日2011二级C)...
  9. Git中tag标签的使用
  10. 综合布线工程测试技术