The 2020 ICPC Asia Taipei-Hsinchu Site Programming Contest C. Pyramid

本文介绍了ICPC亚洲台北-新竹赛点编程竞赛中C题——Pyramid的题意、解题思路和解决方案。题目要求根据金字塔结构和开关状态,确定第k个小球到底部时所在的列。通过分析每个开关对小球流向的影响,可以计算出小球的分布状态,并用动态规划的方法在O(n^2)的时间复杂度内求解,避免了二维数组的使用。
摘要由CSDN通过智能技术生成

题目链接:
https://codeforces.com/gym/102835/problem/C
题意:
给你一个金字塔,从塔尖往下放小球,每个点有一个开关,可以让小球向左下或者向右下滑动,最开始金字塔的每个点的开关都是向左下的,每有一个小球经过,开关状态就进行翻转,给定金字塔的层数n,求第k个小球到塔底时位于哪一列。
题解:
对于任意一个开关,当有a个小球经过时,一定会有(a+1)/2个小球向左,a/2个小球向右(因为最开始的开关状态是向左下,奇数时左边会多一个,偶数时两边小球数目相同),这样我们就可以知道在一个小球到达某开关之前此处有多少小球经过,如果经过的小球是奇数时,这一点的开关就向右下方向,偶数时这一点的开关方向就向左下方向。因此,我们可以得出倒数第二排(k-1)个小球在不同点的分布状态。从而对于最后一个小球,可以通过除了最后一排以外,其他排的小球的分布情况得出最终答案。比如n=5,k=18,我们可以得到如下图的分布。
在这里插入图片描述
之后我们就需要解决如何求出每一点小球经过的个数,但是我们可以知道n的最大数据范围是1e4,我们无法创建出一个二维数据进行计算求解,所以我们需要对于每一层进行逐步计算,我们可以开一个v[2][1e4]的数组,v[0][]和v[1][]依次表示上一行和当前行,比如v[0][]是第一行,而v[1][]就可以是第二行,再进行下一步计算时,v[0][]又可以是第三行,因为此时我们计算第三行只需要第二行,第一行已经没有用了,对于这一种操作,我们可以采取使用v[i%2][]和v[(i-1)%2][]的方式进行求解。我们处理了数组问题后,还需要记录上一个位置分出来一半的小球的数量。这里有个地方需要注意,就是下一层都比上一层多一列,这时我们在循环时就不需要多余考虑,可以理解为这一层第2列的个数加1的一半可以直接加在下一层的2列的位置,个数加1的一半是因为我们只进行了向左下滑动的操作。(从上一层的第2列到下一层的第2列其实是向左下滑动),向右下滑动也是同样的道理。
时间复杂度O(n^2)

上代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h> 
using namespace std;
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值