信息学奥赛一本通 小球(drop)

2024-04-04 05:08

本文主要是介绍信息学奥赛一本通 小球(drop),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

2018年信息学奥赛NOIP资料下载
This drop is gonna last forever!

许多的小球一个一个的从一棵满二叉树上掉下来组成FBT(Full Binary Tree,满二叉树),每一时间,一个正在下降的球第一个访问的是非叶子节点。然后继续下降时,或者走右子树,或者走左子树,直到访问到叶子节点。决定球运动方向的是每个节点的布尔值。最初,所有的节点都是false,当访问到一个节点时,如果这个节点是false,则这个球把它变成true,然后从左子树走,继续它的旅程。如果节点是true,则球也会改变它为false,而接下来从右子树走。满二叉树的标记方法如下图:

因为所有的节点最初为false,所以第一个球将会访问节点1,节点2和节点4,转变节点的布尔值后在在节点8停止。第二个球将会访问节点1、3、6,在节点12停止。明显地,第三个球在它停止之前,会访问节点1、2、5,在节点10停止。

现在你的任务是,给定FBT的深度D,和I,表示第I个小球下落,你可以假定I不超过给定的FBT的叶子数,写一个程序求小球停止时的叶子序号

——以上是题目;
当第一次看到这道题的时候,好像是11月11日(巧了),刚刚自己学习了建树的蒟蒻的我马上想到了去模拟这个过程。原理很简单,用指针去建树,然后每个结构体内去维护四个变量:

1、bool check ---- 判断是否往左还是往右; 2、int data ---- 记录该结点的值;

3、node *lchild ---- 指向左儿子的指针; 4、node *rchild ---- 指向右儿子的指针;

#include<bits/stdc++.h>
using namespace std;
typedef struct node;
typedef node tree;
struct node{
char data;
bool check;
tree lchild,rchild;
};
tree root;
char c;
int D;
long long num, I, ans, i;
void build_bt(tree &bt,int sum,int num){
if(sum>D){
return;
}
bt=new node;
bt->data=num;
bt->check=false;
build_bt(bt->lchild,sum+1,num
2);
build_bt(bt->rchild,sum+1,num*2+1);
}
int solve(int depth,tree &bt){
if(depth==D)
return bt->data;
if(bt->check){
bt->check=false;
solve(depth+1,bt->rchild);
}
else{
bt->check=true;
solve(depth+1,bt->lchild);
}
}
int main(){
cin>>D>>I;
build_bt(root,1,1);
for(i=1;i<=I;i++){
ans=solve(1,root);
}
cout<<ans;
return 0;
}
只要建了树,一遍一遍跑就是了,扪心一想:嗯,一定是将会AC了;

信心满满提交然而并没有AC,WA!没有爆内存,也没有超时,就是WA,GG(挠头)。

改了很久都还是WA,心中mmp骂不出来,于是尝试用数组去做:利用二叉树的左右儿子编号分别为为 父亲编号2和 父亲编号2+1,构建一个数组去模拟,还是开bool数组去判断掉到左边还是右边;

#include<bits/stdc++.h>
using namespace std;
int tr[1<<20];
long long I,D,ans;
long long tree_doit(){
int node=1;
for(int i=1;i<=D-1;i++){
if(!tr[node]){
tr[node]=1;
node=node2;
}
else{
tr[node]=0;
node=node
2+1;
}
}
return node;
}
int main(){
cin>>D>>I;
for(int i=1;i<=I;i++)
ans=tree_doit();
cout<<ans;
return 0;
}
是AC掉了没错,但还是觉得不对,一定有规律可循,想啊想,豁然开朗(噗)。

不难发现我们所需要求的是最后一个小球的位置,那我们可不可以只去模拟最后一个小球的掉落呢?

有人会问:你怎么知道球会怎么落呐?难道不是需要去求出前 I-1 个球所改变的方向吗?

但我们根本不需要知道。

首先球在第一层只会落两个方向:左,右;说明我们球落到球要么在一边,要么在另一边,所以 I 个球落下会在剩下一个球或0

个时,左右是”均分“的。

由于球是先从左边开始落的,落下奇数个球一定是落在左边的,偶数个一定是落在右边的。可以类比一下走路,假如您迈出的第一步是左脚,那么走奇数步时正在迈出的一定是左脚,而不是右脚。

(假如题目改一下,小球先从右边落,在从左落下,道理也是一样的!)

这只是第一层,第二层,第三层 …… 第D层呢?

我们可以发现,无论是在哪一层,小球都需要用一半([I/2](向下取整))个小球去克服两边的每一边,最后的那个球,和第一层一样,只是球的总数变成了原来的1/2;

但是不是左右两边都会剩下一半呢?不是,左边会多剩下一个,还是那个道理,左脚先迈出,左脚便有”先决优势“。

还是利用那个父与子的编号性质,左掉编号2,右掉编号2+1。

好啦,放代码:

#include<bits/stdc++.h>
using namespace std;
int ans=1,D,I;
int main(){
cin>>D>>I;
for(int i=2;i<=D;i++)
if(I%2==1){
ans*=2;
I=I/2+1;
}
else{
ans=ans*2+1;
I/=2;
}
cout<<ans;
return 0;
}
嗯,AC,而且代码显然剪短了许多。
但是我还是不明白为什么建树不对,好歹代码也是这么长的啊。

顺便说一句,代码长短好像并不是解决题目的本质,要了解题意,仔细推敲,找准规律,一针见血!(听说YJQ神牛写线性筛的某一道题,最后写了老长,发现根本不用线性筛一样)

原文:https://blog.csdn.net/Jerry_wang119/article/details/79056076

这篇关于信息学奥赛一本通 小球(drop)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/874864

相关文章

生信代码入门:从零开始掌握生物信息学编程技能

少走弯路,高效分析;了解生信云,访问 【生信圆桌x生信专用云服务器】 : www.tebteb.cc 介绍 生物信息学是一个高度跨学科的领域,结合了生物学、计算机科学和统计学。随着高通量测序技术的发展,海量的生物数据需要通过编程来进行处理和分析。因此,掌握生信编程技能,成为每一个生物信息学研究者的必备能力。 生信代码入门,旨在帮助初学者从零开始学习生物信息学中的编程基础。通过学习常用

生信圆桌x生信分析平台:助力生物信息学研究的综合工具

介绍 少走弯路,高效分析;了解生信云,访问 【生信圆桌x生信专用云服务器】 : www.tebteb.cc 生物信息学的迅速发展催生了众多生信分析平台,这些平台通过集成各种生物信息学工具和算法,极大地简化了数据处理和分析流程,使研究人员能够更高效地从海量生物数据中提取有价值的信息。这些平台通常具备友好的用户界面和强大的计算能力,支持不同类型的生物数据分析,如基因组、转录组、蛋白质组等。

【生物信息学算法】图算法1:概念和算法

文章目录 1. 图的定义、分类、表达方式图的定义图的分类表达方式Python实现 2.相邻节点和度概念定义python实现 3.路径、距离和搜索路径和距离搜索环 4.图论中的欧拉定理 1. 图的定义、分类、表达方式 图的定义 图G可以由两个集合来定义,即G=(V,E)。其中,V是对象的集合,称为图的顶点或节点; E是V中(u,v)顶点对的集合,称为边或弧,表示u和v之间的关系

12个小球 梅氏砝码问题

1. 12个小球,其中有一个是坏球。有一架天平。需要你用最少的称次数来确定哪个小球是坏的并且它到底是轻还是重。 来源:http://blog.csdn.net/pongba/article/details/2544933 这个问题是一道流传已久的智力题。网络上也有很多讲解,还有泛化到N个球的情况下的严格证明。也有零星的一些地方提到从信息论的角度来看待最优解法。本来我一直认

Android 自定义View控件,实现跟随手指触摸移动的小球

Android UI组件是通过继承View类,然后绘制内容,比如ImageView,TextView等组件都是继承View类。 当Android系统提供的组件功能不能满足需求时,可以通过继承View类重写一个或多个方法,派生自定义的组件,View类常用重写方法: 1.构造器:View子类最基本的重写方法 protected voidonDraw(Canvas canvas) public

【简历】25届南京某一本JAVA简历:简历通过率还好,但是拿不到OFFER

注:为保证用户信息安全,姓名和学校等信息已经进行同层次变更,内容部分细节也进行了部分隐藏 简历说明 今天看一份25届南京某一本大学的Java简历。 这个简历呢,学校是一本。我们说上来先要定校招层次,这个层次就按照中厂来讲。因为现在很多的双非一本目标都是在中厂。 这个同学有个实习经历,一本有八成的同学主项目都是重复的。HR他只能看到项目重不重复,要点对不对他不知道,就从这个角度来看,这位同学

信息学奥赛初赛天天练-83-NOIP2014普及组-基础题2-输入设备、输出设备、操作系统、二进制、整数除法、while、do while循环

1 NOIP 2014 普及组 基础题2 4 以下哪一种设备属于输出设备( ) A 扫描仪 B 键盘 C 鼠标 D 打印机 5 下列对操作系统功能的描述最为完整的是( ) A 负责外设与主机之间的信息交换 B 负责诊断机器的故障 C 控制和管理计算机系统的各种硬件和软件资源的使用 D 将没有程序编译成目标程序 11 下列各无符号十进制整数中,能用八位二进制表示的数中最大的是( ) A 296

基于R语言生物信息学大数据分析与绘图

随着高通量测序以及生物信息学的发展,R语言在生物大数据分析以及数据挖掘中发挥着越来越重要的作用。想要成为一名优秀的生物数据分析者与科研团队不可或缺的人才,除了掌握对生物大数据挖掘与分析技能之外,还要具备一定的统计分析能力与SCI论文质量绘图能力。大量生物数据分析案例,包括利用R语言绘制SCI高质量图片、利用R语言分析生物学数据的案例。 原文链接:基于R语言生物信息学大数据分析与绘图

ondrag 事件_html5拖放(Drag和Drop)

二、相关重点 DataTransfer 对象:退拽对象用来传递的媒介,使用一般为Event.dataTransfer。 draggable 属性:就是标签元素要设置draggable=true,否则不会有效果,例如: <div title="拖拽我" draggable="true">列表1</div> ondragstart 事件:当拖拽元素开始被拖拽的时候触发的事件,此事件作用在被拖曳元

生物信息学:DNA序列的构成

DNA序列是由一串字母表示的真实的或者假设的携带基因信息的DNA分子的一级结构。‌ DNA序列的构成基于四种特定的碱基,分别是腺嘌呤(A)、胸腺嘧啶(T)、鸟嘌呤(G)和胞嘧啶(C)。这些碱基以特定的配对方式形成碱基对,即A与T配对,C与G配对,这是基于它们之间的氢键相互作用。每个碱基代表一个特定的遗传信息,通过这些碱基的排列顺序,DNA序列能够编码遗传信息,进而指导生物体的生长、发育和功能。